Compare commits

...

41 Commits

Author SHA1 Message Date
Ting-An Lin
000a07f2bb Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust 2020-01-14 18:52:44 +08:00
Ting-An Lin
828f97be80 Add L2 IF-Module 2020-01-14 18:52:20 +08:00
Chang-Sheng,Liu
7d8daa375f add rxtx_NB_IoT() 2020-01-14 17:24:00 +08:00
Chang-Sheng,Liu
8b5e70e0e0 fix all memory error at current stage,workable version,run okgit status 2020-01-09 20:43:25 +08:00
Ting-An Lin
c61ce7a501 Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust 2020-01-09 18:21:01 +08:00
Ting-An Lin
eb0811b19b fix part of warnings, some unused warnings wait for assign value in future 2020-01-09 18:08:52 +08:00
oai
fc37f649da fix some nb-iot nprach function memory error 2020-01-09 17:19:01 +08:00
Ting-An Lin
20c4a11482 Merge copy function 2020-01-09 15:20:30 +08:00
Ting-An Lin
245f8e99d9 finish copy function 2020-01-09 14:25:03 +08:00
changshengliu
686f3aaac6 finish part of copy function 2020-01-08 18:51:25 +08:00
Ting-An Lin
f53bf807ed Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust 2020-01-08 15:56:53 +08:00
Ting-An Lin
43641bc1e3 Completely assign common value 2020-01-08 15:55:00 +08:00
oai
a06aad7fa1 fix a segmentation error,but still have one...sol:fill NB-IoT parameters tnto eNB_NB_IoT Struct from eNB struct 2020-01-06 17:33:38 +08:00
Ting-An Lin
b159cd3718 Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust 2019-12-30 18:12:46 +08:00
Ting-An Lin
b160b3f784 fix warnings 2019-12-30 18:11:22 +08:00
changshengliu
6cb18da366 Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust 2019-12-30 16:34:43 +08:00
changshengliu
0a41e08a43 add new feture for NB-IoT at config_file 2019-12-30 16:33:05 +08:00
Ting-An Lin
f93acd2293 fix Samuel warning 2019-12-26 17:38:56 +08:00
Chang-Sheng,Liu
0f54bf2799 add L2 IF_Module and fix some memory error 2019-12-25 23:44:21 +08:00
oai
5693f7ba68 fix memory segmentation error 2019-12-25 23:11:14 +08:00
Ting-An Lin
72e609927b fix multiple definition 2019-12-25 17:33:44 +08:00
Chang-Sheng,Liu
4501390266 fix eNBs struct warning 2019-12-25 13:52:08 +08:00
Ting-An Lin
9b1bc43c48 lte_init_NB_IoT.c
(remain error)
2019-12-24 17:25:07 +08:00
Ting-An Lin
fffc6b0291 Add frame_parms_NB_IoT (remain error) 2019-12-17 18:03:45 +08:00
Ting-An Lin
5b93cd38ad Create NB-IoT PHY struct 2019-12-12 15:29:59 +08:00
Ting-An Lin
302159fc78 nprach funcitons added 2019-11-28 16:47:11 +08:00
Ting-An Lin
f83cca43aa Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust 2019-11-14 15:37:31 +08:00
Ting-An Lin
b1adf9da05 fix PHY warnings 2019-11-14 15:30:15 +08:00
Nick Ho
9fc0119067 IF-Module at PHY added 2019-11-07 17:02:25 +08:00
Nick Ho
70d746df67 RACH and segementation 2019-11-05 17:45:30 +08:00
chenhsunyang0922
6c1c85105b Add asn1_msg_NB_IoT.c and fix warning in rrc layer (7 warnings remaining) 2019-11-04 03:55:38 -08:00
Ting-An Lin
232d51d8e4 dlsch functions for TX 2019-11-01 16:03:41 +08:00
oai
a827e6a07f dlsch functions for TX 2019-11-01 15:29:29 +08:00
Nick Ho
af2cb07f89 L1 for RX, 5 warning in PHY 2019-10-31 16:57:13 +08:00
Nick Ho
771043a4aa Remove useless header 2019-10-29 17:29:45 +08:00
Nick Ho
f047f0771a Merge branch 'develop-nb-iot-ntust' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop-nb-iot-ntust 2019-10-29 17:18:03 +08:00
Nick Ho
6c215de96e Top level (Procedure part) for TX 2019-10-29 17:17:52 +08:00
chenhsunyang0922
78730b8082 Add rrc_eNB_NB_IoT.c and rrc_eNB_UE_context_NB_IoT.c (0 error 17 warnings) 2019-10-25 06:06:06 -07:00
Nick Ho
3a002e2cd7 Finish the debug of src in MAC 2019-10-21 17:04:55 +08:00
Nick Ho
4269152ff4 MAC LAYER NB-IoT function first added 2019-10-16 17:18:47 +08:00
oai
5da7305f88 header include & re-construct for NB-IoT 2019-10-14 16:33:40 +08:00
116 changed files with 51482 additions and 2687 deletions

View File

@@ -0,0 +1,306 @@
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 = 2685000000L;
uplink_frequency_offset = -120000000;
Nid_cell = 0;
N_RB_DL = 50;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
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;
//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 = "140.118.123.97"; #"140.118.123.212";
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 */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "140.118.123.97/24";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "140.118.123.97/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "140.118.123.97/24";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
DU = (
{
DU_INTERFACE_NAME_FOR_F1U = "lo";
DU_IPV4_ADDRESS_FOR_F1U = "127.0.0.1/16";
DU_PORT_FOR_F1U = 22100;
F1_U_DU_TRANSPORT_TYPE = "TCP";
}
);
CU = (
{
CU_INTERFACE_NAME_FOR_F1U = "lo";
CU_IPV4_ADDRESS_FOR_F1U = "127.0.0.1"; //Address to search the DU
CU_PORT_FOR_F1U = 22100;
F1_U_CU_TRANSPORT_TYPE = "TCP"; // One of TCP/UDP/SCTP
DU_TYPE = "LTE";
}//,
// {
// CU_INTERFACE_NAME_FOR_F1U = "eth0";
// CU_IPV4_ADDRESS_FOR_F1U = "10.64.93.142"; //Address to search the DU
// CU_PORT_FOR_F1U = 2211;
// F1_U_CU_TRANSPORT_TYPE = "TCP"; // One of TCP/UDP/SCTP
// DU_TYPE = "WiFi";
// }
);
CU_BALANCING = "ALL";
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";
}
);
NB-IoT_L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
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];
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "lo";
FLEXRAN_IPV4_ADDRESS = "140.118.121.81";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_RU_L1_TRX_SPLIT";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
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";
};

View File

@@ -325,8 +325,8 @@ add_custom_target (
set_source_files_properties(${rrc_source} PROPERTIES COMPILE_FLAGS -w) # suppress warnings from generated code
add_library(RRC_LIB ${rrc_source}
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg_NB_IoT.c)
${OPENAIR2_DIR}/RRC/LTE/MESSAGES/asn1_msg.c)
#${OPENAIR2_DIR}/RRC/NBIOT/MESSAGES/asn1_msg_NB_IoT.c
add_dependencies(RRC_LIB rrc_flag)
include_directories ("${RRC_FULL_DIR}")
@@ -770,6 +770,7 @@ include_directories("${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0")
include_directories("${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0")
include_directories("${OPENAIR2_DIR}/RRC/LTE/MESSAGES")
include_directories("${OPENAIR2_DIR}/RRC/LTE")
include_directories("${OPENAIR2_DIR}/RRC/NBIOT")
include_directories("${OPENAIR_DIR}/common/utils")
include_directories("${OPENAIR_DIR}/common/utils/ocp_itti")
include_directories("${OPENAIR3_DIR}/NAS/COMMON")
@@ -1059,6 +1060,18 @@ set(SCHED_SRC
add_library(SCHED_LIB ${SCHED_SRC})
add_dependencies(SCHED_LIB rrc_flag)
# Physical Channel Procedures Scheduling for NB-IoT
################################"
set(SCHED_SRC_NB_IoT
# ${OPENAIR1_DIR}/SCHED_NBIOT/fapi_l1.c
${OPENAIR1_DIR}/SCHED_NBIOT/phy_procedures_lte_eNb_NB_IoT.c
${OPENAIR1_DIR}/SCHED_NBIOT/IF_Module_L1_primitives_NB_IoT.c
${OPENAIR1_DIR}/SCHED_NBIOT/phy_procedures_lte_common_NB_IoT.c
# ${OPENAIR1_DIR}/SCHED/phy_procedures_lte_common.c
)
add_library(SCHED_NB_IoT_LIB ${SCHED_SRC_NB_IoT})
add_dependencies(SCHED_NB_IoT_LIB rrc_flag)
set(SCHED_SRC_RU
${OPENAIR1_DIR}/SCHED/ru_procedures.c
${OPENAIR1_DIR}/SCHED/prach_procedures.c
@@ -1164,22 +1177,31 @@ set(PHY_SRC_COMMON
${OPENAIR1_DIR}/PHY/MODULATION/ofdm_mod.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_sync_time.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_cell_spec_NB_IoT.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_uespec.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_dl_mbsfn.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_ul_ref_NB_IoT.c
${OPENAIR1_DIR}/PHY/LTE_REFSIG/lte_gold_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_lte.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c
${OPENAIR1_DIR}/PHY/CODING/ccoding_byte_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/crc_byte.c
${OPENAIR1_DIR}/PHY/CODING/crc_byte_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_sse.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte_turbo_decoder_sse_16bit.c
${OPENAIR1_DIR}/PHY/CODING/3gpplte.c
${PHY_TURBOIF}
${OPENAIR1_DIR}/PHY/CODING/lte_rate_matching.c
${OPENAIR1_DIR}/PHY/CODING/viterbi.c
${OPENAIR1_DIR}/PHY/CODING/viterbi_lte.c
${OPENAIR1_DIR}/PHY/INIT/init_top.c
${OPENAIR1_DIR}/PHY/INIT/lte_parms.c
${OPENAIR1_DIR}/PHY/INIT/lte_parms_NB_IoT.c
${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
${OPENAIR1_DIR}/PHY/TOOLS/cadd_vv.c
${OPENAIR1_DIR}/PHY/TOOLS/lte_dfts.c
@@ -1195,6 +1217,23 @@ set(PHY_SRC_COMMON
)
set(PHY_SRC
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/SIB_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dci_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dlsch_coding_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dlsch_modulation_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dlsch_scrambling_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/lte_mcs_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/ulsch_demodulation_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/ulsch_decoding_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/lte_Isc_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/nprach_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/nsss_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/npbch_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/pilots_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/npss_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_TRANSPORT/dci_tools_NB_IoT.c
${OPENAIR1_DIR}/PHY/NBIoT_ESTIMATION/lte_ul_channel_estimation_NB_IoT.c
${OPENAIR1_DIR}/PHY/CODING/lte_segmentation_NB_IoT.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/pss.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss.c
${OPENAIR1_DIR}/PHY/LTE_TRANSPORT/sss_gen.c
@@ -1219,6 +1258,7 @@ set(PHY_SRC
# ${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
${OPENAIR1_DIR}/PHY/LTE_ESTIMATION/lte_eNB_measurements.c
${OPENAIR1_DIR}/PHY/INIT/lte_init.c
${OPENAIR1_DIR}/PHY/INIT/lte_init_NB_IoT.c
)
set(PHY_SRC_RU
@@ -1331,6 +1371,7 @@ set(RLC_UM_DIR ${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0)
set(RLC_AM_DIR ${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0)
set(RLC_TM_DIR ${OPENAIR2_DIR}/LAYER2/RLC/TM_v9.3.0)
set(RRC_DIR ${OPENAIR2_DIR}/RRC/LTE)
set(RRC_NB_DIR ${OPENAIR2_DIR}/RRC/NBIOT)
set(PDCP_DIR ${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0)
set(L2_SRC
${OPENAIR2_DIR}/LAYER2/openair2_proc.c
@@ -1368,12 +1409,16 @@ set(L2_SRC
${RLC_DIR}/rlc.c
${RLC_DIR}/rlc_rrc.c
${RLC_DIR}/rlc_mpls.c
# ${RRC_DIR}/rrc_UE.c
#${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_NB_DIR}/rrc_eNB_NB_IoT.c
${RRC_DIR}/rrc_eNB_S1AP.c
${RRC_DIR}/rrc_eNB_UE_context.c
${RRC_NB_DIR}/rrc_eNB_UE_context_NB_IoT.c
${RRC_DIR}/rrc_common.c
#${RRC_NB_DIR}/rrc_common_NB_IoT.c
${RRC_DIR}/L2_interface.c
${RRC_NB_DIR}/L2_interface_NB_IoT.c
${RRC_DIR}/L2_interface_common.c
${RRC_DIR}/L2_interface_ue.c
)
@@ -1422,7 +1467,10 @@ set(L2_SRC_UE
set (MAC_SRC
#${PHY_INTERFACE_DIR}/phy_stub_UE.c
${PHY_INTERFACE_DIR}/IF_Module.c
${PHY_INTERFACE_DIR}/IF_Module_NB_IoT.c
${PHY_INTERFACE_DIR}/IF_Module_L2_primitives_NB_IoT.c
${MAC_DIR}/main.c
${MAC_DIR}/main_NB_IoT.c
#${MAC_DIR}/main_ue.c
#${MAC_DIR}/ue_procedures.c
#${MAC_DIR}/ra_procedures.c
@@ -1430,16 +1478,23 @@ set (MAC_SRC
${MAC_DIR}/rar_tools.c
#${MAC_DIR}/rar_tools_ue.c
${MAC_DIR}/eNB_scheduler.c
${MAC_DIR}/eNB_scheduler_NB_IoT.c
${MAC_DIR}/eNB_scheduler_dlsch.c
${MAC_DIR}/eNB_scheduler_dlsch_NB_IoT.c
${MAC_DIR}/eNB_scheduler_ulsch.c
${MAC_DIR}/eNB_scheduler_ulsch_NB_IoT.c
${MAC_DIR}/eNB_scheduler_mch.c
${MAC_DIR}/eNB_scheduler_bch.c
${MAC_DIR}/eNB_scheduler_bch_NB_IoT.c
${MAC_DIR}/eNB_scheduler_primitives.c
${MAC_DIR}/eNB_scheduler_RA.c
${MAC_DIR}/eNB_scheduler_RA_NB_IoT.c
${MAC_DIR}/eNB_scheduler_fairRR.c
${MAC_DIR}/eNB_scheduler_phytest.c
${MAC_DIR}/pre_processor.c
${MAC_DIR}/config.c
${MAC_DIR}/config_NB_IoT.c
${MAC_DIR}/schedule_tool_NB_IoT.c
#${MAC_DIR}/config_ue.c
)
@@ -1459,6 +1514,7 @@ set (ENB_APP_SRC
${OPENAIR2_DIR}/ENB_APP/enb_config_SL.c
${OPENAIR2_DIR}/ENB_APP/enb_config_eMTC.c
${OPENAIR2_DIR}/ENB_APP/RRC_config_tools.c
${OPENAIR2_DIR}/ENB_APP/NB_IoT_config.c
)
add_library(L2
@@ -2089,7 +2145,7 @@ add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag)
target_link_libraries (lte-softmodem
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB SCHED_RU_LIB PHY_COMMON PHY PHY_RU LFDS L2
RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP X2AP_LIB X2AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_NB_IoT_LIB SCHED_LIB SCHED_RU_LIB PHY PHY_COMMON PHY_RU LFDS L2
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB} LFDS7
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
-Wl,--end-group z dl)

View File

@@ -52,7 +52,7 @@
#include "PHY/defs_L1_NB_IoT.h"
#include "RRC/LTE/defs_NB_IoT.h"
#include "RRC/NBIOT/defs_NB_IoT.h"

View File

@@ -185,6 +185,14 @@ ID = ENB_RRC_CONNECTION_REQUEST
DESC = RRC connection request
GROUP = ALL:RRC:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti
ID = ENB_RRC_CONNECTION_RESUME_REQUEST
DESC = RRC connection resume request
GROUP = ALL:RRC:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti
ID = ENB_RRC_CONNECTION_RESUME_COMPLETE
DESC = RRC connection resume complete request
GROUP = ALL:RRC:ENB
FORMAT = int,eNB_ID : int,frame : int,subframe : int,rnti
ID = ENB_RRC_CONNECTION_REJECT
DESC = RRC connection reject
GROUP = ALL:RRC:ENB

View File

@@ -110,7 +110,7 @@ void msc_log_message(
#else
#define MESSAGE_CHART_GENERATOR msc_interface.msc_loaded
#define MESSAGE_CHART_GENERATOR msc_interface.msc_loaded
msc_interface_t msc_interface;
#define MSC_INIT(arg1,arg2) if(msc_interface.msc_loaded) msc_interface.msc_init(arg1,arg2)

View File

@@ -0,0 +1,159 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_CODING/ccoding_byte_NB_IoT.c
* \Fucntions for CRC attachment and tail-biting convolutional coding for NPBCH channel, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#include "PHY/CODING/defs_NB_IoT.h"
unsigned char ccodelte_table_NB_IoT[128]; // for transmitter
unsigned short glte_NB_IoT[] = { 0133, 0171, 0165 }; // {A,B} //renaimed but is exactly the same as the one in the old implementation
/*************************************************************************
Encodes for an arbitrary convolutional code of rate 1/3
with a constraint length of 7 bits.
The inputs are bit packed in octets (from MSB to LSB).
An optional 8-bit CRC (3GPP) can be added.
Trellis tail-biting is included here
*************************************************************************/
void ccode_encode_NB_IoT (int32_t numbits,
uint8_t add_crc,
uint8_t *inPtr,
uint8_t *outPtr,
uint16_t rnti)
{
uint32_t state;
uint8_t c, out, first_bit;
int8_t shiftbit=0;
uint16_t c16;
uint16_t next_last_byte=0;
uint32_t crc=0;
/* The input bit is shifted in position 8 of the state.
Shiftbit will take values between 1 and 8 */
state = 0;
if (add_crc == 2) {
crc = crc16_NB_IoT(inPtr,numbits); // crc is 2 bytes
// scramble with RNTI
crc ^= (((uint32_t)rnti)<<16); // XOR with crc
first_bit = 2;
c = (uint8_t)((crc>>16)&0xff);
} else {
next_last_byte = numbits>>3;
first_bit = (numbits-6)&7;
c = inPtr[next_last_byte-1];
}
// Perform Tail-biting
// get bits from last byte of input (or crc)
for (shiftbit = 0 ; shiftbit <(8-first_bit) ; shiftbit++) {
if ((c&(1<<(7-first_bit-shiftbit))) != 0)
state |= (1<<shiftbit);
}
state = state & 0x3f; // true initial state of Tail-biting CCode
state<<=1; // because of loop structure in CCode
while (numbits > 0) { // Tail-biting is applied to input bits , input 34 bits , output 102 bits
c = *inPtr++;
for (shiftbit = 7; (shiftbit>=0) && (numbits>0); shiftbit--,numbits--) {
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
}
out = ccodelte_table_NB_IoT[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
*outPtr++ = (out>>2)&1;
}
}
// now code 16-bit CRC for DCI // Tail-biting is applied to CRC bits , input 16 bits , output 48 bits
if (add_crc == 2) {
c16 = (uint16_t)(crc>>16);
for (shiftbit = 15; (shiftbit>=0); shiftbit--) {
state >>= 1;
if ((c16&(1<<shiftbit)) != 0) {
state |= 64;
}
out = ccodelte_table_NB_IoT[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
*outPtr++ = (out>>2)&1;
}
}
}
/*************************************************************************
Functions to initialize the code tables
*************************************************************************/
/* Basic code table initialization for constraint length 7 */
/* Input in MSB, followed by state in 6 LSBs */
void ccodelte_init_NB_IoT(void)
{
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
ccodelte_table_NB_IoT[i] = 0;
/* Compute 3 output bits */
for (j = 0; j < 3; j++) {
sum = 0;
for (k = 0; k < 7; k++)
if ((i & glte_NB_IoT[j]) & (1 << k))
sum++;
/* Write the sum modulo 2 in bit j */
ccodelte_table_NB_IoT[i] |= (sum & 1) << j;
}
}
}

View File

@@ -36,7 +36,7 @@
#define CRC8 3
#define MAX_TURBO_ITERATIONS_MBSFN 8
#define MAX_TURBO_ITERATIONS max_turbo_iterations
#define MAX_TURBO_ITERATIONS 4
typedef struct {
unsigned short nb_bits;

View File

@@ -0,0 +1,210 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* file: crc_byte.c
purpose: generate 3GPP LTE CRCs. Byte-oriented implementation of CRC's
author: raymond.knopp@eurecom.fr, matthieu.kanj@b-com.com
date: 07/2017
*/
#ifndef USER_MODE
#define __NO_VERSION__
#endif
//#include "PHY/types.h"
//#include "defs.h" // to delete in final code version
#include "defs_NB_IoT.h"
/*ref 36-212 v8.6.0 , pp 8-9 */
/* the highest degree is set by default */
unsigned int poly24a_NB_IoT = 0x864cfb00; //1000 0110 0100 1100 1111 1011 D^24 + D^23 + D^18 + D^17 + D^14 + D^11 + D^10 + D^7 + D^6 + D^5 + D^4 + D^3 + D + 1
unsigned int poly24b_NB_IoT = 0x80006300; // 1000 0000 0000 0000 0110 0011 D^24 + D^23 + D^6 + D^5 + D + 1
unsigned int poly16_NB_IoT = 0x10210000; // 0001 0000 0010 0001 D^16 + D^12 + D^5 + 1
unsigned int poly12_NB_IoT = 0x80F00000; // 1000 0000 1111 D^12 + D^11 + D^3 + D^2 + D + 1
unsigned int poly8_NB_IoT = 0x9B000000; // 1001 1011 D^8 + D^7 + D^4 + D^3 + D + 1
/*********************************************************
For initialization && verification purposes,
bit by bit implementation with any polynomial
The first bit is in the MSB of each byte
*********************************************************/
unsigned int crcbit_NB_IoT (unsigned char * inputptr, int octetlen, unsigned int poly)
{
unsigned int i, crc = 0, c;
while (octetlen-- > 0) {
c = (*inputptr++) << 24;
for (i = 8; i != 0; i--) {
if ((1 << 31) & (c ^ crc))
crc = (crc << 1) ^ poly;
else
crc <<= 1;
c <<= 1;
}
}
return crc;
}
/*********************************************************
crc table initialization
*********************************************************/
static unsigned int crc24aTable_NB_IoT[256];
static unsigned int crc24bTable_NB_IoT[256];
static unsigned short crc16Table_NB_IoT[256];
static unsigned short crc12Table_NB_IoT[256];
static unsigned char crc8Table_NB_IoT[256];
void crcTableInit_NB_IoT (void)
{
unsigned char c = 0;
do {
crc24aTable_NB_IoT[c] = crcbit_NB_IoT (&c, 1, poly24a_NB_IoT);
crc24bTable_NB_IoT[c] = crcbit_NB_IoT (&c, 1, poly24b_NB_IoT);
crc16Table_NB_IoT[c] = (unsigned short) (crcbit_NB_IoT (&c, 1, poly16_NB_IoT) >> 16);
crc12Table_NB_IoT[c] = (unsigned short) (crcbit_NB_IoT (&c, 1, poly12_NB_IoT) >> 16);
crc8Table_NB_IoT[c] = (unsigned char) (crcbit_NB_IoT (&c, 1, poly8_NB_IoT) >> 24);
} while (++c);
}
/*********************************************************
Byte by byte implementations,
assuming initial byte is 0 padded (in MSB) if necessary
*********************************************************/
unsigned int crc24a_NB_IoT (unsigned char * inptr, int bitlen)
{
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = (crc << 8) ^ crc24aTable_NB_IoT[(*inptr++) ^ (crc >> 24)];
}
if (resbit > 0)
crc = (crc << resbit) ^ crc24aTable_NB_IoT[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
return crc;
}
unsigned int crc24b_NB_IoT (unsigned char * inptr, int bitlen)
{
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = (crc << 8) ^ crc24bTable_NB_IoT[(*inptr++) ^ (crc >> 24)];
}
if (resbit > 0)
crc = (crc << resbit) ^ crc24bTable_NB_IoT[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
return crc;
}
unsigned int crc16_NB_IoT (unsigned char * inptr, int bitlen)
{
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = (crc << 8) ^ (crc16Table_NB_IoT[(*inptr++) ^ (crc >> 24)] << 16);
}
if (resbit > 0)
crc = (crc << resbit) ^ (crc16Table_NB_IoT[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
return crc;
}
unsigned int crc8_NB_IoT (unsigned char * inptr, int bitlen)
{
int octetlen, resbit;
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = crc8Table_NB_IoT[(*inptr++) ^ (crc >> 24)] << 24;
}
if (resbit > 0)
crc = (crc << resbit) ^ (crc8Table_NB_IoT[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24);
return crc;
}
//#ifdef DEBUG_CRC
/*******************************************************************/
/**
Test code
********************************************************************/
// #include <stdio.h>
// main()
// {
// unsigned char test[] = "Thebigredfox";
// crcTableInit();
// printf("%x\n", crcbit(test, sizeof(test) - 1, poly24));
// printf("%x\n", crc24(test, (sizeof(test) - 1)*8));
// printf("%x\n", crcbit(test, sizeof(test) - 1, poly8));
// printf("%x\n", crc8(test, (sizeof(test) - 1)*8));
// }
//#endif

564
openair1/PHY/CODING/defs.h Normal file
View File

@@ -0,0 +1,564 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* file: PHY/CODING/defs.h
purpose: Top-level definitions, data types and function prototypes for openairinterface coding blocks
author: raymond.knopp@eurecom.fr
date: 21.10.2009
*/
#ifndef __CODING_DEFS__H__
#define __CODING_DEFS__H__
#include <stdint.h>
#ifndef NO_OPENAIR1
#include "PHY/defs.h"
#else
#include "PHY/TOOLS/time_meas.h"
#endif
#define CRC24_A 0
#define CRC24_B 1
#define CRC16 2
#define CRC8 3
#define MAX_TURBO_ITERATIONS_MBSFN 8
#define MAX_TURBO_ITERATIONS 4
#define LTE_NULL 2
/** @addtogroup _PHY_CODING_BLOCKS_
* @{
*/
/** \fn lte_segmentation(uint8_t *input_buffer,
uint8_t **output_buffers,
uint32_t B,
uint32_t *C,
uint32_t *Cplus,
uint32_t *Cminus,
uint32_t *Kplus,
uint32_t *Kminus,
uint32_t *F)
\brief This function implements the LTE transport block segmentation algorithm from 36-212, V8.6 2009-03.
@param input_buffer
@param output_buffers
@param B
@param C
@param Cplus
@param Cminus
@param Kplus
@param Kminus
@param F
*/
int32_t lte_segmentation(uint8_t *input_buffer,
uint8_t **output_buffers,
uint32_t B,
uint32_t *C,
uint32_t *Cplus,
uint32_t *Cminus,
uint32_t *Kplus,
uint32_t *Kminus,
uint32_t *F);
/** \fn int16_t estimate_ue_tx_power(uint32_t tbs, uint32_t nb_rb, uint8_t control_only, lte_prefix_type_t ncp, uint8_t use_srs)
\brief this functions calculates the delta MCS in dB based on the lte_segmentation function
\param tbs transport block size
\param nb_rb number of required rb
\param control_only a flag for the type of data
\param ncp cyclic prefix
\param use_srs a flag indicating the use of srs in the current SF
\returns ue_tx_power estimated ue tx power = delat_ mcs + bw_factor
*/
int16_t estimate_ue_tx_power(uint32_t tbs,
uint32_t nb_rb,
uint8_t control_only,
lte_prefix_type_t ncp,
uint8_t use_srs);
/** \fn uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w)
\brief This is the subblock interleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16.
This function takes the d-sequence and generates the w-sequence. The nu-sequence from 36-212 is implicit.
\param D Number of systematic bits plus 4 (plus 4 for termination)
\param d Pointer to input (d-sequence, turbo code output)
\param w Pointer to output (w-sequence, interleaver output)
\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212)
*/
uint32_t sub_block_interleaving_turbo(uint32_t D, uint8_t *d,uint8_t *w);
/** \fn uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w)
\brief This is the subblock interleaving algorithm for convolutionally coded blocks from 36-212 (Release 8, 8.6 2009-03), pages 15-16.
This function takes the d-sequence and generates the w-sequence. The nu-sequence from 36-212 is implicit.
\param D Number of input bits
\param d Pointer to input (d-sequence, convolutional code output)
\param w Pointer to output (w-sequence, interleaver output)
\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212)
*/
uint32_t sub_block_interleaving_cc(uint32_t D, uint8_t *d,uint8_t *w);
/** \fn void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w)
\brief This is the subblock deinterleaving algorithm from 36-212 (Release 8, 8.6 2009-03), pages 15-16.
This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit.
\param D Number of systematic bits plus 4 (plus 4 for termination)
\param d Pointer to output (d-sequence, turbo code output)
\param w Pointer to input (w-sequence, interleaver output)
*/
void sub_block_deinterleaving_turbo(uint32_t D, int16_t *d,int16_t *w);
/** \fn void sub_block_deinterleaving_cc(uint32_t D, int8_t *d,int8_t *w)
\brief This is the subblock deinterleaving algorithm for convolutionally-coded data from 36-212 (Release 8, 8.6 2009-03), pages 15-16.
This function takes the w-sequence and generates the d-sequence. The nu-sequence from 36-212 is implicit.
\param D Number of input bits
\param d Pointer to output (d-sequence, turbo code output)
\param w Pointer to input (w-sequence, interleaver output)
*/
void sub_block_deinterleaving_cc(uint32_t D,int8_t *d,int8_t *w);
/** \fn generate_dummy_w(uint32_t D, uint8_t *w,uint8_t F)
\brief This function generates a dummy interleaved sequence (first row) for receiver, in order to identify
the NULL positions used to make the matrix complete.
\param D Number of systematic bits plus 4 (plus 4 for termination)
\param w This is the dummy sequence (first row), it will contain zeros and at most 31 "LTE_NULL" values
\param F Number of filler bits due added during segmentation
\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212)
*/
uint32_t generate_dummy_w(uint32_t D, uint8_t *w, uint8_t F);
/** \fn generate_dummy_w_cc(uint32_t D, uint8_t *w)
\brief This function generates a dummy interleaved sequence (first row) for receiver (convolutionally-coded data), in order to identify the NULL positions used to make the matrix complete.
\param D Number of systematic bits plus 4 (plus 4 for termination)
\param w This is the dummy sequence (first row), it will contain zeros and at most 31 "LTE_NULL" values
\returns Interleaving matrix cardinality (\f$K_{\pi}\f$ from 36-212)
*/
uint32_t generate_dummy_w_cc(uint32_t D, uint8_t *w);
/** \fn uint32_t lte_rate_matching_turbo(uint32_t RTC,
uint32_t G,
uint8_t *w,
uint8_t *e,
uint8_t C,
uint32_t Nsoft,
uint8_t Mdlharq,
uint8_t Kmimo,
uint8_t rvidx,
uint8_t Qm,
uint8_t Nl,
uint8_t r)
\brief This is the LTE rate matching algorithm for Turbo-coded channels (e.g. DLSCH,ULSCH). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 )
\param RTC R^TC_subblock from subblock interleaver (number of rows in interleaving matrix) for up to 8 segments
\param G This the number of coded transport bits allocated in sub-frame
\param w This is a pointer to the w-sequence (second interleaver output)
\param e This is a pointer to the e-sequence (rate matching output, channel input/output bits)
\param C Number of segments (codewords) in the sub-frame
\param Nsoft Total number of soft bits (from UE capabilities in 36-306)
\param Mdlharq Number of HARQ rounds
\param Kmimo MIMO capability for this DLSCH (0 = no MIMO)
\param rvidx round index (0-3)
\param Qm modulation order (2,4,6)
\param Nl number of layers (1,2)
\param r segment number
\returns \f$E\f$, the number of coded bits per segment */
uint32_t lte_rate_matching_turbo(uint32_t RTC,
uint32_t G,
uint8_t *w,
uint8_t *e,
uint8_t C,
uint32_t Nsoft,
uint8_t Mdlharq,
uint8_t Kmimo,
uint8_t rvidx,
uint8_t Qm,
uint8_t Nl,
uint8_t r,
uint8_t nb_rb,
uint8_t m);
/**
\brief This is the LTE rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 )
\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix) for up to 8 segments
\param E Number of coded channel bits
\param w This is a pointer to the w-sequence (second interleaver output)
\param e This is a pointer to the e-sequence (rate matching output, channel input/output bits)
\returns \f$E\f$, the number of coded bits per segment */
uint32_t lte_rate_matching_cc(uint32_t RCC,
uint16_t E,
uint8_t *w,
uint8_t *e);
/**
\brief This is the LTE rate matching algorithm for Turbo-coded channels (e.g. DLSCH,ULSCH). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 )
\param RTC R^TC_subblock from subblock interleaver (number of rows in interleaving matrix)
\param G This the number of coded transport bits allocated in sub-frame
\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds
\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions
\param soft_input This is a pointer to the soft channel output
\param C Number of segments (codewords) in the sub-frame
\param Nsoft Total number of soft bits (from UE capabilities in 36-306)
\param Mdlharq Number of HARQ rounds
\param Kmimo MIMO capability for this DLSCH (0 = no MIMO)
\param rvidx round index (0-3)
\param clear 1 means clear soft buffer (start of HARQ round)
\param Qm modulation order (2,4,6)
\param Nl number of layers (1,2)
\param r segment number
\param E_out the number of coded bits per segment
\returns 0 on success, -1 on failure
*/
int lte_rate_matching_turbo_rx(uint32_t RTC,
uint32_t G,
int16_t *w,
uint8_t *dummy_w,
int16_t *soft_input,
uint8_t C,
uint32_t Nsoft,
uint8_t Mdlharq,
uint8_t Kmimo,
uint8_t rvidx,
uint8_t clear,
uint8_t Qm,
uint8_t Nl,
uint8_t r,
uint32_t *E_out);
uint32_t lte_rate_matching_turbo_rx_abs(uint32_t RTC,
uint32_t G,
double *w,
uint8_t *dummy_w,
double *soft_input,
uint8_t C,
uint32_t Nsoft,
uint8_t Mdlharq,
uint8_t Kmimo,
uint8_t rvidx,
uint8_t clear,
uint8_t Qm,
uint8_t Nl,
uint8_t r,
uint32_t *E_out);
/**
\brief This is the LTE rate matching algorithm for Convolutionally-coded channels (e.g. BCH,DCI,UCI). It is taken directly from 36-212 (Rel 8 8.6, 2009-03), pages 16-18 )
\param RCC R^CC_subblock from subblock interleaver (number of rows in interleaving matrix)
\param E This the number of coded bits allocated for channel
\param w This is a pointer to the soft w-sequence (second interleaver output) with soft-combined outputs from successive HARQ rounds
\param dummy_w This is the first row of the interleaver matrix for identifying/discarding the "LTE-NULL" positions
\param soft_input This is a pointer to the soft channel output
\returns \f$E\f$, the number of coded bits per segment
*/
void lte_rate_matching_cc_rx(uint32_t RCC,
uint16_t E,
int8_t *w,
uint8_t *dummy_w,
int8_t *soft_input);
/** \fn void ccodedot11_encode(uint32_t numbytes,uint8_t *inPtr,uint8_t *outPtr,uint8_t puncturing)
\brief This function implements a rate 1/2 constraint length 7 convolutional code.
@param numbytes Number of bytes to encode
@param inPtr Pointer to input buffer
@param outPtr Pointer to output buffer
@param puncturing Puncturing pattern (Not used at present, to be removed)
*/
void ccodedot11_encode (uint32_t numbytes,
uint8_t *inPtr,
uint8_t *outPtr,
uint8_t puncturing);
/*!\fn void ccodedot11_init(void)
\brief This function initializes the generator polynomials for an 802.11 convolutional code.*/
void ccodedot11_init(void);
/*!\fn void ccodedot11_init_inv(void)
\brief This function initializes the trellis structure for decoding an 802.11 convolutional code.*/
void ccodedot11_init_inv(void);
/*!\fn void teillis_table_init(void)
\brief This function initializes the trellis structure for 3GPP LTE Turbo code.*/
void treillis_table_init(void);
/*\fn void threegpplte_turbo_encoder(uint8_t *input,uint16_t input_length_bytes,uint8_t *output,uint8_t F,uint16_t interleaver_f1,uint16_t interleaver_f2)
\brief This function implements a rate 1/3 8-state parralel concatenated turbo code (3GPP-LTE).
@param input Pointer to input buffer
@param input_length_bytes Number of bytes to encode
@param output Pointer to output buffer
@param F Number of filler bits at input
@param interleaver_f1 F1 generator
@param interleaver_f2 F2 generator
*/
void threegpplte_turbo_encoder(uint8_t *input,
uint16_t input_length_bytes,
uint8_t *output,
uint8_t F,
uint16_t interleaver_f1,
uint16_t interleaver_f2);
/** \fn void ccodelte_encode(int32_t numbits,uint8_t add_crc, uint8_t *inPtr,uint8_t *outPtr,uint16_t rnti)
\brief This function implements the LTE convolutional code of rate 1/3
with a constraint length of 7 bits. The inputs are bit packed in octets
(from MSB to LSB). Trellis tail-biting is included here.
@param numbits Number of bits to encode
@param add_crc crc to be appended (8 bits) if add_crc = 1
@param inPtr Pointer to input buffer
@param outPtr Pointer to output buffer
@param rnti RNTI for CRC scrambling
*/
void
ccodelte_encode (int32_t numbits,
uint8_t add_crc,
uint8_t *inPtr,
uint8_t *outPtr,
uint16_t rnti);
/*!\fn void ccodelte_init(void)
\brief This function initializes the generator polynomials for an LTE convolutional code.*/
void ccodelte_init(void);
/*!\fn void ccodelte_init_inv(void)
\brief This function initializes the trellis structure for decoding an LTE convolutional code.*/
void ccodelte_init_inv(void);
/*!\fn void ccodelte_init(void)
\brief This function initializes the generator polynomials for an DAB convolutional code (first 3 bits).*/
void ccodedab_init(void);
/*!\fn void ccodelte_init_inv(void)
\brief This function initializes the trellis structure for decoding an DAB convolutional code (first 3 bits).*/
void ccodedab_init_inv(void);
/*!\fn void crcTableInit(void)
\brief This function initializes the different crc tables.*/
void crcTableInit (void);
/*!\fn void init_td8(void)
\brief This function initializes the tables for 8-bit LLR Turbo decoder.*/
void init_td8 (void);
/*!\fn void init_td16(void)
\brief This function initializes the tables for 16-bit LLR Turbo decoder.*/
void init_td16 (void);
#ifdef __AVX2__
/*!\fn void init_td8(void)
\brief This function initializes the tables for 8-bit LLR Turbo decoder (AVX2).*/
void init_td8avx2 (void);
/*!\fn void init_td16(void)
\brief This function initializes the tables for 16-bit LLR Turbo decoder (AVX2).*/
void init_td16avx2 (void);
#endif
/*!\fn uint32_t crc24a(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 24-bit crc ('a' variant for overall transport block)
based on 3GPP UMTS/LTE specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits
*/
uint32_t crc24a (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc24b(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 24-bit crc ('b' variant for transport-block segments)
based on 3GPP UMTS/LTE specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits
*/
uint32_t crc24b (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc16(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 16-bit crc based on 3GPP UMTS specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits*/
uint32_t crc16 (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc12(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 12-bit crc based on 3GPP UMTS specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits*/
uint32_t crc12 (uint8_t *inPtr, int32_t bitlen);
/*!\fn uint32_t crc8(uint8_t *inPtr, int32_t bitlen)
\brief This computes a 8-bit crc based on 3GPP UMTS specifications.
@param inPtr Pointer to input byte stream
@param bitlen length of inputs in bits*/
uint32_t crc8 (uint8_t *inPtr, int32_t bitlen);
/*!\fn void phy_viterbi_dot11_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n,int offset,int traceback)
\brief This routine performs a SIMD optmized Viterbi decoder for the 802.11 64-state convolutional code. It can be
run in segments with final trace back after last segment.
@param y Pointer to soft input (coded on 8-bits but should be limited to 4-bit precision to avoid overflow)
@param decoded_bytes Pointer to decoded output
@param n Length of input/trellis depth in bits for this run
@param offset offset in receive buffer for segment on which to operate
@param traceback flag to indicate that traceback should be performed*/
void phy_viterbi_dot11_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n);
/*!\fn void phy_viterbi_lte_sse2(int8_t *y, uint8_t *decoded_bytes, uint16_t n)
\brief This routine performs a SIMD optmized Viterbi decoder for the LTE 64-state tail-biting convolutional code.
@param y Pointer to soft input (coded on 8-bits but should be limited to 4-bit precision to avoid overflow)
@param decoded_bytes Pointer to decoded output
@param n Length of input/trellis depth in bits*/
//void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n);
void phy_viterbi_lte_sse2(int8_t *y,uint8_t *decoded_bytes,uint16_t n);
/*!\fn void phy_generate_viterbi_tables(void)
\brief This routine initializes metric tables for the optimized Viterbi decoder.
*/
void phy_generate_viterbi_tables( void );
/*!\fn void phy_generate_viterbi_tables_lte(void)
\brief This routine initializes metric tables for the optimized LTE Viterbi decoder.
*/
void phy_generate_viterbi_tables_lte( void );
/*!\fn int32_t rate_matching(uint32_t N_coded,
uint32_t N_input,
uint8_t *inPtr,
uint8_t N_bps,
uint32_t off)
\brief This routine performs random puncturing of a coded sequence.
@param N_coded Number of coding bits to be output
@param N_input Number of input bits
@param *inPtr Pointer to coded input
@param N_bps Number of modulation bits per symbol (1,2,4)
@param off Offset for seed
*/
int32_t rate_matching(uint32_t N_coded,
uint32_t N_input,
uint8_t *inPtr,
uint8_t N_bps,
uint32_t off);
int32_t rate_matching_lte(uint32_t N_coded,
uint32_t N_input,
uint8_t *inPtr,
uint32_t off);
/*!
\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 16-bit
LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU)
@param y LLR input (16-bit precision)
@param decoded_bytes Pointer to decoded output
@param n number of coded bits (including tail bits)
@param max_iterations The maximum number of iterations to perform
@param interleaver_f1 F1 generator
@param interleaver_f2 F2 generator
@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8)
@param F Number of filler bits at start of packet
@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0)
*/
uint8_t phy_threegpplte_turbo_decoder16(int16_t *y,
uint8_t *decoded_bytes,
uint16_t n,
uint16_t interleaver_f1,
uint16_t interleaver_f2,
uint8_t max_iterations,
uint8_t crc_type,
uint8_t F,
time_stats_t *init_stats,
time_stats_t *alpha_stats,
time_stats_t *beta_stats,
time_stats_t *gamma_stats,
time_stats_t *ext_stats,
time_stats_t *intl1_stats,
time_stats_t *intl2_stats);
uint8_t phy_threegpplte_turbo_decoder16avx2(int16_t *y,
int16_t *y2,
uint8_t *decoded_bytes,
uint8_t *decoded_bytes2,
uint16_t n,
uint16_t interleaver_f1,
uint16_t interleaver_f2,
uint8_t max_iterations,
uint8_t crc_type,
uint8_t F,
time_stats_t *init_stats,
time_stats_t *alpha_stats,
time_stats_t *beta_stats,
time_stats_t *gamma_stats,
time_stats_t *ext_stats,
time_stats_t *intl1_stats,
time_stats_t *intl2_stats);
/*!
\brief This routine performs max-logmap detection for the 3GPP turbo code (with termination). It is optimized for SIMD processing and 8-bit
LLR arithmetic, and requires SSE2,SSSE3 and SSE4.1 (gcc >=4.3 and appropriate CPU)
@param y LLR input (16-bit precision)
@param decoded_bytes Pointer to decoded output
@param n number of coded bits (including tail bits)
@param max_iterations The maximum number of iterations to perform
@param interleaver_f1 F1 generator
@param interleaver_f2 F2 generator
@param crc_type Length of 3GPPLTE crc (CRC24a,CRC24b,CRC16,CRC8)
@param F Number of filler bits at start of packet
@returns number of iterations used (this is 1+max if incorrect crc or if crc_len=0)
*/
uint8_t phy_threegpplte_turbo_decoder8(int16_t *y,
uint8_t *decoded_bytes,
uint16_t n,
uint16_t interleaver_f1,
uint16_t interleaver_f2,
uint8_t max_iterations,
uint8_t crc_type,
uint8_t F,
time_stats_t *init_stats,
time_stats_t *alpha_stats,
time_stats_t *beta_stats,
time_stats_t *gamma_stats,
time_stats_t *ext_stats,
time_stats_t *intl1_stats,
time_stats_t *intl2_stats);
uint8_t phy_threegpplte_turbo_decoder_scalar(int16_t *y,
uint8_t *decoded_bytes,
uint16_t n,
uint16_t interleaver_f1,
uint16_t interleaver_f2,
uint8_t max_iterations,
uint8_t crc_type,
uint8_t F,
uint8_t inst);
/** @} */
uint32_t crcbit (uint8_t * ,
int32_t,
uint32_t);
int16_t reverseBits(int32_t ,int32_t);
void phy_viterbi_dot11(int8_t *,uint8_t *,uint16_t);
#endif

View File

@@ -92,6 +92,8 @@ void ccode_encode_NB_IoT (int32_t numbits,
\brief This function initializes the generator polynomials for an LTE convolutional code.*/
void ccodelte_init_NB_IoT(void);
void ccodelte_init2_NB_IoT(void);
/*!\fn void crcTableInit(void)
\brief This function initializes the different crc tables.*/
void crcTableInit_NB_IoT (void);

View File

@@ -0,0 +1,210 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
unsigned short f1f2mat_old[2*188] = {3, 10,
7, 12,
19, 42,
7, 16,
7, 18,
11, 20,
5, 22,
11, 24,
7, 26,
41, 84,
103, 90,
15, 32,
9, 34,
17, 108,
9, 38,
21, 120,
101, 84,
21, 44,
57, 46,
23, 48,
13, 50,
27, 52,
11, 36,
27, 56,
85, 58,
29, 60,
33, 62,
15, 32,
17, 198,
33, 68,
103, 210,
19, 36,
19, 74,
37, 76,
19, 78,
21, 120,
21, 82,
115, 84,
193, 86,
21, 44,
133, 90,
81, 46,
45, 94,
23, 48,
243, 98,
151, 40,
155, 102,
25, 52,
51, 106,
47, 72,
91, 110,
29, 168,
29, 114,
247, 58,
29, 118,
89, 180,
91, 122,
157, 62,
55, 84,
31, 64,
17, 66,
35, 68,
227, 420,
65, 96,
19, 74,
37, 76,
41, 234,
39, 80,
185, 82,
43, 252,
21, 86,
155, 44,
79, 120,
139, 92,
23, 94,
217, 48,
25, 98,
17, 80,
127, 102,
25, 52,
239, 106,
17, 48,
137, 110,
215, 112,
29, 114,
15, 58,
147, 118,
29, 60,
59, 122,
65, 124,
55, 84,
31, 64,
17, 66,
171, 204,
67, 140,
35, 72,
19, 74,
39, 76,
19, 78,
199, 240,
21, 82,
211, 252,
21, 86,
43, 88,
149, 60,
45, 92,
49, 846,
71, 48,
13, 28,
17, 80,
25, 102,
183, 104,
55, 954,
127, 96,
27, 110,
29, 112,
29, 114,
57, 116,
45, 354,
31, 120,
59, 610,
185, 124,
113, 420,
31, 64,
17, 66,
171, 136,
209, 420,
253, 216,
367, 444,
265, 456,
181, 468,
39, 80,
27, 164,
127, 504,
143, 172,
43, 88,
29, 300,
45, 92,
157, 188,
47, 96,
13, 28,
111, 240,
443, 204,
51, 104,
51, 212,
451, 192,
257, 220,
57, 336,
313, 228,
271, 232,
179, 236,
331, 120,
363, 244,
375, 248,
127, 168,
31, 64,
33, 130,
43, 264,
33, 134,
477, 408,
35, 138,
233, 280,
357, 142,
337, 480,
37, 146,
71, 444,
71, 120,
37, 152,
39, 462,
127, 234,
39, 158,
39, 80,
31, 96,
113, 902,
41, 166,
251, 336,
43, 170,
21, 86,
43, 174,
45, 176,
45, 178,
161, 120,
89, 182,
323, 184,
47, 186,
23, 94,
47, 190,
263, 480
};

View File

@@ -0,0 +1,223 @@
/***********************************************************************
**********************************************************************/
/*! \file PHY/LTE_CODING/lte_rate_matching_NB_IoT.c
* \Procedures for rate matching/interleaving for NB-IoT (turbo-coded transport channels) (TX/RX), TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
/* // check if this ifdef MAIN is required for NB-IoT
#ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#endif
*/
//#include "PHY/CODING/defs_NB_IoT.h"
#include "PHY/defs_L1_NB_IoT.h"
//#include "assertions.h"
//#include "PHY/LTE_REFSIG/defs_NB_IoT.h" // does this file is needed ?
static uint32_t bitrev_cc_NB_IoT[32] = {1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31,0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30};
uint32_t sub_block_interleaving_cc_NB_IoT(uint32_t D, uint8_t *d,uint8_t *w)
{
uint32_t RCC = (D>>5), ND, ND3; // D = 50 ,
uint32_t row,col,Kpi,index;
uint32_t index3,k;
if ((D&0x1f) > 0)
RCC++;
Kpi = (RCC<<5); // Kpi = 32
ND = Kpi - D;
ND3 = ND*3; // ND3 = ND*3 = 18 *3 = 54
k=0;
for (col=0; col<32; col++) {
index = bitrev_cc_NB_IoT[col];
index3 = 3*index;
for (row=0; row<RCC; row++) {
w[k] = d[(int32_t)index3-(int32_t)ND3];
w[Kpi+k] = d[(int32_t)index3-(int32_t)ND3+1];
w[(Kpi<<1)+k] = d[(int32_t)index3-(int32_t)ND3+2];
index3+=96;
index+=32;
k++;
}
}
return(RCC);
}
uint32_t lte_rate_matching_cc_NB_IoT(uint32_t RCC, // RRC = 2
uint16_t E, // E = 1600
uint8_t *w, // length
uint8_t *e) // length 1600
{
uint32_t ind=0,k;
uint16_t Kw = 3*(RCC<<5); // 3*64 = 192
for (k=0; k<E; k++) {
while(w[ind] == LTE_NULL_NB_IoT) {
ind++;
if (ind==Kw)
ind=0;
}
e[k] = w[ind];
ind++;
if (ind==Kw)
ind=0;
}
return(E);
}
//******************* below functions related to uplink transmission , to be reviwed *********
// this function should be adapted to NB-IoT , this deinterleaving is for LTE
void sub_block_deinterleaving_cc_NB_IoT(uint32_t D,int8_t *d,int8_t *w)
{
//WANG_Hao uint32_t RCC = (D>>5), ND, ND3;
uint32_t RCC = (D>>5);
ptrdiff_t ND, ND3;
uint32_t row,col,Kpi,index;
//WANG_Hao uint32_t index3,k;
ptrdiff_t index3;
uint32_t k;
if ((D&0x1f) > 0)
RCC++;
Kpi = (RCC<<5);
// Kpi3 = Kpi*3;
ND = Kpi - D;
ND3 = ND*3;
k=0;
for (col=0; col<32; col++) {
index = bitrev_cc_NB_IoT[col];
index3 = 3*index;
for (row=0; row<RCC; row++) {
d[index3-ND3] = w[k];
d[index3-ND3+1] = w[Kpi+k];
d[index3-ND3+2] = w[(Kpi<<1)+k];
index3+=96;
index+=32;
k++;
}
}
}
void lte_rate_matching_cc_rx_NB_IoT(uint32_t RCC,
uint16_t E,
int8_t *w,
uint8_t *dummy_w,
int8_t *soft_input)
{
uint32_t ind=0,k;
uint16_t Kw = 3*(RCC<<5);
uint32_t acc=1;
int16_t w16[Kw];
memset(w,0,Kw);
memset(w16,0,Kw*sizeof(int16_t));
for (k=0; k<E; k++) {
while(dummy_w[ind] == LTE_NULL_NB_IoT) {
ind++;
if (ind==Kw)
ind=0;
}
w16[ind] += soft_input[k];
ind++;
if (ind==Kw) {
ind=0;
acc++;
}
}
// rescale
for (ind=0; ind<Kw; ind++) {
// w16[ind]=(w16[ind]/acc);
if (w16[ind]>7)
w[ind]=7;
else if (w16[ind]<-8)
w[ind]=-8;
else
w[ind]=(int8_t)w16[ind];
}
}
uint32_t generate_dummy_w_cc_NB_IoT(uint32_t D, uint8_t *w)
{
uint32_t RCC = (D>>5), ND;
uint32_t col,Kpi,index;
int32_t k;
if ((D&0x1f) > 0)
RCC++;
Kpi = (RCC<<5);
// Kpi3 = Kpi*3;
ND = Kpi - D;
// copy d02 to dD2 (for mod Kpi operation from clause (4), p.16 of 36.212
k=0;
for (col=0; col<32; col++) {
index = bitrev_cc_NB_IoT[col];
if (index<ND) {
w[k] = LTE_NULL_NB_IoT;
w[Kpi+k] = LTE_NULL_NB_IoT;
w[(Kpi<<1)+k] = LTE_NULL_NB_IoT;
}
k+=RCC;
}
return(RCC);
}

View File

@@ -0,0 +1,152 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* file: lte_segmentation.c
purpose: Procedures for transport block segmentation for LTE (turbo-coded transport channels)
author: raymond.knopp@eurecom.fr
date: 21.10.2009
*/
#include "PHY/defs_L1_NB_IoT.h"
#include "SCHED_NBIOT/defs_NB_IoT.h"
//#define DEBUG_SEGMENTATION
int lte_segmentation_NB_IoT(unsigned char *input_buffer,
unsigned char **output_buffers,
unsigned int B,
unsigned int *C,
unsigned int *Cplus,
unsigned int *Cminus,
unsigned int *Kplus,
unsigned int *Kminus,
unsigned int *F)
{
unsigned int L,Bprime,Bprime_by_C,r,Kr,k,s,crc;
if (B<=6144) {
L=0;
*C=1;
Bprime=B;
} else {
L=24;
*C = B/(6144-L);
if ((6144-L)*(*C) < B)
*C=*C+1;
Bprime = B+((*C)*L);
}
if ((*C)>MAX_NUM_DLSCH_SEGMENTS_NB_IoT) {
LOG_E(PHY,"lte_segmentation.c: too many segments %d, B %d, L %d, Bprime %d\n",*C,B,L,Bprime);
return(-1);
}
// Find K+
Bprime_by_C = Bprime/(*C);
if (Bprime_by_C <= 40) {
*Kplus = 40;
*Kminus = 0;
} else if (Bprime_by_C<=512) { // increase by 1 byte til here
*Kplus = (Bprime_by_C>>3)<<3;
*Kminus = Bprime_by_C-8;
} else if (Bprime_by_C <=1024) { // increase by 2 bytes til here
*Kplus = (Bprime_by_C>>4)<<4;
if (*Kplus < Bprime_by_C)
*Kplus = *Kplus + 16;
*Kminus = (*Kplus - 16);
} else if (Bprime_by_C <= 2048) { // increase by 4 bytes til here
*Kplus = (Bprime_by_C>>5)<<5;
if (*Kplus < Bprime_by_C)
*Kplus = *Kplus + 32;
*Kminus = (*Kplus - 32);
} else if (Bprime_by_C <=6144 ) { // increase by 8 bytes til here
*Kplus = (Bprime_by_C>>6)<<6;
if (*Kplus < Bprime_by_C)
*Kplus = *Kplus + 64;
*Kminus = (*Kplus - 64);
} else {
msg("lte_segmentation.c: Illegal codeword size !!!\n");
return(-1);
}
if (*C == 1) {
*Cplus = *C;
*Kminus = 0;
*Cminus = 0;
} else {
// printf("More than one segment (%d), exiting \n",*C);
// exit(-1);
*Cminus = ((*C)*(*Kplus) - (Bprime))/((*Kplus) - (*Kminus));
*Cplus = (*C) - (*Cminus);
}
*F = ((*Cplus)*(*Kplus) + (*Cminus)*(*Kminus) - (Bprime));
if ((input_buffer) && (output_buffers)) {
for (k=0; k<*F>>3; k++) {
output_buffers[0][k] = 0;
}
s=0;
for (r=0; r<*C; r++) {
if (r<*Cminus)
Kr = *Kminus;
else
Kr = *Kplus;
while (k<((Kr - L)>>3)) {
output_buffers[r][k] = input_buffer[s];
// printf("encoding segment %d : byte %d (%d) => %d\n",r,k,Kr>>3,input_buffer[s]);
k++;
s++;
}
if (*C > 1) { // add CRC
crc = crc24b_NB_IoT(output_buffers[r],Kr-24)>>8;
output_buffers[r][(Kr-24)>>3] = ((uint8_t*)&crc)[2];
output_buffers[r][1+((Kr-24)>>3)] = ((uint8_t*)&crc)[1];
output_buffers[r][2+((Kr-24)>>3)] = ((uint8_t*)&crc)[0];
}
k=0;
}
}
return(0);
}

View File

@@ -0,0 +1,776 @@
#include "../impl_defs_lte_NB_IoT.h"
#include "../defs_L1_NB_IoT.h"
#include "phy_init_NB_IoT.h"
#include "common/config/config_paramdesc.h"
#include "openair2/ENB_APP/NB_IoT_paramdef.h"
#include "PHY/phy_vars.h"
#include "openair1/PHY/LTE_REFSIG/lte_refsig.h"
#include "openair1/PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "openair1/PHY/CODING/defs_NB_IoT.h"
#include "openair1/PHY/vars_NB_IoT.h"
// #include "openair2/PHY_INTERFACE/nfapi_interface.h"
#include "openair2/COMMON/platform_types.h"
PHY_VARS_eNB_NB_IoT* init_lte_eNB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t Nid_cell,
eNB_func_NB_IoT_t node_function,
uint8_t abstraction_flag)
{
//int i;
PHY_VARS_eNB_NB_IoT* PHY_vars_eNB = malloc(sizeof(PHY_VARS_eNB_NB_IoT));
memset(PHY_vars_eNB,0,sizeof(PHY_VARS_eNB_NB_IoT));
PHY_vars_eNB->Mod_id=eNB_id;
PHY_vars_eNB->cooperation_flag=0;//cooperation_flag;
memcpy(&(PHY_vars_eNB->frame_parms), frame_parms, sizeof(NB_IoT_DL_FRAME_PARMS));
//PHY_vars_eNB->frame_parms.Nid_cell = ((Nid_cell/3)*3)+((eNB_id+Nid_cell)%3);
//PHY_vars_eNB->frame_parms.nushift = PHY_vars_eNB->frame_parms.Nid_cell%6;
PHY_vars_eNB->frame_parms.Nid_cell = Nid_cell; ///////((Nid_cell/3)*3)+((eNB_id+Nid_cell)%3);
PHY_vars_eNB->frame_parms.nushift = PHY_vars_eNB->frame_parms.Nid_cell%6;
phy_init_lte_eNB_NB_IoT(PHY_vars_eNB,0,abstraction_flag);
// for NB-IoT testing
// PHY_vars_eNB->ndlsch_SIB.content_sib1.si_rnti = 0xffff;
// PHY_vars_eNB->ndlsch_SIB.content_sib23.si_rnti = 0xffff;
////////////////////////////
/*LOG_I(PHY,"init eNB: Node Function %d\n",node_function);
LOG_I(PHY,"init eNB: Nid_cell %d\n", frame_parms->Nid_cell);
LOG_I(PHY,"init eNB: frame_type %d,tdd_config %d\n", frame_parms->frame_type,frame_parms->tdd_config);
LOG_I(PHY,"init eNB: number of ue max %d number of enb max %d number of harq pid max %d\n",
NUMBER_OF_UE_MAX, NUMBER_OF_eNB_MAX, NUMBER_OF_HARQ_PID_MAX);
LOG_I(PHY,"init eNB: N_RB_DL %d\n", frame_parms->N_RB_DL);
LOG_I(PHY,"init eNB: prach_config_index %d\n", frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex);
*/
/*
if (node_function >= NGFI_RRU_IF5)
// For RRU, don't allocate DLSCH/ULSCH Transport channel buffers
return (PHY_vars_eNB);
*/
/*
for (i=0; i<NUMBER_OF_UE_MAX_NB_IoT; i++) {
LOG_I(PHY,"Allocating Transport Channel Buffers for DLSCH, UE %d\n",i);
for (j=0; j<2; j++) {
PHY_vars_eNB->dlsch[i][j] = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL,abstraction_flag,frame_parms);
if (!PHY_vars_eNB->dlsch[i][j]) {
LOG_E(PHY,"Can't get eNB dlsch structures for UE %d \n", i);
exit(-1);
} else {
LOG_D(PHY,"dlsch[%d][%d] => %p\n",i,j,PHY_vars_eNB->dlsch[i][j]);
PHY_vars_eNB->dlsch[i][j]->rnti=0;
}
}
LOG_I(PHY,"Allocating Transport Channel Buffer for ULSCH, UE %d\n", i);
PHY_vars_eNB->ulsch[1+i] = new_eNB_ulsch(MAX_TURBO_ITERATIONS,frame_parms->N_RB_UL, abstraction_flag);
if (!PHY_vars_eNB->ulsch[1+i]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
*/
// this is the transmission mode for the signalling channels
// this will be overwritten with the real transmission mode by the RRC once the UE is connected
PHY_vars_eNB->transmission_mode[0] = 1 ;
/*#ifdef LOCALIZATION
PHY_vars_eNB->ulsch[1+i]->aggregation_period_ms = 5000; // 5000 milliseconds // could be given as an argument (TBD))
struct timeval ts;
gettimeofday(&ts, NULL);
PHY_vars_eNB->ulsch[1+i]->reference_timestamp_ms = ts.tv_sec * 1000 + ts.tv_usec / 1000;
int j;
for (j=0; j<10; j++) {
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rss_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_rssi_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_subcarrier_rss_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_advance_list[j]);
initialize(&PHY_vars_eNB->ulsch[1+i]->loc_timing_update_list[j]);
}
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rss_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_rssi_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_subcarrier_rss_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_timing_advance_list);
initialize(&PHY_vars_eNB->ulsch[1+i]->tot_loc_timing_update_list);
#endif*/
// }
/*
// ULSCH for RA
PHY_vars_eNB->ulsch[0] = new_eNB_ulsch(MAX_TURBO_ITERATIONS, frame_parms->N_RB_UL, abstraction_flag);
if (!PHY_vars_eNB->ulsch[0]) {
LOG_E(PHY,"Can't get eNB ulsch structures\n");
exit(-1);
}
PHY_vars_eNB->dlsch_SI = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
LOG_D(PHY,"eNB %d : SI %p\n",eNB_id,PHY_vars_eNB->dlsch_SI);
PHY_vars_eNB->dlsch_ra = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, abstraction_flag, frame_parms);
LOG_D(PHY,"eNB %d : RA %p\n",eNB_id,PHY_vars_eNB->dlsch_ra);
PHY_vars_eNB->dlsch_MCH = new_eNB_dlsch(1,8,NSOFT,frame_parms->N_RB_DL, 0, frame_parms);
LOG_D(PHY,"eNB %d : MCH %p\n",eNB_id,PHY_vars_eNB->dlsch_MCH);
*/
PHY_vars_eNB->rx_total_gain_dB=130;
/* for(i=0; i<NUMBER_OF_UE_MAX; i++)
PHY_vars_eNB->mu_mimo_mode[i].dl_pow_off = 2;
PHY_vars_eNB->check_for_total_transmissions = 0;
PHY_vars_eNB->check_for_MUMIMO_transmissions = 0;
PHY_vars_eNB->FULL_MUMIMO_transmissions = 0;
PHY_vars_eNB->check_for_SUMIMO_transmissions = 0;
PHY_vars_eNB->frame_parms.pucch_config_common.deltaPUCCH_Shift = 1;
*/
return (PHY_vars_eNB);
}
int phy_init_lte_eNB_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
unsigned char is_secondary_eNB,
unsigned char abstraction_flag)
{
// shortcuts
NB_IoT_DL_FRAME_PARMS* const fp = &eNB->frame_parms;
NB_IoT_eNB_COMMON* const common_vars = &eNB->common_vars;
NB_IoT_eNB_PUSCH** const pusch_vars = eNB->pusch_vars;
NB_IoT_eNB_SRS* const srs_vars = eNB->srs_vars;
NB_IoT_eNB_PRACH* const prach_vars = &eNB->prach_vars;
int i, j, eNB_id, UE_id;
int re;
eNB->total_dlsch_bitrate = 0;
eNB->total_transmitted_bits = 0;
eNB->total_system_throughput = 0;
eNB->check_for_MUMIMO_transmissions=0;
if (eNB->node_function != NGFI_RRU_IF4p5_NB_IoT) {
lte_gold_NB_IoT(fp,eNB->lte_gold_table_NB_IoT,fp->Nid_cell); //Ann
// generate_pcfich_reg_mapping(fp);
// generate_phich_reg_mapping(fp);
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX_NB_IoT; UE_id++) {
eNB->first_run_timing_advance[UE_id] =
1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
// clear whole structure
bzero( &eNB->UE_stats[UE_id], sizeof(NB_IoT_eNB_UE_stats) );
eNB->physicalConfigDedicated[UE_id] = NULL;
}
eNB->first_run_I0_measurements = 1; ///This flag used to be static. With multiple eNBs this does no longer work, hence we put it in the structure. However it has to be initialized with 1, which is performed here.
}
// for (eNB_id=0; eNB_id<3; eNB_id++) {
{
eNB_id=0;
if (abstraction_flag==0) {
// TX vars
if (eNB->node_function != NGFI_RCC_IF4p5_NB_IoT)
common_vars->txdata[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_tx*sizeof(int32_t*));
common_vars->txdataF[eNB_id] = (int32_t **)malloc16(NB_ANTENNA_PORTS_ENB*sizeof(int32_t*));
common_vars->txdataF_BF[eNB_id] = (int32_t **)malloc16(fp->nb_antennas_tx*sizeof(int32_t*));
if (eNB->node_function != NGFI_RRU_IF5_NB_IoT) {
for (i=0; i<NB_ANTENNA_PORTS_ENB; i++) {
if (i<fp->nb_antenna_ports_eNB || i==5) {
common_vars->txdataF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t) );
#ifdef DEBUG_PHY
printf("[openair][LTE_PHY][INIT] common_vars->txdataF[%d][%d] = %p (%lu bytes)\n",
eNB_id,i,common_vars->txdataF[eNB_id][i],
fp->ofdm_symbol_size*fp->symbols_per_tti*10*sizeof(int32_t));
#endif
}
}
}
for (i=0; i<fp->nb_antennas_tx; i++) {
common_vars->txdataF_BF[eNB_id][i] = (int32_t*)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t) );
if (eNB->node_function != NGFI_RCC_IF4p5_NB_IoT)
// Allocate 10 subframes of I/Q TX signal data (time) if not
common_vars->txdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
#ifdef DEBUG_PHY
printf("[openair][LTE_PHY][INIT] common_vars->txdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->txdata[eNB_id][i],
fp->samples_per_tti*10*sizeof(int32_t));
#endif
}
for (i=0; i<NB_ANTENNA_PORTS_ENB; i++) {
if (i<fp->nb_antenna_ports_eNB || i==5) {
common_vars->beam_weights[eNB_id][i] = (int32_t **)malloc16_clear(fp->nb_antennas_tx*sizeof(int32_t*));
for (j=0; j<fp->nb_antennas_tx; j++) {
common_vars->beam_weights[eNB_id][i][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t));
// antenna ports 0-3 are mapped on antennas 0-3
// antenna port 4 is mapped on antenna 0
// antenna ports 5-14 are mapped on all antennas
if (((i<4) && (i==j)) || ((i==4) && (j==0))) {
for (re=0; re<fp->ofdm_symbol_size; re++)
common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff;
}
else if (i>4) {
for (re=0; re<fp->ofdm_symbol_size; re++)
common_vars->beam_weights[eNB_id][i][j][re] = 0x00007fff/fp->nb_antennas_tx;
}
#ifdef DEBUG_PHY
msg("[openair][LTE_PHY][INIT] lte_common_vars->beam_weights[%d][%d][%d] = %p (%zu bytes)\n",
eNB_id,i,j,common_vars->beam_weights[eNB_id][i][j],
fp->ofdm_symbol_size*sizeof(int32_t));
#endif
}
}
}
// RX vars
if (eNB->node_function != NGFI_RCC_IF4p5_NB_IoT) {
common_vars->rxdata[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
common_vars->rxdata_7_5kHz[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
}
common_vars->rxdataF[eNB_id] = (int32_t**)malloc16(fp->nb_antennas_rx*sizeof(int32_t*) );
for (i=0; i<fp->nb_antennas_rx; i++) {
if (eNB->node_function != NGFI_RCC_IF4p5_NB_IoT) {
// allocate 2 subframes of I/Q signal data (time) if not an RCC (no time-domain signals)
common_vars->rxdata[eNB_id][i] = (int32_t*)malloc16_clear( fp->samples_per_tti*10*sizeof(int32_t) );
if (eNB->node_function != NGFI_RRU_IF5_NB_IoT)
// allocate 2 subframes of I/Q signal data (time, 7.5 kHz offset)
common_vars->rxdata_7_5kHz[eNB_id][i] = (int32_t*)malloc16_clear( 2*fp->samples_per_tti*2*sizeof(int32_t) );
}
if (eNB->node_function != NGFI_RRU_IF5_NB_IoT)
// allocate 2 subframes of I/Q signal data (frequency)
common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(2*fp->ofdm_symbol_size*fp->symbols_per_tti) );
#ifdef DEBUG_PHY
printf("[openair][LTE_PHY][INIT] common_vars->rxdata[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata[eNB_id][i],fp->samples_per_tti*10*sizeof(int32_t));
if (eNB->node_function != NGFI_RRU_IF5_NB_IoT)
printf("[openair][LTE_PHY][INIT] common_vars->rxdata_7_5kHz[%d][%d] = %p (%lu bytes)\n",eNB_id,i,common_vars->rxdata_7_5kHz[eNB_id][i],fp->samples_per_tti*2*sizeof(int32_t));
#endif
common_vars->rxdataF[eNB_id][i] = (int32_t*)malloc16_clear(sizeof(int32_t)*(fp->ofdm_symbol_size*fp->symbols_per_tti) );
}
if ((eNB->node_function != NGFI_RRU_IF4p5_NB_IoT)&&(eNB->node_function != NGFI_RRU_IF5_NB_IoT)) {
// Channel estimates for SRS
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
srs_vars[UE_id].srs_ch_estimates[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
srs_vars[UE_id].srs_ch_estimates_time[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
for (i=0; i<fp->nb_antennas_rx; i++) {
srs_vars[UE_id].srs_ch_estimates[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size );
srs_vars[UE_id].srs_ch_estimates_time[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->ofdm_symbol_size*2 );
}
} //UE_id
common_vars->sync_corr[eNB_id] = (uint32_t*)malloc16_clear( LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*sizeof(uint32_t)*fp->samples_per_tti );
}
} // abstraction_flag = 0
else { //UPLINK abstraction = 1
eNB->sinr_dB = (double*) malloc16_clear( fp->N_RB_DL*12*sizeof(double) );
}
} //eNB_id
if (abstraction_flag==0) {
if ((eNB->node_function != NGFI_RRU_IF4p5_NB_IoT)&&(eNB->node_function != NGFI_RRU_IF5_NB_IoT)) {
generate_ul_ref_sigs_rx();
// SRS
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
srs_vars[UE_id].srs = (int32_t*)malloc16_clear(2*fp->ofdm_symbol_size*sizeof(int32_t));
}
}
}
// ULSCH VARS, skip if NFGI_RRU_IF4
if ((eNB->node_function!=NGFI_RRU_IF4p5_NB_IoT)&&(eNB->node_function != NGFI_RRU_IF5_NB_IoT))
prach_vars->prachF = (int16_t*)malloc16_clear( 1024*2*sizeof(int16_t) );
/* number of elements of an array X is computed as sizeof(X) / sizeof(X[0]) */
AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->rxsigF) / sizeof(prach_vars->rxsigF[0]),
"nb_antennas_rx too large");
for (i=0; i<fp->nb_antennas_rx; i++) {
prach_vars->rxsigF[i] = (int16_t*)malloc16_clear( fp->ofdm_symbol_size*12*2*sizeof(int16_t) );
#ifdef DEBUG_PHY
printf("[openair][LTE_PHY][INIT] prach_vars->rxsigF[%d] = %p\n",i,prach_vars->rxsigF[i]);
#endif
}
if ((eNB->node_function != NGFI_RRU_IF4p5_NB_IoT)&&(eNB->node_function != NGFI_RRU_IF5_NB_IoT)) {
AssertFatal(fp->nb_antennas_rx <= sizeof(prach_vars->prach_ifft) / sizeof(prach_vars->prach_ifft[0]),
"nb_antennas_rx too large");
for (i=0; i<fp->nb_antennas_rx; i++) {
prach_vars->prach_ifft[i] = (int16_t*)malloc16_clear(1024*2*sizeof(int16_t));
#ifdef DEBUG_PHY
printf("[openair][LTE_PHY][INIT] prach_vars->prach_ifft[%d] = %p\n",i,prach_vars->prach_ifft[i]);
#endif
}
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
//FIXME
pusch_vars[UE_id] = (NB_IoT_eNB_PUSCH*)malloc16_clear( NUMBER_OF_UE_MAX*sizeof(NB_IoT_eNB_PUSCH) );
if (abstraction_flag==0) {
for (eNB_id=0; eNB_id<3; eNB_id++) {
pusch_vars[UE_id]->rxdataF_ext[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
pusch_vars[UE_id]->rxdataF_ext2[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
pusch_vars[UE_id]->drs_ch_estimates[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
pusch_vars[UE_id]->rxdataF_comp[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
pusch_vars[UE_id]->ul_ch_mag[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
pusch_vars[UE_id]->ul_ch_magb[eNB_id] = (int32_t**)malloc16( fp->nb_antennas_rx*sizeof(int32_t*) );
for (i=0; i<fp->nb_antennas_rx; i++) {
// RK 2 times because of output format of FFT!
// FIXME We should get rid of this
pusch_vars[UE_id]->rxdataF_ext[eNB_id][i] = (int32_t*)malloc16_clear( 2*sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->rxdataF_ext2[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->drs_ch_estimates[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->drs_ch_estimates_time[eNB_id][i] = (int32_t*)malloc16_clear( 2*2*sizeof(int32_t)*fp->ofdm_symbol_size );
pusch_vars[UE_id]->rxdataF_comp[eNB_id][i] = (int32_t*)malloc16_clear( sizeof(int32_t)*fp->N_RB_UL*12*fp->symbols_per_tti );
pusch_vars[UE_id]->ul_ch_mag[eNB_id][i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
pusch_vars[UE_id]->ul_ch_magb[eNB_id][i] = (int32_t*)malloc16_clear( fp->symbols_per_tti*sizeof(int32_t)*fp->N_RB_UL*12 );
}
} //eNB_id
pusch_vars[UE_id]->llr = (int16_t*)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
} // abstraction_flag
} //UE_id
if (abstraction_flag==0) {
if (is_secondary_eNB) {
for (eNB_id=0; eNB_id<3; eNB_id++) {
eNB->dl_precoder_SeNB[eNB_id] = (int **)malloc16(4*sizeof(int*));
if (eNB->dl_precoder_SeNB[eNB_id]) {
#ifdef DEBUG_PHY
printf("[openair][SECSYS_PHY][INIT] eNB->dl_precoder_SeNB[%d] allocated at %p\n",eNB_id,
eNB->dl_precoder_SeNB[eNB_id]);
#endif
} else {
printf("[openair][SECSYS_PHY][INIT] eNB->dl_precoder_SeNB[%d] not allocated\n",eNB_id);
return(-1);
}
for (j=0; j<fp->nb_antennas_tx; j++) {
eNB->dl_precoder_SeNB[eNB_id][j] = (int *)malloc16(2*sizeof(int)*(fp->ofdm_symbol_size)); // repeated format (hence the '2*')
if (eNB->dl_precoder_SeNB[eNB_id][j]) {
#ifdef DEBUG_PHY
printf("[openair][LTE_PHY][INIT] eNB->dl_precoder_SeNB[%d][%d] allocated at %p\n",eNB_id,j,
eNB->dl_precoder_SeNB[eNB_id][j]);
#endif
memset(eNB->dl_precoder_SeNB[eNB_id][j],0,2*sizeof(int)*(fp->ofdm_symbol_size));
} else {
printf("[openair][LTE_PHY][INIT] eNB->dl_precoder_SeNB[%d][%d] not allocated\n",eNB_id,j);
return(-1);
}
} //for(j=...nb_antennas_tx
} //for(eNB_id...
}
}
/*
for (UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++)
eNB->UE_stats_ptr[UE_id] = &eNB->UE_stats[UE_id];
//defaul value until overwritten by RRCConnectionReconfiguration
if (fp->nb_antenna_ports_eNB==2)
eNB->pdsch_config_dedicated->p_a = dBm3;
else
eNB->pdsch_config_dedicated->p_a = dB0;
init_prach_tables(839);
*/
} // node_function != NGFI_RRU_IF4p5
return (0);
}
void phy_init_lte_top_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms)
{
crcTableInit_NB_IoT();
//ccodedot11_init();
//ccodedot11_init_inv();
ccodelte_init_NB_IoT();
ccodelte_init2_NB_IoT();
//ccodelte_init_inv();
//treillis_table_init();
//phy_generate_viterbi_tables();
//phy_generate_viterbi_tables_lte();
//init_td8();
// init_td16();
#ifdef __AVX2__
// init_td16avx2();
#endif
//lte_sync_time_init_NB_IoT(frame_parms);
//generate_ul_ref_sigs();
//generate_ul_ref_sigs_rx();
generate_ul_ref_sigs_rx_NB_IoT();
// generate_64qam_table();
//generate_16qam_table();
// generate_RIV_tables();
init_unscrambling_lut_NB_IoT();
// init_scrambling_lut();
//set_taus_seed(1328);
}
//for NB-IoT layer1 to get informstion from layer2
int
l1_north_init_NB_IoT()
{
int j;
paramlist_def_t NbIoT_L1_ParamList = {NBIOT_L1LIST_CONFIG_STRING,NULL,0};
if (RC.L1_NB_IoT != NULL)
{
AssertFatal(RC.L1_NB_IoT!=NULL,"RC.L1_NB_IoT is null\n");
LOG_I(PHY,"RC.L1_NB_IoT = %p\n",RC.L1_NB_IoT);
for (j=0; j<NbIoT_L1_ParamList.numelt; j++) {
AssertFatal(RC.L1_NB_IoT[j]!=NULL,"RC.eNB_NB_IoT[%d] is null\n",j);
LOG_I(PHY,"RC.L1_NB_IoT = %p\n",RC.L1_NB_IoT);
if ((RC.L1_NB_IoT[j]->if_inst_NB_IoT = IF_Module_init_NB_IoT(j))<0) return(-1);
LOG_I(PHY,"RC.L1_NB_IoT = %p\n",RC.L1_NB_IoT);
RC.L1_NB_IoT[j]->if_inst_NB_IoT->PHY_config_req = PHY_config_req_NB_IoT;
RC.L1_NB_IoT[j]->if_inst_NB_IoT->schedule_response = schedule_response_NB_IoT;
}
}
else
{
LOG_I(PHY,"%s() Not installing PHY callbacks - RC.nb_nb_iot_L1_inst:%d RC.L1_NB_IoT:%p\n", __FUNCTION__, RC.nb_nb_iot_L1_inst, RC.L1_NB_IoT);
}
return(0);
}
// void phy_config_mib_eNB_NB_IoT(int Mod_id,
// int eutra_band,
// int Nid_cell,
// int Ncp,
// int Ncp_UL,
// int p_eNB,
// uint16_t EARFCN,
// uint16_t prb_index, // NB_IoT_RB_ID,
// uint16_t operating_mode,
// uint16_t control_region_size,
// uint16_t eutra_NumCRS_ports)
// {
// AssertFatal(PHY_vars_eNB_NB_IoT_g != NULL, "PHY_vars_eNB_NB_IoT_g instance pointer doesn't exist\n");
// AssertFatal(PHY_vars_eNB_NB_IoT_g[Mod_id] != NULL, "PHY_vars_eNB_NB_IoT_g instance %d doesn't exist\n",Mod_id);
// AssertFatal(PHY_vars_eNB_NB_IoT_g[Mod_id][0] != NULL, "PHY_vars_eNB_NB_IoT_g instance %d, CCid %d doesn't exist\n",Mod_id,0);
// NB_IoT_DL_FRAME_PARMS *fp = &PHY_vars_eNB_NB_IoT_g[Mod_id][0]->frame_parms_NB_IoT;
// fp = (NB_IoT_DL_FRAME_PARMS*) malloc (sizeof(NB_IoT_DL_FRAME_PARMS));
// LOG_I(PHY,"Configuring MIB-NB for instance %d, CCid %d : (band %d,Nid_cell %d,p %d,EARFCN %u)\n",Mod_id, 0, eutra_band, Nid_cell, p_eNB,EARFCN);
// // fp->N_RB_DL
// // fp->N_RB_UL also this two values need to be known when we are dealing with in-band and guard-band operating mode
// fp->Nid_cell = Nid_cell;
// fp->nushift = Nid_cell%6;
// fp->eutra_band = eutra_band;
// fp->Ncp = Ncp;
// fp->Ncp_UL = Ncp_UL;
// fp->nb_antenna_ports_eNB = p_eNB; //tx antenna port
// fp->dl_CarrierFreq = from_earfcn_NB_IoT(eutra_band,EARFCN,0);
// fp->ul_CarrierFreq = fp->dl_CarrierFreq - get_uldl_offset_NB_IoT(eutra_band);
// fp->operating_mode = operating_mode; //see how are defined by FAPI structure
// fp->NB_IoT_RB_ID = prb_index; //XXX to be better understand how should be managed
// //fp->nb_rx_antenna_ports_eNB
// fp->control_region_size = control_region_size; //(assume that this value is negative if not used)
// fp->eutra_NumCRS_ports = eutra_NumCRS_ports; //(valid only for in-band operating mode with different PCI)
// LOG_I(PHY,"Configure-MIB complete\n");
// //TODO (new Raymond implementation) in the classic implementation seems to be used only by oaisim
// //init_frame_parms(fp,1);
// //init_lte_top(fp);
// }
// #if 0 //Ann //wait for nfapi integration
// void phy_config_sib2_eNB_NB_IoT(uint8_t Mod_id,
// nfapi_config_NB_IoT_t *config,
// nfapi_rf_config_t *rf_config,
// nfapi_uplink_reference_signal_config_t *ul_nrs_config,
// extra_phyConfig_t *extra_phy_parms)
// {
// NB_IoT_DL_FRAME_PARMS *fp = &PHY_vars_eNB_NB_IoT_g[Mod_id][0]->frame_parms_NB_IoT;
// // PHY_VARS_eNB *eNB = &PHY_vars_eNB_g[0][0];
// LOG_I(PHY,"[eNB%d] CCid %d: Applying config_NB_IoT from sib2_NB\n",Mod_id,0);
// fp = (NB_IoT_DL_FRAME_PARMS*) malloc (sizeof(NB_IoT_DL_FRAME_PARMS));
// /*NPRACH_ConfigSIB_NB_r13----------------------------------------------------------*/
// //MP: FAPI style approach: instead of a list they consider the 3 possible configuration separately
// if(config->nprach_config_0_enabled.value == 1){
// LOG_I(PHY, "NPRACH Config #0 enabled\n");
// fp->nprach_config_common.nprach_CP_Length = config->nprach_config_0_cp_length.value; //NPRACH_ConfigSIB_NB_r13__nprach_CP_Length_r13_us66dot7
// LOG_D(PHY," config#0: nprach_CP_Length = %d\n",fp->nprach_config_common.nprach_CP_Length);
// //FIXME: MP: memory for the list should be allocated? initialization??
// fp->nprach_config_common.nprach_ParametersList.list[0].nprach_Periodicity = config->nprach_config_0_sf_periodicity.value;
// LOG_D(PHY,"config#0: nprach_Periodicity = %d\n", fp->nprach_config_common.nprach_ParametersList.list[0].nprach_Periodicity);
// fp->nprach_config_common.nprach_ParametersList.list[0].nprach_StartTime = config->nprach_config_0_start_time.value;
// LOG_D(PHY,"config#0: nprach_StartTime = %d\n",fp->nprach_config_common.nprach_ParametersList.list[0].nprach_StartTime);
// fp->nprach_config_common.nprach_ParametersList.list[0].nprach_SubcarrierOffset = config->nprach_config_0_subcarrier_offset.value;
// LOG_D(PHY,"config#0: nprach_SubcarrierOffset= %d\n", fp->nprach_config_common.nprach_ParametersList.list[0].nprach_SubcarrierOffset);
// fp->nprach_config_common.nprach_ParametersList.list[0].nprach_NumSubcarriers = config->nprach_config_0_number_of_subcarriers.value;
// LOG_D(PHY,"config#0: nprach_NumSubcarriers= %d\n",fp->nprach_config_common.nprach_ParametersList.list[0].nprach_NumSubcarriers);
// fp->nprach_config_common.nprach_ParametersList.list[0].numRepetitionsPerPreambleAttempt = config->nprach_config_0_number_of_repetitions_per_attempt.value;
// LOG_D(PHY,"config#0: numRepetitionsPerPreambleAttempt= %d\n",fp->nprach_config_common.nprach_ParametersList.list[0].numRepetitionsPerPreambleAttempt);
// //////////////////////////////////////////////////////////////////////////
// /* eNB->nprach_config_common.nprach_CP_Length = config->nprach_config_0_cp_length.value;
// eNB->nprach_config_common.nprach_ParametersList.list[0].nprach_Periodicity = config->nprach_config_0_sf_periodicity.value;
// eNB->nprach_config_common.nprach_ParametersList.list[0].nprach_StartTime = config->nprach_config_0_start_time.value;
// eNB->nprach_config_common.nprach_ParametersList.list[0].nprach_SubcarrierOffset = config->nprach_config_0_subcarrier_offset.value;
// eNB->nprach_config_common.nprach_ParametersList.list[0].nprach_NumSubcarriers = config->nprach_config_0_number_of_subcarriers.value;
// eNB->nprach_config_common.nprach_ParametersList.list[0].numRepetitionsPerPreambleAttempt = config->nprach_config_0_number_of_repetitions_per_attempt.value;
// */
// //////////////////////////////////////////////////////////////////////////
// //missed configuration in FAPI config_request (TS 36.331 pag 610) (may not needed)
// /*fp->nprach_config_common.nprach_ParametersList.list.array[0]->nprach_SubcarrierMSG3_RangeStart = extra_phy_parms->nprach_config_0_subcarrier_MSG3_range_start;
// fp->nprach_config_common.nprach_ParametersList.list.array[0]->npdcch_StartSF_CSS_RA = extra_phy_parms->nprach_config_0_npdcch_startSF_CSS_RA;
// fp->nprach_config_common.nprach_ParametersList.list.array[0]->npdcch_NumRepetitions_RA = extra_phy_parms->nprach_config_0_npdcch_num_repetitions_RA;
// fp->nprach_config_common.nprach_ParametersList.list.array[0]->npdcch_Offset_RA = extra_phy_parms->nprach_config_0_npdcch_offset_RA;
// fp->nprach_config_common.nprach_ParametersList.list.array[0]->maxNumPreambleAttemptCE = extra_phy_parms->nprach_config_0_max_num_preamble_attempt_CE;
// */
// //fp->nprach_config_common.rsrp_ThresholdsPrachInfoList.list /*OPTIONAL*/
// }
// if(config->nprach_config_1_enabled.value == 1){
// LOG_I(PHY, "NPRACH Config #1 enabled\n");
// fp->nprach_config_common.nprach_CP_Length = config->nprach_config_1_cp_length.value; //NPRACH_ConfigSIB_NB_r13__nprach_CP_Length_r13_us66dot7
// LOG_D(PHY," config#1: nprach_CP_Length = %d\n",fp->nprach_config_common.nprach_CP_Length);
// //FIXME: MP: memory for the list should be allocated? initialization??
// fp->nprach_config_common.nprach_ParametersList.list[1].nprach_Periodicity = config->nprach_config_1_sf_periodicity.value;
// LOG_D(PHY,"config#1: nprach_Periodicity = %d\n", fp->nprach_config_common.nprach_ParametersList.list[1].nprach_Periodicity);
// fp->nprach_config_common.nprach_ParametersList.list[1].nprach_StartTime = config->nprach_config_1_start_time.value;
// LOG_D(PHY,"config#1: nprach_StartTime = %d\n",fp->nprach_config_common.nprach_ParametersList.list[1].nprach_StartTime);
// fp->nprach_config_common.nprach_ParametersList.list[1].nprach_SubcarrierOffset = config->nprach_config_1_subcarrier_offset.value;
// LOG_D(PHY,"config#1: nprach_SubcarrierOffset= %d\n", fp->nprach_config_common.nprach_ParametersList.list[1].nprach_SubcarrierOffset);
// fp->nprach_config_common.nprach_ParametersList.list[1].nprach_NumSubcarriers = config->nprach_config_1_number_of_subcarriers.value;
// LOG_D(PHY,"config#1: nprach_NumSubcarriers= %d\n",fp->nprach_config_common.nprach_ParametersList.list[1].nprach_NumSubcarriers);
// fp->nprach_config_common.nprach_ParametersList.list[1].numRepetitionsPerPreambleAttempt = config->nprach_config_1_number_of_repetitions_per_attempt.value;
// LOG_D(PHY,"config#1: numRepetitionsPerPreambleAttempt= %d\n",fp->nprach_config_common.nprach_ParametersList.list[1].numRepetitionsPerPreambleAttempt);
// ///////////////////////////////////////////////////////////////////////////////////////
// /* eNB->nprach_config_common.nprach_CP_Length = config->nprach_config_1_cp_length.value;
// eNB->nprach_config_common.nprach_ParametersList.list[1].nprach_Periodicity = config->nprach_config_1_sf_periodicity.value;
// eNB->nprach_config_common.nprach_ParametersList.list[1].nprach_StartTime = config->nprach_config_1_start_time.value;
// eNB->nprach_config_common.nprach_ParametersList.list[1].nprach_SubcarrierOffset = config->nprach_config_1_subcarrier_offset.value;
// eNB->nprach_config_common.nprach_ParametersList.list[1].nprach_NumSubcarriers = config->nprach_config_1_number_of_subcarriers.value;
// eNB->nprach_config_common.nprach_ParametersList.list[1].numRepetitionsPerPreambleAttempt = config->nprach_config_1_number_of_repetitions_per_attempt.value;
// */
// //////////////////////////////////////////////////////////////////////////////////////
// //missed configuration in FAPI config_request (TS 36.331 pag 610) (may not needed)
// /*fp->nprach_config_common.nprach_ParametersList.list.array[1]->nprach_SubcarrierMSG3_RangeStart = extra_phy_parms->nprach_config_1_subcarrier_MSG3_range_start;
// fp->nprach_config_common.nprach_ParametersList.list.array[1]->npdcch_StartSF_CSS_RA = extra_phy_parms->nprach_config_1_npdcch_startSF_CSS_RA;
// fp->nprach_config_common.nprach_ParametersList.list.array[1]->npdcch_NumRepetitions_RA = extra_phy_parms->nprach_config_1_npdcch_num_repetitions_RA;
// fp->nprach_config_common.nprach_ParametersList.list.array[1]->npdcch_Offset_RA = extra_phy_parms->nprach_config_1_npdcch_offset_RA;
// fp->nprach_config_common.nprach_ParametersList.list.array[1]->maxNumPreambleAttemptCE = extra_phy_parms->nprach_config_1_max_num_preamble_attempt_CE;
// */
// //fp->nprach_config_common.rsrp_ThresholdsPrachInfoList.list /*OPTIONAL*/
// }
// if(config->nprach_config_2_enabled.value == 1){
// LOG_I(PHY, "NPRACH Config #2 enabled\n");
// fp->nprach_config_common.nprach_CP_Length = config->nprach_config_2_cp_length.value; //NPRACH_ConfigSIB_NB_r13__nprach_CP_Length_r13_us66dot7
// LOG_D(PHY," config#2: nprach_CP_Length = %d\n",fp->nprach_config_common.nprach_CP_Length);
// //FIXME: MP: memory for the list should be allocated? initialization?? where??
// fp->nprach_config_common.nprach_ParametersList.list[2].nprach_Periodicity = config->nprach_config_2_sf_periodicity.value;
// LOG_D(PHY,"config#2: nprach_Periodicity = %d\n", fp->nprach_config_common.nprach_ParametersList.list[2].nprach_Periodicity);
// fp->nprach_config_common.nprach_ParametersList.list[2].nprach_StartTime = config->nprach_config_2_start_time.value;
// LOG_D(PHY,"config#2: nprach_StartTime = %d\n",fp->nprach_config_common.nprach_ParametersList.list[2].nprach_StartTime);
// fp->nprach_config_common.nprach_ParametersList.list[2].nprach_SubcarrierOffset = config->nprach_config_2_subcarrier_offset.value;
// LOG_D(PHY,"config#2: nprach_SubcarrierOffset= %d\n", fp->nprach_config_common.nprach_ParametersList.list[2].nprach_SubcarrierOffset);
// fp->nprach_config_common.nprach_ParametersList.list[2].nprach_NumSubcarriers = config->nprach_config_2_number_of_subcarriers.value;
// LOG_D(PHY,"config#2: nprach_NumSubcarriers= %d\n",fp->nprach_config_common.nprach_ParametersList.list[2].nprach_NumSubcarriers);
// fp->nprach_config_common.nprach_ParametersList.list[2].numRepetitionsPerPreambleAttempt = config->nprach_config_2_number_of_repetitions_per_attempt.value;
// LOG_D(PHY,"config#2: numRepetitionsPerPreambleAttempt= %d\n",fp->nprach_config_common.nprach_ParametersList.list[2].numRepetitionsPerPreambleAttempt);
// //////////////////////////////////////////////////////////////////////////////////////
// /*
// eNB->nprach_config_common.nprach_CP_Length = config->nprach_config_2_cp_length.value;
// eNB->nprach_config_common.nprach_ParametersList.list[2].nprach_Periodicity = config->nprach_config_2_sf_periodicity.value;
// eNB->nprach_config_common.nprach_ParametersList.list[2].nprach_StartTime = config->nprach_config_2_start_time.value;
// eNB->nprach_config_common.nprach_ParametersList.list[2].nprach_SubcarrierOffset = config->nprach_config_2_subcarrier_offset.value;
// eNB->nprach_config_common.nprach_ParametersList.list[2].nprach_NumSubcarriers = config->nprach_config_2_number_of_subcarriers.value;
// eNB->nprach_config_common.nprach_ParametersList.list[2].numRepetitionsPerPreambleAttempt = config->nprach_config_2_number_of_repetitions_per_attempt.value;
// */
// //////////////////////////////////////////////////////////////////////////////////////
// //missed configuration in FAPI config_request (TS 36.331 pag 610) (may not needed)
// /*fp->nprach_config_common.nprach_ParametersList.list.array[2]->nprach_SubcarrierMSG3_RangeStart = extra_phy_parms->nprach_config_2_subcarrier_MSG3_range_start;
// LOG_D(PHY,"config#2: nprach_SubcarrierMSG3_RangeStart= %d\n",fp->nprach_config_common.nprach_ParametersList.list.array[2]->nprach_SubcarrierMSG3_RangeStart);
// fp->nprach_config_common.nprach_ParametersList.list.array[2]->npdcch_StartSF_CSS_RA = extra_phy_parms->nprach_config_2_npdcch_startSF_CSS_RA;
// LOG_D(PHY,"config#2: npdcch_StartSF_CSS_RA= %d\n",fp->nprach_config_common.nprach_ParametersList.list.array[2]->npdcch_StartSF_CSS_RA);
// fp->nprach_config_common.nprach_ParametersList.list.array[2]->npdcch_NumRepetitions_RA = extra_phy_parms->nprach_config_2_npdcch_num_repetitions_RA;
// LOG_D(PHY,"config#2: npdcch_NumRepetitions_RA= %d\n",fp->nprach_config_common.nprach_ParametersList.list.array[2]->npdcch_NumRepetitions_RA);
// fp->nprach_config_common.nprach_ParametersList.list.array[2]->npdcch_Offset_RA = extra_phy_parms->nprach_config_2_npdcch_offset_RA;
// LOG_D(PHY,"config#2: npdcch_Offset_RA= %d\n",fp->nprach_config_common.nprach_ParametersList.list.array[2]->npdcch_Offset_RA);
// fp->nprach_config_common.nprach_ParametersList.list.array[2]->maxNumPreambleAttemptCE = extra_phy_parms->nprach_config_2_max_num_preamble_attempt_CE;
// LOG_D(PHY,"config#2: maxNumPreambleAttemptCE= %d\n",fp->nprach_config_common.nprach_ParametersList.list.array[2]->maxNumPreambleAttemptCE);
// */
// //fp->nprach_config_common.rsrp_ThresholdsPrachInfoList.list /*OPTIONAL*/
// }
// //TODO: Should modify to compute_nprach_seq --> nprach.
// //compute_prach_seq(&fp->prach_config_common,fp->frame_type,PHY_vars_eNB_NB_IoT_g[Mod_id][0]->X_u);
// /*NPDSCH ConfigCommon-------------------------------------------------------------------*/
// //NPDSCH_ConfigCommon_NB_r13_t b;
// //FIXME: the FAPI specs pag 140 fix a range of value (0->255) but i don't find any similar correspondence in the 3GPP specs (TS 36.331 pag 608 and TS 36.213 ch 16.2.2)
// fp->npdsch_config_common.nrs_Power = rf_config->reference_signal_power.value;
// /*NPUSCH ConfigCommon-------------------------------------------------------------------*/
// //NPUSCH_ConfigCommon_NB_r13_t c;
// fp->npusch_config_common.dmrs_Config.threeTone_BaseSequence = config->three_tone_base_sequence.value;
// LOG_D(PHY,"npusch_config_common.dmrs_Config.threeTone_BaseSequence = %d\n",fp->npusch_config_common.dmrs_Config.threeTone_BaseSequence);
// fp->npusch_config_common.dmrs_Config.sixTone_BaseSequence = config->six_tone_base_sequence.value;
// LOG_D(PHY,"npusch_config_common.dmrs_Config.sixTone_BaseSequence = %d\n",fp->npusch_config_common.dmrs_Config.sixTone_BaseSequence);
// fp->npusch_config_common.dmrs_Config.threeTone_CyclicShift = config->three_tone_cyclic_shift.value;
// LOG_D(PHY,"npusch_config_common.dmrs_Config.threeTone_CyclicShift = %d\n",fp->npusch_config_common.dmrs_Config.threeTone_CyclicShift);
// fp->npusch_config_common.dmrs_Config.sixTone_CyclicShift = config->six_tone_cyclic_shift.value;
// LOG_D(PHY,"npusch_config_common.dmrs_Config.sixTone_CyclicShift = %d\n",fp->npusch_config_common.dmrs_Config.sixTone_CyclicShift);
// fp->npusch_config_common.dmrs_Config.twelveTone_BaseSequence= config->twelve_tone_base_sequence.value;
// LOG_D(PHY,"npusch_config_common.dmrs_Config.twelveTone_BaseSequence = %d\n",fp->npusch_config_common.dmrs_Config.twelveTone_BaseSequence);
// fp->npusch_config_common.ul_ReferenceSignalsNPUSCH.groupHoppingEnabled = ul_nrs_config->uplink_rs_hopping.value;
// LOG_D(PHY,"npusch_config_common.ul_ReferenceSignalsNPUSCH.groupHoppingEnabled = %d\n",fp->npusch_config_common.ul_ReferenceSignalsNPUSCH.groupHoppingEnabled);
// LOG_D(PHY,"**%s**\n",fp->npusch_config_common.ul_ReferenceSignalsNPUSCH.groupHoppingEnabled == 1 ? "RS_GROUP_HOPPING" : "RS_NO_HOPPING");
// fp->npusch_config_common.ul_ReferenceSignalsNPUSCH.groupAssignmentNPUSCH = ul_nrs_config->group_assignment.value;
// LOG_D(PHY,"npusch_config_common.ul_ReferenceSignalsNPUSCH.groupAssignmentNPUSCH = %d]n",fp->npusch_config_common.ul_ReferenceSignalsNPUSCH.groupAssignmentNPUSCH);
// //MP: FAPI missed parameters (may not needed at eNB side and some of them are optional by the 3GPP specs)
// //fp->npusch_config_common.ack_NACK_NumRepetitions_Msg4 --> list of size maxNPRACH_Resources_NB_r13 (3 elements)
// //fp->npusch_config_common.srs_SubframeConfig /*OPTIONAL*/
// //No Frequency hopping in NULSCH for NB-IoT and not init_ncs_cell used for PUCCH
// /*UL Power Control Config Common---------------------------------------------------------*/
// //F nothing has been defined in FAPI specs for this (may because are only UE stuffs)
// /*fp->ul_power_control_config_common.p0_NominalNPUSCH = extra_phy_parms->p0_nominal_npusch;
// fp->ul_power_control_config_common.alpha = extra_phy_parms->alpha;
// fp->ul_power_control_config_common.deltaPreambleMsg3 = extra_phy_parms->delta_preamle_MSG*/
// /*DL gap Config - OPTIONAL----------------------------------------------------------------*/
// //DL_GapConfig_NB_r13_t a;
// if(config->dl_gap_config_enable.value == 1){
// fp->DL_gap_config.dl_GapDurationCoeff= config->dl_gap_periodicity.value;
// fp->DL_gap_config.dl_GapPeriodicity = config->dl_gap_periodicity.value;
// fp->DL_gap_config.dl_GapThreshold = config->dl_gap_threshold.value;
// }
// LOG_I(PHY,"SIB-2 configure complete\n");
// }
// #endif
// void phy_config_dedicated_eNB_NB_IoT(module_id_t Mod_id,
// rnti_t rnti,
// extra_phyConfig_t *extra_parms)
// {
// PHY_VARS_eNB_NB_IoT *eNB = PHY_vars_eNB_NB_IoT_g[Mod_id][0];
// NB_IoT_eNB_NPDCCH_t *npdcch;
// uint8_t UE_id = find_ue_NB_IoT(rnti,eNB);
// if (UE_id == -1) {
// LOG_E( PHY, "[eNB %"PRIu8"] find_ue() returns -1\n", Mod_id);
// return;
// }
// //configure UE specific parameters for NPDCCH Search Space
// if (eNB->npdcch[UE_id]) {
// npdcch = eNB->npdcch[UE_id];
// npdcch->rnti[0] = rnti;
// npdcch->npdcch_NumRepetitions[0] = extra_parms->npdcch_NumRepetitions; //Rmax maybe is the only one needed
// //npdcch->npdcch_Offset_USS = extra_parms->npdcch_Offset_USS;
// //npdcch->npdcch_StartSF_USS = extra_parms->npdcch_StartSF_USS;
// LOG_I(PHY,"phy_config_dedicated_eNB_NB_IoT: npdcch_NumRepetitions = %d\n",npdcch->npdcch_NumRepetitions[0]);
// } else {
// LOG_E(PHY,"[eNB %d] Received NULL radioResourceConfigDedicated from eNB %d\n",Mod_id, UE_id);
// return;
// }
// }

View File

@@ -0,0 +1,147 @@
#include "defs.h"
#include "common/utils/LOG/log.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
int init_frame_parms_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint8_t osf)
{
uint8_t log2_osf;
#if DISABLE_LOG_X
printf("Initializing frame parms for N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
#else
LOG_I(PHY,"Initializing frame parms for N_RB_DL %d, Ncp %d, osf %d\n",frame_parms->N_RB_DL,frame_parms->Ncp,osf);
#endif
frame_parms->nb_prefix_samples0 = 160;
frame_parms->nb_prefix_samples = 144;
frame_parms->symbols_per_tti = 14;
switch(osf) {
case 1:
log2_osf = 0;
break;
case 2:
log2_osf = 1;
break;
case 4:
log2_osf = 2;
break;
case 8:
log2_osf = 3;
break;
case 16:
log2_osf = 4;
break;
default:
printf("Illegal oversampling %d\n",osf);
return(-1);
}
switch (frame_parms->N_RB_DL) {
case 100:
if (osf>1) {
printf("Illegal oversampling %d for N_RB_DL %d\n",osf,frame_parms->N_RB_DL);
return(-1);
}
if (frame_parms->threequarter_fs) {
frame_parms->ofdm_symbol_size = 1536;
frame_parms->samples_per_tti = 23040;
frame_parms->first_carrier_offset = 1536-600;
frame_parms->nb_prefix_samples=(frame_parms->nb_prefix_samples*3)>>2;
frame_parms->nb_prefix_samples0=(frame_parms->nb_prefix_samples0*3)>>2;
}
else {
frame_parms->ofdm_symbol_size = 2048;
frame_parms->samples_per_tti = 30720;
frame_parms->first_carrier_offset = 2048-600;
}
break;
case 75:
if (osf>1) {
printf("Illegal oversampling %d for N_RB_DL %d\n",osf,frame_parms->N_RB_DL);
return(-1);
}
frame_parms->ofdm_symbol_size = 1536;
frame_parms->samples_per_tti = 23040;
frame_parms->first_carrier_offset = 1536-450;
frame_parms->nb_prefix_samples=(frame_parms->nb_prefix_samples*3)>>2;
frame_parms->nb_prefix_samples0=(frame_parms->nb_prefix_samples0*3)>>2;
break;
case 50:
if (osf>1) {
printf("Illegal oversampling %d for N_RB_DL %d\n",osf,frame_parms->N_RB_DL);
return(-1);
}
frame_parms->ofdm_symbol_size = 1024*osf;
frame_parms->samples_per_tti = 15360*osf;
frame_parms->first_carrier_offset = frame_parms->ofdm_symbol_size - 300;
frame_parms->nb_prefix_samples>>=(1-log2_osf);
frame_parms->nb_prefix_samples0>>=(1-log2_osf);
break;
case 25:
if (osf>2) {
printf("Illegal oversampling %d for N_RB_DL %d\n",osf,frame_parms->N_RB_DL);
return(-1);
}
frame_parms->ofdm_symbol_size = 512*osf;
frame_parms->samples_per_tti = 7680*osf;
frame_parms->first_carrier_offset = frame_parms->ofdm_symbol_size - 150;
frame_parms->nb_prefix_samples>>=(2-log2_osf);
frame_parms->nb_prefix_samples0>>=(2-log2_osf);
break;
case 15:
frame_parms->ofdm_symbol_size = 256*osf;
frame_parms->samples_per_tti = 3840*osf;
frame_parms->first_carrier_offset = frame_parms->ofdm_symbol_size - 90;
frame_parms->nb_prefix_samples>>=(3-log2_osf);
frame_parms->nb_prefix_samples0>>=(3-log2_osf);
break;
case 6:
frame_parms->ofdm_symbol_size = 128*osf;
frame_parms->samples_per_tti = 1920*osf;
frame_parms->first_carrier_offset = frame_parms->ofdm_symbol_size - 36;
frame_parms->nb_prefix_samples>>=(4-log2_osf);
frame_parms->nb_prefix_samples0>>=(4-log2_osf);
break;
default:
printf("init_frame_parms: Error: Number of resource blocks (N_RB_DL %d) undefined, frame_parms = %p \n",frame_parms->N_RB_DL, frame_parms);
return(-1);
break;
}
printf("lte_parms.c: Setting N_RB_DL to %d, ofdm_symbol_size %d\n",frame_parms->N_RB_DL, frame_parms->ofdm_symbol_size);
// frame_parms->tdd_config=3;
return(0);
}

View File

@@ -0,0 +1,18 @@
#ifndef __PHY_INIT_NB_IOT__H__
#define __PHY_INIT_NB_IOT__H__
#include "../defs_L1_NB_IoT.h"
// for NB-IoT testing
PHY_VARS_eNB_NB_IoT* init_lte_eNB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t eNB_id,
uint8_t Nid_cell,
eNB_func_NB_IoT_t node_function,
uint8_t abstraction_flag);
int phy_init_lte_eNB_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNb,
unsigned char is_secondary_eNb,
unsigned char abstraction_flag);
#endif

View File

@@ -0,0 +1,161 @@
/***********************************************************************
**********************************************************************/
/*! \file PHY/LTE_REFSIG/lte_dl_cell_spec_NB_IoT.c
* \function called by pilots_NB_IoT.c , TS 36-211, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
/* check if this is required for NB-IoT
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#endif
*/
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "PHY/defs_L1_NB_IoT.h"
int lte_dl_cell_spec_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
int32_t *output,
short amp,
unsigned char Ns,
unsigned char l,
unsigned char p,
unsigned short RB_IoT_ID) // the ID of the RB dedicated for NB_IoT
{
unsigned char nu,m;
unsigned char mprime,mprime_dword,mprime_qpsk_symb;
unsigned short k,a;
unsigned short NB_IoT_start,bandwidth_even_odd;
int32_t qpsk[4];
a = (amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15;
((short *)&qpsk[0])[0] = a;
((short *)&qpsk[0])[1] = a;
((short *)&qpsk[1])[0] = -a;
((short *)&qpsk[1])[1] = a;
((short *)&qpsk[2])[0] = a;
((short *)&qpsk[2])[1] = -a;
((short *)&qpsk[3])[0] = -a;
((short *)&qpsk[3])[1] = -a;
if ((p==0) && (l==0) )
nu = 0;
else if ((p==0) && (l>0))
nu = 3;
else if ((p==1) && (l==0))
nu = 3;
else if ((p==1) && (l>0))
nu = 0;
else {
printf("lte_dl_cell_spec_NB_IoT: p %d, l %d -> ERROR\n",p,l);
return(-1);
}
//mprime = 110 - eNB->frame_parms.N_RB_DL;
mprime = 109;
// testing if the total number of RBs is even or odd
bandwidth_even_odd = phy_vars_eNB->frame_parms.N_RB_DL % 2; // 0 even, 1 odd
//mprime = 0; // mprime = 0,1 for NB_IoT // for LTE , maximum number of resources blocks (110) - the total number of RB in the selected bandwidth (.... 15 , 25 , 50, 100)
k = (nu + phy_vars_eNB->frame_parms.nushift)%6;
if(RB_IoT_ID < (phy_vars_eNB->frame_parms.N_RB_DL/2))
{ //XXX this mod operation is not valid since the second member is not an integer but double (for the moment i put a cast)
NB_IoT_start = phy_vars_eNB->frame_parms.ofdm_symbol_size - 12*(phy_vars_eNB->frame_parms.N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID%((int)(ceil(phy_vars_eNB->frame_parms.N_RB_DL/(float)2))));
} else {
//XXX invalid mod operation (put a cast for the moment)
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID%((int)(ceil(phy_vars_eNB->frame_parms.N_RB_DL/(float)2))));
}
k+=NB_IoT_start;
DevAssert( Ns < 20 );
DevAssert( l < 2 );
for (m=0; m<2; m++) {
mprime_dword = mprime>>4;
mprime_qpsk_symb = mprime&0xf;
output[k] = qpsk[(phy_vars_eNB->lte_gold_table_NB_IoT[Ns][l][mprime_dword]>>(2*mprime_qpsk_symb)) & 3]; //TODO should be defined one for NB-IoT
mprime++;
k+=6;
}
return(0);
}
/////////////////////////////////////////////////////////////////////////
/*
int lte_dl_cell_spec_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
int32_t *output,
short amp,
unsigned char Ns,
unsigned char l,
unsigned char p,
unsigned short RB_IoT_ID) // the ID of the RB dedicated for NB_IoT
{
unsigned char nu,m;
unsigned short k,a;
unsigned short NB_IoT_start,bandwidth_even_odd;
int32_t qpsk[4];
a = (amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15;
((short *)&qpsk[0])[0] = a;
((short *)&qpsk[0])[1] = a;
((short *)&qpsk[1])[0] = -a;
((short *)&qpsk[1])[1] = a;
((short *)&qpsk[2])[0] = a;
((short *)&qpsk[2])[1] = -a;
((short *)&qpsk[3])[0] = -a;
((short *)&qpsk[3])[1] = -a;
if ((p==0) && (l==0) )
nu = 0;
else if ((p==0) && (l>0))
nu = 3;
else if ((p==1) && (l==0))
nu = 3;
else if ((p==1) && (l>0))
nu = 0;
else {
printf("lte_dl_cell_spec_NB_IoT: p %d, l %d -> ERROR\n",p,l);
return(-1);
}
// testing if the total number of RBs is even or odd
bandwidth_even_odd = phy_vars_eNB->frame_parms.N_RB_DL % 2; // 0 even, 1 odd
//mprime = 0; // mprime = 0,1 for NB_IoT // for LTE , maximum number of resources blocks (110) - the total number of RB in the selected bandwidth (.... 15 , 25 , 50, 100)
k = (nu + phy_vars_eNB->frame_parms.nushift)%6;
if(RB_IoT_ID < (phy_vars_eNB->frame_parms.N_RB_DL/2))
{ //XXX this mod operation is not valid since the second member is not an integer but double (for the moment i put a cast)
NB_IoT_start = phy_vars_eNB->frame_parms.ofdm_symbol_size - 12*(phy_vars_eNB->frame_parms.N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID%((int)(ceil(phy_vars_eNB->frame_parms.N_RB_DL/(float)2))));
} else {
//XXX invalid mod operation (put a cast for the moment)
NB_IoT_start = (bandwidth_even_odd*6) + 12*(RB_IoT_ID%((int)(ceil(phy_vars_eNB->frame_parms.N_RB_DL/(float)2))));
}
k+=NB_IoT_start;
DevAssert( Ns < 20 );
DevAssert( l < 2 );
for (m=0; m<2; m++) {
output[k] = qpsk[(phy_vars_eNB->lte_gold_table_NB_IoT[Ns][l][0]) & 3]; //TODO should be defined one for NB-IoT
k+=6;
}
return(0);
}
*/

View File

@@ -0,0 +1,83 @@
/***********************************************************************
**********************************************************************/
/*! \file PHY/LTE_REFSIG/lte_gold_NB_IoT.c
* \function called by lte_dl_cell_spec_NB_IoT.c , TS 36-211, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
//#include "defs.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "../impl_defs_lte_NB_IoT.h"
void lte_gold_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t lte_gold_table_NB_IoT[20][2][14],uint16_t Nid_cell) // Nid_cell = Nid_cell_NB_IoT
{
unsigned char ns,l,Ncp=1;
unsigned int n,x1,x2;
for (ns=0; ns<20; ns++) {
for (l=0; l<2; l++) {
x2 = Ncp + (Nid_cell<<1) + (((1+(Nid_cell<<1))*(1 + (l+5) + (7*(1+ns))))<<10); //cinit
x1 = 1+ (1<<31);
x2 = x2 ^ ((x2 ^ (x2>>1) ^ (x2>>2) ^ (x2>>3))<<31);
// skip first 50 double words (1600 bits)
for (n=1; n<50; n++) {
x1 = (x1>>1) ^ (x1>>4);
x1 = x1 ^ (x1<<31) ^ (x1<<28);
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
}
for (n=0; n<14; n++) {
x1 = (x1>>1) ^ (x1>>4);
x1 = x1 ^ (x1<<31) ^ (x1<<28);
x2 = (x2>>1) ^ (x2>>2) ^ (x2>>3) ^ (x2>>4);
x2 = x2 ^ (x2<<31) ^ (x2<<30) ^ (x2<<29) ^ (x2<<28);
lte_gold_table_NB_IoT[ns][l][n] = x1^x2;
}
}
}
}
// \brief gold sequenquence generator
//\param x1
//\param x2 this should be set to c_init if reset=1
//\param reset resets the generator
//\return 32 bits of the gold sequence
unsigned int lte_gold_generic_NB_IoT(unsigned int *x1, unsigned int *x2, unsigned char reset)
{
int n;
if (reset) {
*x1 = 1+ (1<<31);
*x2=*x2 ^ ((*x2 ^ (*x2>>1) ^ (*x2>>2) ^ (*x2>>3))<<31);
for (n=1; n<50; n++) {
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
}
}
*x1 = (*x1>>1) ^ (*x1>>4);
*x1 = *x1 ^ (*x1<<31) ^ (*x1<<28);
*x2 = (*x2>>1) ^ (*x2>>2) ^ (*x2>>3) ^ (*x2>>4);
*x2 = *x2 ^ (*x2<<31) ^ (*x2<<30) ^ (*x2<<29) ^ (*x2<<28);
return(*x1^*x2);
}

View File

@@ -0,0 +1,329 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_REFSIG/lte_ul_ref_NB_IoT.c
* \function called by lte_dl_cell_spec_NB_IoT.c , TS 36-211, V13.4.0 2017-02
* \author: Vincent Savaux
* \date 2018
* \version 0.0
* \company b<>com
* \email: vincent.savaux@b-com.com
* \note
* \warning
*/
#ifdef MAIN
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#endif
// #include "defs.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "PHY/defs_L1_NB_IoT.h"
#include "lte_refsig.h"
// uint16_t dftsizes[33] = {12,24,36,48,60,72,96,108,120,144,180,192,216,240,288,300,324,360,384,432,480,540,576,600,648,720,864,900,960,972,1080,1152,1200};
// uint16_t ref_primes[33] = {11,23,31,47,59,71,89,107,113,139,179,191,211,239,283,293,317,359,383,431,479,523,571,599,647,719,863,887,953,971,1069,1151,1193};
uint16_t sequence_length[4] = {100,100,100,100}; //the "32" value corresponds to the max gold sequence length
// int16_t *ul_ref_sigs[30][33];
int16_t *ul_ref_sigs_rx_NB_IoT[30][4]; //these contain the sequences in repeated format and quantized to QPSK ifdef IFFT_FPGA
int16_t *ul_ref_sigs_f2_rx_NB_IoT[16]; //this table contain the 16 possible pilots for format 2 NPUSCH
uint16_t u_max[4] = {16,12,14,30}; // maximum u value, see 36.211, Section 10.1.4
/* 36.211 table 5.5.1.2-1 */
char ref12_NB_IoT[360] = {-1,1,3,-3,3,3,1,1,3,1,-3,3,1,1,3,3,3,-1,1,-3,-3,1,-3,3,1,1,-3,-3,-3,-1,-3,-3,1,-3,1,-1,-1,1,1,1,1,-1,-3,-3,1,-3,3,-1,-1,3,1,-1,1,-1,-3,-1,1,-1,1,3,1,-3,3,-1,-1,1,1,-1,-1,3,-3,1,-1,3,-3,-3,-3,3,1,-1,3,3,-3,1,-3,-1,-1,-1,1,-3,3,-1,1,-3,3,1,1,-3,3,1,-1,-1,-1,1,1,3,-1,1,1,-3,-1,3,3,-1,-3,1,1,1,1,1,-1,3,-1,1,1,-3,-3,-1,-3,-3,3,-1,3,1,-1,-1,3,3,-3,1,3,1,3,3,1,-3,1,1,-3,1,1,1,-3,-3,-3,1,3,3,-3,3,-3,1,1,3,-1,-3,3,3,-3,1,-1,-3,-1,3,1,3,3,3,-1,1,3,-1,1,-3,-1,-1,1,1,3,1,-1,-3,1,3,1,-1,1,3,3,3,-1,-1,3,-1,-3,1,1,3,-3,3,-3,-3,3,1,3,-1,-3,3,1,1,-3,1,-3,-3,-1,-1,1,-3,-1,3,1,3,1,-1,-1,3,-3,-1,-3,-1,-1,-3,1,1,1,1,3,1,-1,1,-3,-1,-1,3,-1,1,-3,-3,-3,-3,-3,1,-1,-3,1,1,-3,-3,-3,-3,-1,3,-3,1,-3,3,1,1,-1,-3,-1,-3,1,-1,1,3,-1,1,1,1,3,1,3,3,-1,1,-1,-3,-3,1,1,-3,3,3,1,3,3,1,-3,-1,-1,3,1,3,-3,-3,3,-3,1,-1,-1,3,-1,-3,-3,-1,-3,-1,-3,3,1,-1,1,3,-3,-3,-1,3,-3,3,-1,3,3,-3,3,3,-1,-1,3,-3,-3,-1,-1,-3,-1,3,-3,3,1,-1};
/* 36.211 table 5.5.1.2-2 */
// char ref24[720] = {
// -1,3,1,-3,3,-1,1,3,-3,3,1,3,-3,3,1,1,-1,1,3,-3,3,-3,-1,-3,-3,3,-3,-3,-3,1,-3,-3,3,-1,1,1,1,3,1,-1,3,-3,-3,1,3,1,1,-3,3,-1,3,3,1,1,-3,3,3,3,3,1,-1,3,-1,1,1,-1,-3,-1,-1,1,3,3,-1,-3,1,1,3,-3,1,1,-3,-1,-1,1,3,1,3,1,-1,3,1,1,-3,-1,-3,-1,-1,-1,-1,-3,-3,-1,1,1,3,3,-1,3,-1,1,-1,-3,1,-1,-3,-3,1,-3,-1,-1,-3,1,1,3,-1,1,3,1,-3,1,-3,1,1,-1,-1,3,-1,-3,3,-3,-3,-3,1,1,1,1,-1,-1,3,-3,-3,3,-3,1,-1,-1,1,-1,1,1,-1,-3,-1,1,-1,3,-1,-3,-3,3,3,-1,-1,-3,-1,3,1,3,1,3,1,1,-1,3,1,-1,1,3,-3,-1,-1,1,-3,1,3,-3,1,-1,-3,3,-3,3,-1,-1,-1,-1,1,-3,-3,-3,1,-3,-3,-3,1,-3,1,1,-3,3,3,-1,-3,-1,3,-3,3,3,3,-1,1,1,-3,1,-1,1,1,-3,1,1,-1,1,-3,-3,3,-1,3,-1,-1,-3,-3,-3,-1,-3,-3,1,-1,1,3,3,-1,1,-1,3,1,3,3,-3,-3,1,3,1,-1,-3,-3,-3,3,3,-3,3,3,-1,-3,3,-1,1,-3,1,1,3,3,1,1,1,-1,-1,1,-3,3,-1,1,1,-3,3,3,-1,-3,3,-3,-1,-3,-1,3,-1,-1,-1,-1,-3,-1,3,3,1,-1,1,3,3,3,-1,1,1,-3,1,3,-1,-3,3,-3,-3,3,1,3,1,-3,3,1,3,1,1,3,3,-1,-1,-3,1,-3,-1,3,1,1,3,-1,-1,1,-3,1,3,-3,1,-1,-3,-1,3,1,3,1,-1,-3,-3,-1,-1,-3,-3,-3,-1,-1,-3,3,-1,-1,-1,-1,1,1,-3,3,1,3,3,1,-1,1,-3,1,-3,1,1,-3,-1,1,3,-1,3,3,-1,-3,1,-1,-3,3,3,3,-1,1,1,3,-1,-3,-1,3,-1,-1,-1,1,1,1,1,1,-1,3,-1,-3,1,1,3,-3,1,-3,-1,1,1,-3,-3,3,1,1,-3,1,3,3,1,-1,-3,3,-1,3,3,3,-3,1,-1,1,-1,-3,-1,1,3,-1,3,-3,-3,-1,-3,3,-3,-3,-3,-1,-1,-3,-1,-3,3,1,3,-3,-1,3,-1,1,-1,3,-3,1,-1,-3,-3,1,1,-1,1,-1,1,-1,3,1,-3,-1,1,-1,1,-1,-1,3,3,-3,-1,1,-3,-3,-1,-3,3,1,-1,-3,-1,-3,-3,3,-3,3,-3,-1,1,3,1,-3,1,3,3,-1,-3,-1,-1,-1,-1,3,3,3,1,3,3,-3,1,3,-1,3,-1,3,3,-3,3,1,-1,3,3,1,-1,3,3,-1,-3,3,-3,-1,-1,3,-1,3,-1,-1,1,1,1,1,-1,-1,-3,-1,3,1,-1,1,-1,3,-1,3,1,1,-1,-1,-3,1,1,-3,1,3,-3,1,1,-3,-3,-1,-1,-3,-1,1,3,1,1,-3,-1,-1,-3,3,-3,3,1,-3,3,-3,1,-1,1,-3,1,1,1,-1,-3,3,3,1,1,3,-1,-3,-1,-1,-1,3,1,-3,-3,-1,3,-3,-1,-3,-1,-3,-1,-1,-3,-1,-1,1,-3,-1,-1,1,-1,-3,1,1,-3,1,-3,-3,3,1,1,-1,3,-1,-1,1,1,-1,-1,-3,-1,3,-1,3,-1,1,3,1,-1,3,1,3,-3,-3,1,-1,-1,1,3
// };
// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-1
char ref3[36] = {1, -3, -3, 1, -3, -1, 1, -3, 3, 1, -1, -1, 1, -1, 1, 1, -1, 3, 1, 1, -3, 1, 1, -1, 1, 1, 3, 1, 3, -1, 1, 3, 1, 1, 3, 3 };
// 36.211, Section 10.1.4.1.2, Table 10.1.4.1.2-2
char ref6[84] = {1, 1, 1, 1, 3, -3, 1, 1, 3, 1, -3, 3, 1, -1, -1, -1, 1, -3, 1, -1, 3, -3, -1, -1, 1, 3, 1, -1, -1, 3, 1, -3, -3, 1, 3, 1, -1, -1, 1, -3, -3, -1,
-1, -1, -1, 3, -3, -1, 3, -1, 1, -3, -3, 3, 3, -1, 3, -3, -1, 1, 3, -3, 3, -1, 3, 3, -3, 1, 3, 1, -3, -1, -3, 1, -3, 3, -3, -1, -3, 3, -3, 1, 1, -3};
// NB-IoT: 36.211, Section 10.1.4.1.1, Table 10.1.4.1.1-1
int16_t w_n[256] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1,
1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1,
1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1, 1,-1,-1, 1,
1, 1, 1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1,
1,-1, 1,-1,-1, 1,-1, 1, 1,-1, 1,-1,-1, 1,-1, 1,
1, 1,-1,-1,-1,-1, 1, 1, 1, 1,-1,-1,-1,-1, 1, 1,
1,-1,-1, 1,-1, 1, 1,-1, 1,-1,-1, 1,-1, 1, 1,-1,
1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1,
1,-1, 1,-1, 1,-1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1,
1, 1,-1,-1, 1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1,
1,-1,-1, 1, 1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1,
1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1,-1, 1, 1, 1, 1,
1,-1, 1,-1,-1, 1,-1, 1,-1, 1,-1, 1, 1,-1, 1,-1,
1, 1,-1,-1,-1,-1, 1, 1,-1,-1, 1, 1, 1, 1,-1,-1,
1,-1,-1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 1,-1,-1, 1
};
// void generate_ul_ref_sigs(void)
// {
// double qbar,phase;
// unsigned int u,v,Msc_RS,q,m,n;
// // These are the Zadoff-Chu sequences (for RB 3-100)
// for (Msc_RS=2; Msc_RS<33; Msc_RS++) {
// for (u=0; u<30; u++) {
// for (v=0; v<2; v++) {
// qbar = ref_primes[Msc_RS] * (u+1)/(double)31;
// ul_ref_sigs[u][v][Msc_RS] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[Msc_RS]);
// if ((((int)floor(2*qbar))&1) == 0)
// q = (int)(floor(qbar+.5)) - v;
// else
// q = (int)(floor(qbar+.5)) + v;
// #ifdef MAIN
// printf("Msc_RS %d (%d), u %d, v %d -> q %d (qbar %f)\n",Msc_RS,dftsizes[Msc_RS],u,v,q,qbar);
// #endif
// for (n=0; n<dftsizes[Msc_RS]; n++) {
// m=n%ref_primes[Msc_RS];
// phase = (double)q*m*(m+1)/ref_primes[Msc_RS];
// ul_ref_sigs[u][v][Msc_RS][n<<1] =(int16_t)(floor(32767*cos(M_PI*phase)));
// ul_ref_sigs[u][v][Msc_RS][1+(n<<1)] =-(int16_t)(floor(32767*sin(M_PI*phase)));
// #ifdef MAIN
// if (Msc_RS<5)
// printf("(%d,%d) ",ul_ref_sigs[u][v][Msc_RS][n<<1],ul_ref_sigs[u][v][Msc_RS][1+(n<<1)]);
// #endif
// }
// #ifdef MAIN
// if (Msc_RS<5)
// printf("\n");
// #endif
// }
// }
// }
// // These are the sequences for RB 1
// for (u=0; u<30; u++) {
// ul_ref_sigs[u][0][0] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[0]);
// for (n=0; n<dftsizes[0]; n++) {
// ul_ref_sigs[u][0][0][n<<1] =(int16_t)(floor(32767*cos(M_PI*ref12[(u*12) + n]/4)));
// ul_ref_sigs[u][0][0][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref12[(u*12) + n]/4)));
// }
// }
// // These are the sequences for RB 2
// for (u=0; u<30; u++) {
// ul_ref_sigs[u][0][1] = (int16_t*)malloc16(2*sizeof(int16_t)*dftsizes[1]);
// for (n=0; n<dftsizes[1]; n++) {
// ul_ref_sigs[u][0][1][n<<1] =(int16_t)(floor(32767*cos(M_PI*ref24[(u*24) + n]/4)));
// ul_ref_sigs[u][0][1][1+(n<<1)]=(int16_t)(floor(32767*sin(M_PI*ref24[(u*24) + n]/4)));
// }
// }
// }
/*void generate_ul_ref_sigs_rx_NB_IoT(void)
{
unsigned int u,index_Nsc_RU,n; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12
uint8_t npusch_format = 1; // NB-IoT: format 1 (data), or 2: ack. Should be defined in higher layer
int16_t a;
int16_t qpsk[2];
unsigned int x1, x2=35; // NB-IoT: defined in 36.211, Section 10.1.4.1.1
int16_t ref_sigs_sc1[2*sequence_length[0]];
uint32_t s;
a = (ONE_OVER_SQRT2_Q15_NB_IoT)>>15;
qpsk[0] = a;
qpsk[1] = -a;
s = lte_gold_generic_NB_IoT(&x1, &x2, 1);
for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++) {
for (u=0; u<u_max[index_Nsc_RU]; u++) {
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc16(2*sizeof(int16_t)*sequence_length[index_Nsc_RU]);
switch (index_Nsc_RU){
case 0: // 36.211, Section 10.1.4.1.1
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*sequence_length[index_Nsc_RU]*12+24)); // *12 is mandatory to fit channel estimation functions
// NB-IoT: for same reason, +24 is added in order to fit the possible subcarrier start shift when index_Nsc_RU = 0, 1, 2 --> see ul_sc_start in channel estimation function
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
if (n!=0 && n%32==0)
{
s = lte_gold_generic_NB_IoT(&x1, &x2, 0);
}
ref_sigs_sc1[n<<1] = qpsk[(s>>(n%32))&1]*w_n[16*u+n%16];
// ref_sigs_sc1[1+(n<<1)] = qpsk[(s>>n)&1]*w_n[16*u+n%16];
ref_sigs_sc1[1+(n<<1)] = ref_sigs_sc1[n<<1];
}
if (npusch_format==1){
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1] = ref_sigs_sc1[n<<1];
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= ref_sigs_sc1[1+(n<<1)];
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][12*(n<<1)+24] = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, real part
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+12*(n<<1)+24]= ref_sigs_sc1[1+(n<<1)]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, imaginary part
}
}
if (npusch_format==2){// NB-IoT: to be implemented
printf("Not coded yet\n");
}
break;
case 1: // 36.211, Section 10.1.4.1.2
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*12+24)); // *12 is mandatory to fit channel estimation functions
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift])));
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref3[(u*3) + n]/4 + alpha3[threetnecyclicshift])));
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][(n<<1)+24] = (int16_t)(floor(32767*cos(M_PI*ref3[(u*3) + n]/4 )));
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)+24]= (int16_t)(floor(32767*sin(M_PI*ref3[(u*3) + n]/4 )));
}
break;
case 2:
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*12+24)); // *12 is mandatory to fit channel estimation functions
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref6[(u*6) + n]/4 + alpha6[sixtonecyclichift])));
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][(n<<1)+24] = (int16_t)(floor(32767*cos(M_PI*ref6[(u*6) + n]/4 )));
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)+24]= (int16_t)(floor(32767*sin(M_PI*ref6[(u*6) + n]/4 )));
}
break;
case 3:
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*12+24)); // *12 is mandatory to fit channel estimation functions
for (n=0; n<sequence_length[index_Nsc_RU]; n++) {
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][n<<1] = (int16_t)(floor(32767*cos(M_PI*ref12_NB_IoT[(u*12) + n]/4)));
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+(n<<1)]= (int16_t)(floor(32767*sin(M_PI*ref12_NB_IoT[(u*12) + n]/4)));
}
break;
}
}
}
}*/
void generate_ul_ref_sigs_rx_NB_IoT(void)
{
unsigned int u,index_Nsc_RU,n,m; // Vincent: index_Nsc_RU 0,1,2,3 ---> number of sc 1,3,6,12
//uint8_t npusch_format = 1; // NB-IoT: format 1 (data), or 2: ack. Should be defined in higher layer
int16_t a;
int16_t qpsk[2];
unsigned int x1, x2; // NB-IoT: defined in 36.211, Section 10.1.4.1.1
int16_t ref_sigs_sc1[2*sequence_length[0]]; // this is for format 1
//int16_t ref_sigs_sc1_f2[2*sequence_length[0]]; // this is for format 2
uint32_t s;
a = ONE_OVER_SQRT2_Q15_NB_IoT;
qpsk[0] = a;
qpsk[1] = -a;
//printf("\n\n\n in generate_ul_ref_sigs_rx_NB_IoT %d \n\n\n",a);
for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++)
{
for (u=0; u<u_max[index_Nsc_RU]; u++)
{
// ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc16(2*sizeof(int16_t)*sequence_length[index_Nsc_RU]);
switch (index_Nsc_RU)
{
case 0: // 36.211, Section 10.1.4.1.1
x2=35;
s = lte_gold_generic_NB_IoT(&x1, &x2, 1);
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU] = (int16_t*)malloc(sizeof(int16_t)*(2*sequence_length[index_Nsc_RU]*12+24)); // *12 is mandatory to fit channel estimation functions
ul_ref_sigs_f2_rx_NB_IoT[u] = (int16_t*)malloc(sizeof(int16_t)*(2*12*12+24)); // first "*12" is mandatory to fit channel estimation functions; first "*12" is the length of pilot sequence for format 2
// NB-IoT: for same reason, +24 is added in order to fit the possible subcarrier start shift when index_Nsc_RU = 0, 1, 2 --> see ul_sc_start in channel estimation function
for (n=0; n<sequence_length[index_Nsc_RU]; n++)
{
if (n>0 && n%32==0)
{
s = lte_gold_generic_NB_IoT(&x1, &x2, 0);
}
ref_sigs_sc1[n<<1] = qpsk[(s>>(n%32))&1]*w_n[16*u+n%16];
// ref_sigs_sc1[1+(n<<1)] = qpsk[(s>>n)&1]*w_n[16*u+n%16];
ref_sigs_sc1[1+(n<<1)] = ref_sigs_sc1[n<<1];
}
for (n=0; n<sequence_length[index_Nsc_RU]; n++)
{
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][12*(n<<1)+24] = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, real part
ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU][1+12*(n<<1)+24]= ref_sigs_sc1[1+(n<<1)]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, imaginary part
}
for (n=0; n<4; n++)
{
for (m=0; m<3; m++)
{
ul_ref_sigs_f2_rx_NB_IoT[u][12*((3*n+m)<<1)+24] = ref_sigs_sc1[n<<1]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, real part
ul_ref_sigs_f2_rx_NB_IoT[u][1+12*((3*n+m)<<1)+24] = ref_sigs_sc1[1+(n<<1)]; // ul_ref_sigs_rx_NB_IoT is filled every 12 RE, imaginary part
}
}
break;
}
}
}
}
void free_ul_ref_sigs_NB_IoT(void)
{
unsigned int u,index_Nsc_RU;
for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++) {
for (u=0; u<30; u++) {
if (ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU])
free16(ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU],4*sizeof(int16_t)*sequence_length[index_Nsc_RU]);
}
}
}
// void free_ul_ref_sigs(void)
// {
// unsigned int u,index_Nsc_RU;
// for (index_Nsc_RU=0; index_Nsc_RU<4; index_Nsc_RU++) {
// for (u=0; u<30; u++) {
// if (ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU])
// free16(ul_ref_sigs_rx_NB_IoT[u][index_Nsc_RU],4*sizeof(int16_t)*sequence_length[index_Nsc_RU]);
// }
// }
// }
#ifdef MAIN
main()
{
//generate_ul_ref_sigs();
generate_ul_ref_sigs_rx();
free_ul_ref_sigs();
}
#endif

View File

@@ -0,0 +1,18 @@
/***********************************************************************
**********************************************************************/
/*! \file PHY/LTE_REFSIG/primary_synch_NB_IoT.c
* \Narrowband Primary Synchronisation Signal(NPSS) for NB-IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
// 12x11= 132 RE ( x 2= 264 since Re,Img).
// For the In-band case: the RE dedicated to LTE pilots are supposed to overwrite 16 REs of the NPSS signal.
short primary_synch_NB_IoT[264] = {32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0,32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0,32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0,32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0,-32767,0,31439,9231,21457,24763,4663,-32434,31439,-9232,-13612,-29806,31439,-9232,4663,-32434,21457,24763,31439,9231,-32767,0,0,0,-32767,0,31439,9231,21457,24763,4663,-32434,31439,-9232,-13612,-29806,31439,-9232,4663,-32434,21457,24763,31439,9231,-32767,0,0,0,32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0,32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0,32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0,-32767,0,31439,9231,21457,24763,4663,-32434,31439,-9232,-13612,-29806,31439,-9232,4663,-32434,21457,24763,31439,9231,-32767,0,0,0,32767,0,-31440,-9232,-21458,-24764,-4664,32433,-31440,9231,13611,29805,-31440,9231,-4664,32433,-21458,-24764,-31440,-9232,32767,-1,0,0};

View File

@@ -1,362 +0,0 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.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
*/
/*! \file PHY/LTE_TRANSPORT/proto.h
* \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#ifndef __LTE_TRANSPORT_PROTO_NB_IOT__H__
#define __LTE_TRANSPORT_PROTO_NB_IOT__H__
#include "PHY/defs_L1_NB_IoT.h"
//#include <math.h>
//NPSS
int generate_npss_NB_IoT(int32_t **txdataF,
short amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
unsigned short symbol_offset, // symbol_offset should equal to 3 for NB-IoT
unsigned short slot_offset,
unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
//NSSS
int generate_sss_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint16_t symbol_offset, // symbol_offset = 3 for NB-IoT
uint16_t slot_offset,
unsigned short frame_number, // new attribute (Get value from higher layer), it does not exist for LTE
unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
//*****************Vincent part for Cell ID estimation from NSSS ******************//
int rx_nsss_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int32_t *tot_metric);
int nsss_extract_NB_IoT(PHY_VARS_UE_NB_IoT *ue,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **nsss_ext,
int l);
//NRS
void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
int32_t **txdataF,
int16_t amp,
uint16_t Ntti, // Ntti = 10
unsigned short RB_IoT_ID, // RB reserved for NB-IoT
unsigned short With_NSSS); // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal
//NPBCH
int allocate_npbch_REs_in_RB(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
int16_t amp,
unsigned short id_offset,
uint32_t *re_allocated);
int generate_npbch(NB_IoT_eNB_NPBCH_t *eNB_npbch,
int32_t **txdataF,
int amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t *npbch_pdu,
uint8_t frame_mod64,
unsigned short NB_IoT_RB_ID);
void npbch_scrambling(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t *npbch_e,
uint32_t length);
// Functions below implement 36-211 and 36-212
/*Function to pack the DCI*/
// newly added function for NB-IoT , does not exist for LTE
void add_dci_NB_IoT(DCI_PDU_NB_IoT *DCI_pdu,
void *pdu,
rnti_t rnti,
unsigned char dci_size_bytes,
unsigned char aggregation,
unsigned char dci_size_bits,
unsigned char dci_fmt,
uint8_t npdcch_start_symbol);
/*Use the UL DCI Information to configure PHY and also Pack the DCI*/
int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
DCI_CONTENT *DCI_Content,
uint16_t rnti,
DCI_format_NB_IoT_t dci_format,
uint8_t UE_id,
uint8_t aggregation,
uint8_t npdcch_start_symbol);
/*Use the DL DCI Information to configure PHY and also Pack the DCI*/
int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int frame,
uint8_t subframe,
DCI_CONTENT *DCI_Content,
uint16_t rnti,
DCI_format_NB_IoT_t dci_format,
NB_IoT_eNB_NDLSCH_t *ndlsch,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t aggregation,
uint8_t npdcch_start_symbol);
/*Function for DCI encoding, scrambling, modulation*/
uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t *npdcch,
uint8_t Num_dci,
DCI_ALLOC_NB_IoT_t *dci_alloc,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *fp,
int32_t **txdataF,
uint32_t subframe,
uint8_t npdcch_start_symbol);
/*!
\brief Decoding of PUSCH/ACK/RI/ACK from 36-212.
@param phy_vars_eNB Pointer to eNB top-level descriptor
@param proc Pointer to RXTX proc variables
@param UE_id ID of UE transmitting this PUSCH
@param subframe Index of subframe for PUSCH
@param control_only_flag Receive PUSCH with control information only
@param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
@returns 0 on success
*/
unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
uint8_t UE_id,
uint8_t control_only_flag,
uint8_t Nbundled,
uint8_t llr8_flag);
//NB-IoT version
NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(//unsigned char Kmimo,
//unsigned char Mdlharq,
uint32_t Nsoft,
//unsigned char N_RB_DL,
uint8_t abstraction_flag,
NB_IoT_DL_FRAME_PARMS* frame_parms);
NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t abstraction_flag);
uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe);
/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
@param I_MCS */
//uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS);
unsigned char get_Qm_ul_NB_IoT(unsigned char I_MCS, uint8_t N_sc_RU);
/** \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_NB_IoT(unsigned char *a,
NB_IoT_eNB_DLSCH_t *dlsch,
uint8_t Nsf, // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table)
unsigned int G, // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation)
time_stats_t *rm_stats,
time_stats_t *te_stats,
time_stats_t *i_stats);
void rx_ulsch_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
uint8_t eNB_id, // this is the effective sector id
uint8_t UE_id,
NB_IoT_eNB_NULSCH_t **ulsch,
uint8_t cooperation_flag);
void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
int32_t **rxdataF_ext,
// uint32_t first_rb,
//uint32_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block
uint8_t N_sc_RU, // number of subcarriers in UL
uint32_t I_sc, // subcarrier indication field
uint32_t nb_rb,
uint8_t l,
uint8_t Ns,
NB_IoT_DL_FRAME_PARMS *frame_parms);
void extract_CQI_NB_IoT(void *o,UCI_format_NB_IoT_t uci_format,NB_IoT_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode);
//*****************Vincent part for nprach ******************//
void RX_NPRACH_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_buffer);
uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int16_t *Rx_sub_sampled_buffer,
uint16_t sub_sampling_rate,
uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
uint32_t estimated_TA_coarse,
char coarse);
uint8_t NPRACH_detection_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int16_t *Rx_sub_sampled_buffer, uint16_t sub_sampling_rate, uint32_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES);
int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate);
//************************************************************//
//*****************Vincent part for ULSCH demodulation ******************//
uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc);
void generate_grouphop_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms);
void init_ul_hopping_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms);
void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol,
uint8_t Qm);
void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol);
int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint8_t uint8_t,
int16_t **llrp);
int32_t ulsch_qpsk_llr_NB_IoT(
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint8_t nb_rb,
int16_t **llrp);
void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t UE_id,
uint8_t symbol);
//************************************************************//
//************************************************************//
//*****************Vincent part for DLSCH demodulation ******************//
int rx_npdsch_NB_IoT(PHY_VARS_UE_NB_IoT *ue,
unsigned char eNB_id,
unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
uint32_t frame,
uint8_t subframe,
unsigned char symbol,
unsigned char first_symbol_flag,
unsigned char i_mod,
unsigned char harq_pid);
unsigned short dlsch_extract_rbs_single_NB_IoT(int **rxdataF,
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
unsigned short pmi,
unsigned char *pmi_ext,
unsigned int *rb_alloc,
unsigned char symbol,
unsigned char subframe,
uint32_t frame,
uint32_t high_speed_flag,
NB_IoT_DL_FRAME_PARMS *frame_parms);
void dlsch_channel_level_NB_IoT(int **dl_ch_estimates_ext,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t *avg,
uint8_t symbol,
unsigned short nb_rb);
void dlsch_channel_compensation_NB_IoT(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
int **dl_ch_magb,
int **rxdataF_comp,
int **rho,
NB_IoT_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
uint8_t first_symbol_flag,
unsigned char mod_order,
unsigned short nb_rb,
unsigned char output_shift,
PHY_MEASUREMENTS_NB_IoT *measurements);
int dlsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *dlsch_llr,
uint8_t symbol,
uint8_t first_symbol_flag,
uint16_t nb_rb,
int16_t **llr32p,
uint8_t beamforming_mode);
//************************************************************//
#endif

View File

@@ -31,7 +31,6 @@
*/
#ifndef __TRANSPORT_UE__H__
#define __TRANSPORT_UE__H__
#include "PHY/defs_UE.h"
#include "PHY/impl_defs_lte.h"
#include "../LTE_TRANSPORT/dci.h"
#include "../LTE_TRANSPORT/mdci.h"

View File

@@ -0,0 +1,80 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __LTE_ESTIMATION_DEFS_NB_IOT__H__
#define __LTE_ESTIMATION_DEFS_NB_IOT__H__
#include "PHY/defs_L1_NB_IoT.h"
/*
int lte_est_timing_advance(NB_IoT_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_SRS *lte_eNb_srs,
unsigned int *eNb_id,
unsigned char clear,
unsigned char number_of_cards,
short coef);
*/
////////// Vincent: NB-IoT DL synchronization //////////////////////////////////////////////////
int lte_sync_time_init_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms );
void lte_sync_time_free_NB_IoT(void);
int lte_sync_time_NB_IoT(int **rxdata, ///rx data in time domain
NB_IoT_DL_FRAME_PARMS *frame_parms,
int *eNB_id);
void lte_sync_timefreq_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int band,unsigned int DL_freq);
////////////////////////////////////////////////////////////////////////////////////////////////
int NB_IoT_est_timing_advance_pusch(PHY_VARS_eNB_NB_IoT* phy_vars_eNB,module_id_t UE_id);
////////// Vincent: NB-IoT specific adapted function for channel estimation ////////////////////
/*
int ul_channel_estimation_NB_IoT(PHY_VARS_eNB *eNB,
eNB_rxtx_proc_t *proc,
uint8_t eNB_id,
uint8_t UE_id,
unsigned char l,
unsigned char Ns,
uint8_t N_sc_RU,
uint8_t pilot_pos1,
uint8_t pilot_pos2,
uint8_t cooperation_flag); */
////////////////////////////////////////////////////////////////////////////////////////////////
int16_t lte_ul_freq_offset_estimation_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t *ul_ch_estimates,
uint16_t nb_rb);
void freq_equalization_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int **rxdataF_comp,
int **ul_ch_mag,
int **ul_ch_mag_b,
unsigned char symbol,
unsigned short Msc_RS,
unsigned char Qm);
/** @} */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,481 @@
/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/SIB_NB_IoT.c
* \Fucntions for the generation of SIB information for NB_IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2018
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
//#include "PHY/CODING/defs_NB_IoT.h"
//#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
//#include "PHY/impl_defs_lte_NB_IoT.h"
//#include "PHY/impl_defs_top_NB_IoT.h"
#include "PHY/impl_defs_lte.h"
/////////////////////////////////////////////////////////////////////////////////////////
int generate_SIB1(NB_IoT_eNB_NDLSCH_t *sib1_struct,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID,
uint8_t operation_mode,
uint8_t release_v13_5_0)
{
int done=0;
uint8_t *sib1_pdu = sib1_struct->harq_process->pdu;
uint8_t opr_mode = 3;
if(operation_mode>=2)
{
opr_mode =0;
}
uint8_t tmp =0;
uint8_t rep_val = 0;
uint8_t start_frame = get_start_frame_SIB1_NB_IoT(frame_parms, get_rep_num_SIB1_NB_IoT(sib1_struct->repetition_number_SIB1));
switch( get_rep_num_SIB1_NB_IoT(sib1_struct->repetition_number_SIB1) )
{
case 4:
rep_val = 64;
break;
case 8:
rep_val = 32;
break;
case 16:
rep_val = 16;
break;
default:
printf("Error in SIB1");
}
uint8_t var = 0;
if(start_frame == 1)
{
var =1;
}
if(start_frame>=16)
{
tmp = 1;
}
uint8_t born_inf = 0 + start_frame*tmp;
uint8_t born_sup = 16 + start_frame*tmp;
if((subframe == 4) && (frame%2 == var) && (born_inf<= frame % rep_val) && (frame % rep_val < born_sup ))
{
LOG_D(PHY,"[%3d][%2d] Generating SIB1\n",frame,subframe);
int G = get_G_SIB1_NB_IoT(frame_parms,operation_mode);
if( frame % rep_val == var )
{
dlsch_encoding_NB_IoT(sib1_pdu,
sib1_struct,
8, ///// number_of_subframes_required
G); //// this vallue is fixed, should take into account in future the case of stand-alone & guard-band
dlsch_scrambling_Gen_NB_IoT(frame_parms,
sib1_struct,
8*G,
frame,
subframe*2,
sib1_struct->rnti,
release_v13_5_0,
1);
}
dlsch_modulation_NB_IoT(txdataF,
amp,
frame_parms,
opr_mode, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
sib1_struct,
G, // number of bits per subframe
((frame%16)/2),
4,
RB_IoT_ID);
done =1;
frame_parms->flag_free_sf =1;
}
return(done);
}
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
int generate_SIB23(NB_IoT_eNB_NDLSCH_t *SIB23,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID,
uint8_t release_v13_5_0)
{
int done=0;
if( SIB23->active == 1 )
{
//LOG_I(PHY,"[Frame: %d][Subframe: %d]sent SIB23\n",frame,subframe);
uint8_t *SIB23_pdu = SIB23->harq_process->pdu;
uint32_t rep = SIB23->resource_assignment;
uint8_t eutra_control_region = 3;
uint32_t counter_rep = SIB23->counter_repetition_number;
uint32_t pointer_to_sf = SIB23->pointer_to_subframe; /// to identify wich encoded subframe to transmit
int G = get_G_NB_IoT(frame_parms);
uint8_t Nsf = SIB23->resource_assignment; //value 2 or 8
if(counter_rep == rep)
{
dlsch_encoding_NB_IoT(SIB23_pdu,
SIB23,
Nsf, ///// number_of_subframes_required
G); //// this vallue is fixed, should take into account in future the case of stand-alone & guard-band
dlsch_scrambling_Gen_NB_IoT(frame_parms,
SIB23,
Nsf*G,
frame,
subframe*2,
SIB23->rnti,
release_v13_5_0,
1);
}
dlsch_modulation_NB_IoT(txdataF,
amp,
frame_parms,
eutra_control_region, //should be replace by start_symbole // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
SIB23,
G, // number of bits per subframe
pointer_to_sf,
subframe,
RB_IoT_ID);
SIB23->counter_repetition_number--;
SIB23->pointer_to_subframe++;
frame_parms->flag_free_sf =1;
if(SIB23->counter_repetition_number == 0)
{
SIB23->active = 0;
}
done =1;
}
return(done);
}
////////////////////////////////////////////////////////////////////////
int generate_NDLSCH_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_eNB_NDLSCH_t *RAR,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID,
uint8_t release_v13_5_0)
{
int done = 0;
if( RAR->active == 1 )
{
uint8_t *RAR_pdu = RAR->harq_process->pdu;
if(RAR->active_msg2 == 1 && RAR_pdu!=NULL)
{
uint8_t one_byte = RAR_pdu[2]>>3;
uint8_t subcarrier_spacing = one_byte & 0x01;
eNB->ulsch_NB_IoT[0]->harq_process->subcarrier_spacing = subcarrier_spacing;
}
// make different between RAR data and NPDSCH data // add a flag in NPDSCH to switch between RA and normal data transmission
uint32_t rep = RAR->repetition_number;
uint8_t eutra_control_region = 3;
uint32_t counter_rep = RAR->counter_repetition_number;
uint32_t counter_sf_rep = RAR->counter_current_sf_repetition; /// for identifiying when to trigger new scrambling
uint32_t pointer_to_sf = RAR->pointer_to_subframe; /// to identify wich encoded subframe to transmit
int G = get_G_NB_IoT(frame_parms);
uint8_t Nsf = RAR->number_of_subframes_for_resource_assignment;
//LOG_I(PHY,"[Frame: %d][Subframe: %d]sent RAR, rep : %d, counter_rep:%d, Num_res:%d\n",frame,subframe,rep,counter_rep,Nsf);
if( (counter_rep == rep) && (counter_sf_rep == 0) && (pointer_to_sf == 0) )
{
dlsch_encoding_NB_IoT(RAR_pdu,
RAR,
Nsf, ///// number_of_subframes_required
G); //// this vallue is fixed, should take into account in future the case of stand-alone & guard-band
dlsch_scrambling_Gen_NB_IoT(frame_parms,
RAR,
Nsf*G,
frame,
subframe*2,
RAR->rnti,
release_v13_5_0,
0);
}
if( (counter_rep != rep) && (counter_sf_rep == 0) && (pointer_to_sf == 0) )
{
dlsch_scrambling_Gen_NB_IoT(frame_parms,
RAR,
Nsf*G,
frame,
subframe*2,
RAR->rnti,
release_v13_5_0,
0);
}
if( rep > 4)
{
RAR->counter_current_sf_repetition++;
dlsch_modulation_NB_IoT(txdataF,
amp,
frame_parms,
eutra_control_region, //should be replace by start_symbole // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
RAR,
G, // number of bits per subframe
pointer_to_sf,
subframe,
RB_IoT_ID);
if(RAR->counter_current_sf_repetition == 4)
{
RAR->pointer_to_subframe++;
RAR->counter_current_sf_repetition =0;
if (Nsf == RAR->pointer_to_subframe && (RAR->counter_repetition_number > 4))
{
RAR->counter_repetition_number = RAR->counter_repetition_number-4;
RAR->pointer_to_subframe =0;
RAR->counter_current_sf_repetition =0;
} else {
RAR->active = 0;
RAR->active_msg2 = 0;
done =1;
}
}
} else {
RAR->counter_current_sf_repetition++;
dlsch_modulation_NB_IoT(txdataF,
amp,
frame_parms,
eutra_control_region, //should be replace by start_symbole // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
RAR,
G, // number of bits per subframe
pointer_to_sf,
subframe,
RB_IoT_ID);
if(RAR->counter_current_sf_repetition == rep)
{
RAR->pointer_to_subframe++;
RAR->counter_current_sf_repetition =0;
if (Nsf == RAR->pointer_to_subframe)
{
RAR->active = 0;
RAR->active_msg2 = 0;
done =1;
}
}
}
}
return(done);
}
/////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
int generate_NPDCCH_NB_IoT(NB_IoT_eNB_NPDCCH_t *DCI_1,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID)
{
int done=0;
for(int i=0; i<2; i++)
{
uint8_t ncce_index = 0; /// = DCI->ncce_index[i];
uint8_t agr_level = 2; /// = DCI->aggregation_level[i];
if( DCI_1->active[i] == 1)
{
//LOG_I(PHY,"[Frame: %d][Subframe: %d]sent DCI\n",frame,subframe);
uint8_t *DCI_pdu = DCI_1->pdu[i];
uint32_t rep = DCI_1->dci_repetitions[i]; /// repetition number
uint8_t eutra_control_region = 3;
uint8_t num_bits_of_DCI =DCI_1->A[i]; //DCI->dci_bits_length; /// value to be passed through nfapi when filling the PHY structures
uint32_t counter_rep = DCI_1->counter_repetition_number[i]; ////// Buffer for repetitions
int G = get_G_NB_IoT(frame_parms);
//////////// uint8_t Nsf = DCI->number_of_subframes_for_resource_assignment;
if( counter_rep == rep)
{
dci_encoding_NB_IoT(DCI_pdu, // Array of two DCI pdus, even if one DCI is to transmit , the number of DCI is indicated in dci_number
DCI_1, ////uint8_t *e[2], // *e should be e[2][G]
num_bits_of_DCI, //////A = number of bits of the DCI
G,
ncce_index,
agr_level);
npdcch_scrambling_NB_IoT(frame_parms,
DCI_1, // Input data
G, // Total number of bits to transmit in one subframe(case of DCI = G)
subframe*2, //XXX we pass the subframe // Slot number (0..19)
ncce_index,
agr_level);
}
if( ((counter_rep %4)== 0) && (counter_rep != rep) )
{
npdcch_scrambling_NB_IoT(frame_parms,
DCI_1, // Input data
G, // Total number of bits to transmit in one subframe(case of DCI = G)
subframe*2, //XXX we pass the subframe // Slot number (0..19)
ncce_index,
agr_level);
}
dci_modulation_NB_IoT(txdataF,
amp,
frame_parms,
eutra_control_region, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
DCI_1,
0, // npdsch_data_subframe, // subframe index of the data table of npdsch channel (G*Nsf) , values are between 0..Nsf
agr_level,
ncce_index,
subframe,
RB_IoT_ID);
DCI_1->counter_repetition_number[i]--;
if(DCI_1->counter_repetition_number[i] == 0)
{
//printf("DCI REP done\n");
DCI_1->active[i] = 0;
done =1;
}
}
}
return(done);
}
////////////////////////////////////////////////// backup ///////////////////////////
//////////////////////////////////////////////////// SIB23 ////////////////////////////////////////////////////////////////////////
/* if( (subframe >0) && (subframe !=5) && (With_NSSS == 0) && (frame%2==1) && (frame%64<16) ) ////if((subframe != 0) && (subframe != 4) && (subframe != 9) )
{
if( subframe == 1 )
{
dlsch_encoding_NB_IoT(sib23_pdu,
sib23,
8, ///// number_of_subframes_required
236); //////////// G*2
dlsch_scrambling_Gen_NB_IoT(fp, // is called only in subframe 4
sib23,
1888, ////// total_bits
frame,
subframe*2,
eNB->ndlsch_SIB23->rnti);
}
if( subframe < 5 )
{
dlsch_modulation_NB_IoT(txdataF,
AMP,
fp,
3, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
sib23,
236, // number of bits per subframe
(subframe-1), ///npdsch_data_subframe, data per subframe//subframe index of the data table of npdsch channel (G*Nsf) ((frame%32)/2),values are between 0..Nsf
subframe,
RB_IoT_ID);
} else {
dlsch_modulation_NB_IoT(txdataF,
AMP,
fp,
3, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
sib23,
236, // number of bits per subframe
(subframe-2),///npdsch_data_subframe, data per subframe//subframe index of the data table of npdsch channel (G*Nsf) ((frame%32)/2),values are between 0..Nsf
subframe,
RB_IoT_ID);
}
}
*/

View File

@@ -0,0 +1,504 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/dci_NB_IoT.c
* \brief Implements PDCCH physical channel TX/RX procedures (36.211) and DCI encoding/decoding (36.212/36.213). Current LTE compliance V8.6 2009-03.
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#ifdef USER_MODE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#endif
#include "PHY/defs_common.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "defs_NB_IoT.h"
//#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
#include "PHY/CODING/defs_NB_IoT.h"
#include "PHY/defs_L1_NB_IoT.h" // /LTE_TRANSPORT/defs_NB_IoT.h
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
//#include "PHY/extern.h"
//////////#include "PHY/extern_NB_IoT.h"
//#include "SCHED/defs.h"
/////////////////////////////#include "SCHED/defs_nb_iot.h"
//#include "SIMULATION/TOOLS/defs.h" // for taus
//#include "PHY/sse_intrin.h"
//#include "assertions.h"
//#include "T.h"
/////////////////////////////////////////////////////////////////////
//static uint8_t d[2][3*(MAX_DCI_SIZE_BITS_NB_IoT + 16) + 96];
//static uint8_t w[2][3*3*(MAX_DCI_SIZE_BITS_NB_IoT+16)];
void dci_encoding_NB_IoT(uint8_t *a, // Array of two DCI pdus, even if one DCI is to transmit , the number of DCI is indicated in dci_number
NB_IoT_eNB_NPDCCH_t *dlcch, ////uint8_t *e[2], // *e should be e[2][G]
uint8_t A,
uint16_t G,
uint8_t ncce_index,
uint8_t agr_level) // Aggregation level
{
uint8_t D = (A + 16);
uint32_t RCC;
uint8_t occupation_size=1;
if(agr_level == 2 && ncce_index == 0)
{
occupation_size=1;
}else{
occupation_size=2;
}
memset((void *)dlcch->npdcch_d[ncce_index],LTE_NULL_NB_IoT,96);
ccode_encode_NB_IoT(A,2,a,dlcch->npdcch_d[ncce_index]+96,dlcch->rnti[ncce_index]); // CRC attachement & Tail-biting convolutional coding
RCC = sub_block_interleaving_cc_NB_IoT(D,dlcch->npdcch_d[ncce_index]+96,dlcch->npdcch_w[ncce_index]); // Interleaving
lte_rate_matching_cc_NB_IoT(RCC,(G/occupation_size),dlcch->npdcch_w[ncce_index],dlcch->npdcch_e[ncce_index]); // Rate Matching
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///The scrambling sequence shall be initialised at the start of the search space and after every 4th NPDCCH subframes.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void npdcch_scrambling_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_NPDCCH_t *dlcch, // Input data
int G, // Total number of bits to transmit in one subframe(case of DCI = G)
uint8_t Ns, //XXX we pass the subframe // Slot number (0..19)
uint8_t ncce_index,
uint8_t agr_level) // Aggregation level
{
int i;
uint32_t x1, x2, s=0;
uint8_t reset;
uint8_t occupation_size=1;
reset = 1;
if(agr_level == 2 && ncce_index == 0)
{
occupation_size=1;
}else{
occupation_size=2;
}
x2 = ((Ns>>1)<<9) + frame_parms->Nid_cell; // This is c_init in 36.211 Sec 10.2.3.1
for (i=0; i<G/occupation_size; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic_NB_IoT(&x1, &x2, reset);
reset = 0;
}
dlcch->npdcch_e[ncce_index][i] = (dlcch->npdcch_e[ncce_index][i]&1) ^ ((s>>(i&0x1f))&1);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int dci_allocate_REs_in_RB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
uint8_t pilot_shift,
int16_t amp,
unsigned short id_offset,
uint8_t ncce_index,
uint8_t agr_level,
uint32_t *re_allocated)
{
MIMO_mode_t mimo_mode = (frame_parms->mode1_flag==1)? SISO:ALAMOUTI;
uint32_t tti_offset,aa;
uint8_t re;
int16_t gain_lin_QPSK;
uint8_t first_re,last_re;
int32_t tmp_sample1,tmp_sample2;
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
first_re = 0;
last_re = 12;
if(ncce_index == 0 && agr_level == 2)
{
for (re=first_re; re<last_re; re++) { // re varies between 0 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || (re%6 != ((id_offset + 3*pilot_shift) % 6) ) ) // if re is not a pilot
{
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
} else if(agr_level == 1) {
for (re=(first_re + ncce_index*6); re<(6 + ncce_index*6); re++) { // re varies between 0 and 6 or 6 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || (re%6 != ((id_offset + 3*pilot_shift) % 6) ) ) // if re is not a pilot
{
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
} else {
printf("Error in allocate RE of DCI NB_IoT");
}
return(0);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int dci_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
NB_IoT_eNB_NPDCCH_t *dlcch,
unsigned int npdsch_data_subframe, // subframe index of the data table of npdsch channel (G*Nsf) , values are between 0..Nsf
uint8_t agr_level,
uint8_t ncce_index,
unsigned int subframe,
unsigned short NB_IoT_RB_ID) /// NB_IoT_RB_ID should be initialized in the LTE_DL_FRAME_PARMS
{
uint32_t jj = 0;
uint32_t re_allocated,symbol_offset;
uint16_t l;
uint8_t id_offset,pilot_shift,pilots = 0;
unsigned short bandwidth_even_odd;
unsigned short NB_IoT_start, RB_IoT_ID;
re_allocated = 0;
id_offset = 0;
pilot_shift = 0;
// testing if the total number of RBs is even or odd
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
RB_IoT_ID = NB_IoT_RB_ID;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for (l=control_region_size; l<14; l++) { // loop on OFDM symbols
if((l>=4 && l<=7) || (l>=11 && l<=13))
{
pilots = 1;
if(l==4 || l==6 || l==11 || l==13)
{
pilot_shift = 1;
}
} else {
pilots = 0;
}
id_offset = frame_parms->Nid_cell % 6; // Cell_ID_NB_IoT % 6
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
}
symbol_offset = (14*subframe*frame_parms->ofdm_symbol_size) + frame_parms->ofdm_symbol_size*l + NB_IoT_start; // symbol_offset = 512 * L + NB_IOT_RB start
if(agr_level == 2)
{
dci_allocate_REs_in_RB_NB_IoT(frame_parms,
txdataF,
&jj,
symbol_offset,
&dlcch->npdcch_e[0][MAX_BITS_IN_SF],
pilots,
pilot_shift,
amp,
id_offset,
ncce_index,
agr_level,
&re_allocated);
} else {
dci_allocate_REs_in_RB_NB_IoT(frame_parms,
txdataF,
&jj,
symbol_offset,
&dlcch->npdcch_e[ncce_index][MAX_BITS_IN_SF],
pilots,
pilot_shift,
amp,
id_offset,
ncce_index,
agr_level,
&re_allocated);
}
}
return (re_allocated);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t *npdcch,
uint8_t Num_dci,
DCI_ALLOC_NB_IoT_t *dci_alloc,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *fp,
int32_t **txdataF,
uint32_t subframe,
uint8_t npdcch_start_symbol)
{
int i, G;
//temporary variable
uint16_t rnti[i];
uint8_t L = 0;
/* PARAMETERS may not needed
**e_ptr : store the encoding result, and as a input to modulation
*num_pdcch_symbols : to calculate the resource allocation for pdcch
*L = aggregation level (there is 2 (at most) in NB-IoT) (Note this is not the real value but the index)
*lprime,kprime,kprime_mod12,mprime,nsymb,symbol_offset,tti_offset,re_offset : used in the REG allocation
*gain_lin_QPSK,yseq0[Msymb],yseq1[Msymb],*y[2] : used in the modulation
*mi = used in interleaving
*e = used to store the taus sequence (taus sequence is used to generate the first sequence for DCI) Turbo coding
*wbar used in the interleaving and also REG allocation
*/
// MAC is assumed to have ordered the UE spec DCI according to the RNTI-based randomization???
// Value of aggregation level (FAPI/NFAPI specs v.9.0 pag 221 value 1,2)
/*
* in NB-IoT we can have at most 2 aggregation level since we have only 2 NCCE (Narrowband control channel element)
* if only 1 DCI transmitted:
* - Aggregation level could be 1 or 2
* if 2 DCI transmitted:
* - Aggregation level should be 1
*
*/
//First take all the DCI pdu and their corrispondent rnti
for(i = 0; i<Num_dci;i++)
{
npdcch->pdu[i]= (uint8_t*)dci_alloc[i].dci_pdu;
rnti[i]= dci_alloc[i].rnti;
L = dci_alloc[i].L;
}
if(Num_dci == 2 && L == 1)
LOG_E(PHY,"generate_dci_top_NB_IoT: Aggregation level not compatible with Num_dci\n" );
//Second, evaluate the G variable based of the npdcch_start_sysmbol
/*
* TS 36.213 ch 16.6.1
* npdcch_start_symbol indicate the starting OFDM symbol for NPDCCH in the first slot of a subframe k ad is determined as follow:
* - if eutracontrolregionsize is present (defined for in-band operating mode (mode 0,1 for FAPI specs))
* npdcch_start_symbol = eutracontrolregionsize (value 1,2,3) [units in number of OFDM symbol]
* -otherwise
* npdcch_start_symbol = 0
*
*XXX npdcch_start symbol should be the same for every DCI once is decided since depends on the parameters
*(the setting of this npdcch_start_symbol parameter should be done in the MAC)
*Depending on npdcch_start_symbol then we define different values for G
*
*/
switch(npdcch_start_symbol) //mail Bcom matthieu
{
case 0:
G = 304;
break;
case 1:
G = 240;
break;
case 2:
G = 224;
break;
case 3:
G =200;
break;
default:
LOG_E (PHY,"npdcch_start_symbol has unwanted value\n");
break;
}
//NB-IoT encoding
// dci_encoding_NB_IoT(
// a,
// 4, // total length (in byte) of a [assume max 2 pdus of ??]
// G,
// npdcch->e,
// rnti,
// Num_dci,
// L
// );
//NB-IoT scrambling
// npdcch_scrambling_NB_IoT(
// fp,
// npdcch->e,
// G,
// subframe,
// Num_dci,
// L
// );
//NB-IoT Modulation
// dci_modulation_NB_IoT(
// txdataF,
// amp,
// fp,
// npdcch_start_symbol,
// npdcch->e,
// G,
// Num_dci,
// L
// );
return 0;
}

View File

@@ -3,7 +3,9 @@
* 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
*

View File

@@ -0,0 +1,563 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/dci_tools.c
* \brief PHY Support routines (eNB/UE) for filling PDSCH/PUSCH/DLSCH/ULSCH data structures based on DCI PDUs generated by eNB MAC scheduler.
* \author R. Knopp
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
//#include "PHY/defs.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/extern_NB_IoT.h"
//#include "PHY/LTE_TRANSPORT/extern_NB_IoT.h"
#include "defs_NB_IoT.h"
/*
#ifdef DEBUG_DCI_TOOLS
#include "PHY/vars_NB_IoT.h"
#endif
*/
//#include "assertions.h"
//#include "dlsch_tbs_full.h"
#include "dlsch_tbs_full_NB_IoT.h"
//#define DEBUG_HARQ
//#include "LAYER2/MAC/extern_NB_IoT.h"
//#include "LAYER2/MAC/defs_NB_IoT.h"
#include "PHY/defs_L1_NB_IoT.h"
//#define DEBUG_DCI
void add_dci_NB_IoT(DCI_PDU_NB_IoT *DCI_pdu,void *pdu,rnti_t rnti,unsigned char dci_size_bytes,unsigned char aggregation,unsigned char dci_size_bits,unsigned char dci_fmt, uint8_t npdcch_start_symbol)
{
//put the pdu
memcpy(&DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_pdu[0],pdu,dci_size_bytes);
//configure the dci alloc
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].dci_length = dci_size_bits;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].L = aggregation;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].rnti = rnti;
DCI_pdu->dci_alloc[DCI_pdu->Num_dci].format = dci_fmt;
DCI_pdu->npdcch_start_symbol = npdcch_start_symbol;
DCI_pdu->Num_dci++;
LOG_D(MAC,"add ue specific dci format %d for rnti %x \n",dci_fmt,rnti);
}
//map the Isf (DCI param) to the number of subframes (Nsf)
int resource_to_subframe[8] = {1,2,3,4,5,6,8,10};
int Scheddly_less_128[8] = {0,4,8,12,16,32,64,128};
int Scheddly_bigger_128[8] = {0,16,32,64,128,256,512,1024};
int Irep_to_Nrep[16] = {1,2,4,8,16,32,64,128,192,256,384,512,768,1024,1536,2048};
int Idelay_to_K0(uint8_t Sched_delay, int Rmax)
{
int k0=0;
if(Rmax <128)
{
k0 = Scheddly_less_128[Sched_delay];
}else if(Rmax >=128)
{
k0 = Scheddly_bigger_128[Sched_delay];
}
return k0;
}
int DCIrep_to_real_rep(uint8_t DCI_rep, int Rmax)
{
int R=0;
if(Rmax == 1)
{
if(DCI_rep == 0)
R = 1;
}else if (Rmax == 2)
{
if(DCI_rep == 0)
R = 1;
else if(DCI_rep == 1)
R = 2;
}else if (Rmax == 4)
{
if(DCI_rep == 0)
R = 1;
else if(DCI_rep == 1)
R = 2;
else if(DCI_rep == 2)
R = 4;
}else if (Rmax >= 8)
{
if(DCI_rep == 0)
R = Rmax/8;
else if(DCI_rep == 1)
R = Rmax/4;
else if(DCI_rep == 2)
R = Rmax/2;
else if(DCI_rep == 3)
R = Rmax;
}
return R;
}
int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int frame,
uint8_t subframe,
DCI_CONTENT *DCI_Content,
uint16_t rnti,
NB_IoT_eNB_NPDCCH_t *ndlcch,
uint8_t aggregation,
uint8_t npdcch_start_symbol,
uint8_t ncce_index)
{
int tmp = 0;
int i = 0;
uint8_t *DCI_flip = NULL;
ncce_index = 0;
/// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
uint8_t type;
/// Subcarrier indication, 6 bits
uint8_t scind;
/// Resourse Assignment (RU Assignment), 3 bits
uint8_t ResAssign;
/// Modulation and Coding Scheme, 4 bits
uint8_t mcs;
/// New Data Indicator, 1 bits
uint8_t ndi;
/// Scheduling Delay, 2 bits
uint8_t Scheddly;
/// Repetition Number, 3 bits
uint8_t RepNum;
/// Redundancy version for HARQ (only use 0 and 2), 1 bits
uint8_t rv;
/// DCI subframe repetition Number, 2 bits
uint8_t DCIRep;
type = DCI_Content->DCIN0.type;
scind = DCI_Content->DCIN0.scind;
ResAssign = DCI_Content->DCIN0.ResAssign;
mcs = DCI_Content->DCIN0.mcs;
ndi = DCI_Content->DCIN0.ndi;
Scheddly = DCI_Content->DCIN0.Scheddly;
RepNum = DCI_Content->DCIN0.RepNum;
rv = DCI_Content->DCIN0.rv;
DCIRep = DCI_Content->DCIN0.DCIRep;
/*Now configure the npdcch structure*/
// ndlcch->ncce_index = NCCE_index;
// ndlcch->aggregation_level = aggregation;
ndlcch->A[ncce_index] = sizeof_DCIN0_t; // number of bits in DCI
ndlcch->rnti[ncce_index] = rnti; //we store the RNTI (e.g. for RNTI will be used later)
ndlcch->active[ncce_index] = 1; //will be activated by the corresponding NDSLCH pdu
ndlcch->dci_repetitions[ncce_index] = DCIrep_to_real_rep(DCIRep,16); ////??????? should be repalce by the value in spec table 16.6-3, check also Rmax
printf("dci_repetitions: %d, A = %d\n",ndlcch->dci_repetitions[ncce_index],ndlcch->A[ncce_index]);
DCI_flip = (uint8_t*)malloc(3*sizeof(uint8_t));
for(i=0; i<3; ++i){
DCI_flip[i] = 0x0;
}
DCI_flip[0] = (type << 7) | (scind << 1) | (ResAssign>>2);
DCI_flip[1] = (uint8_t)(ResAssign << 6) | (Scheddly << 4) | mcs;
DCI_flip[2] = (rv << 7) | (RepNum << 4) | (ndi << 3) |(DCIRep <<1);
ndlcch->pdu[ncce_index] = DCI_flip;
printf("DCI N0 content:");
for (tmp =0;tmp<3;tmp++)
printf("%d ",DCI_flip[tmp]);
printf("\n");
/*
* TS 36.213 ch 16.4.1.5
* ITBS is always set equivalent to IMCS for data
* ISF = ResAssign
*/
ndlcch->counter_repetition_number[ncce_index] = DCIrep_to_real_rep(DCIRep,16); ////??????? should be repalce by the value in spec table 16.6-3, check also Rmax
LOG_I(PHY,"DCI packing for N0 done \n");
}
int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int frame,
uint8_t subframe,
DCI_CONTENT *DCI_Content,
uint16_t rnti,
DCI_format_NB_IoT_t dci_format,
NB_IoT_eNB_NPDCCH_t *ndlcch,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t aggregation, //////????? maybe add the ncce index ??????????
uint8_t npdcch_start_symbol,
uint8_t ncce_index)
{
// NB_IoT_eNB_NPDCCH_t *ndlcch = ;
int tmp = 0;
int i = 0;
uint8_t *DCI_flip = NULL;
//N1 parameters
//uint8_t ncce_index = 0;
/// type = 0 => DCI Format N0, type = 1 => DCI Format N1, 1 bits
uint8_t type = 0;
//NPDCCH order indicator (set to 0),1 bits
uint8_t orderIndicator = 0;
// Scheduling Delay, 3 bits
uint8_t Sched_delay = 0;
// Resourse Assignment (RU Assignment), 3 bits
uint8_t ResAssign = 0;//Isf
// Modulation and Coding Scheme, 4 bits
uint8_t mcs = 0;
// Repetition Number, 4 bits
uint8_t RepNum = 0;
// DCI subframe repetition Number, 2 bits
uint8_t DCIRep = 0;
// New Data Indicator,1 bits
uint8_t ndi = 0;
// HARQ-ACK resource,4 bits
uint8_t HARQackRes = 0;
//N2 parameters
//Direct indication information, 8 bits
uint8_t directIndInf= 0;
// Reserved information bits, 6 bits
uint8_t resInfoBits =0;
// printf("Generate eNB DCI, format %d, rnti %x (pdu %p)\n",dci_format,rnti,dci_pdu);
switch (dci_format) {
// Impossible to have a DCI N0, we have condition before
case DCIFormatN0:
return(-1);
break;
case DCIFormatN1_RAR: // This is DLSCH allocation for control traffic (no NDI and no ACK/NACK resource for RAR DCI)
/*Packed DCI here-------------------------------------------*/
type = DCI_Content->DCIN1_RAR.type;
orderIndicator = DCI_Content->DCIN1_RAR.orderIndicator;
Sched_delay = DCI_Content->DCIN1_RAR.Scheddly;
ResAssign = DCI_Content->DCIN1_RAR.ResAssign;
mcs = DCI_Content->DCIN1_RAR.mcs;
RepNum = DCI_Content->DCIN1_RAR.RepNum;
ndi = DCI_Content->DCIN1_RAR.ndi;
HARQackRes = DCI_Content->DCIN1_RAR.HARQackRes;
DCIRep = DCI_Content->DCIN1_RAR.DCIRep;
/*Now configure the npdcch structure*/
// ndlcch->ncce_index = NCCE_index;
// ndlcch->aggregation_level = aggregation;
ndlcch->A[ncce_index] = sizeof_DCIN1_RAR_t; // number of bits in DCI
//ndlcch->subframe_tx[subframe] = 1; // check if it's OK
ndlcch->rnti[ncce_index] = rnti; //we store the RNTI (e.g. for RNTI will be used later)
ndlcch->active[ncce_index] = 1; //will be activated by the corresponding NDSLCH pdu
// use this value to configure PHY both harq_processes and resource mapping.
ndlcch->scheduling_delay[ncce_index] = Idelay_to_K0(Sched_delay,4);
ndlcch->resource_assignment[ncce_index] = resource_to_subframe[ResAssign]; //from Isf of DCI to the number of subframe
ndlcch->repetition_number[ncce_index] = Irep_to_Nrep[RepNum]; // repetition number for NPDSCH
ndlcch->dci_repetitions[ncce_index] = DCIrep_to_real_rep(DCIRep,4); ////??????? should be repalce by the value in spec table 16.6-3, check also Rmax
//printf("dci_repetitions: %d, A = %d\n",ndlcch->dci_repetitions[ncce_index],ndlcch->A[ncce_index]);
ndlcch->modulation[ncce_index] = 2; //QPSK
//// ////////////////////////////////////////////////if(ndlcch->round == 0) //this should be set from initialization (init-lte)
//ndlcch->status[ncce_index] = ACTIVE_NB_IoT;
ndlcch->mcs[ncce_index] = mcs;
DCI_flip = (uint8_t*)malloc(3*sizeof(uint8_t));
for(i=0; i<3; ++i){
DCI_flip[i] = 0x0;
}
DCI_flip[0] = (type << 7) | (orderIndicator << 6) | (Sched_delay<<2) | ResAssign ;
DCI_flip[1] = (mcs << 4) | RepNum;
DCI_flip[2] = (ndi << 7) | (HARQackRes << 3) | (DCIRep <<1);
ndlcch->pdu[ncce_index] = DCI_flip;
printf("DCI N1 RAR PDU content:");
for (tmp =0;tmp<3;tmp++)
printf("%d ",DCI_flip[tmp]);
printf("\n");
/*
* TS 36.213 ch 16.4.1.5
* ITBS is always set equivalent to IMCS for data
* ISF = ResAssign
*/
ndlcch->TBS[ncce_index] = TBStable_NB_IoT[mcs][ResAssign];
//ndlcch->subframe[ncce_index] = subframe;
ndlcch->counter_repetition_number[ncce_index] = DCIrep_to_real_rep(DCIRep,4); ////??????? should be repalce by the value in spec table 16.6-3, check also Rmax
//ndlsch_harq->B; we don-t have now my is given when we receive the dlsch data
//ndlsch->error_treshold
//ndlsch->G??
//ndlsc->nsoft?? //set in new_eNB_dlsch (initialization)
//ndlsch-> sqrt_rho_a?? set in dlsch_modulation
//ndlsch-> sqrt_rho_b??? set in dlsch_modulation
LOG_I(PHY,"DCI packing for N1RAR done \n");
//set in new_eNB_dlsch (initialization)
/*
* Mlimit
* nsoft
* round
*/
break;
case DCIFormatN1: // for user data
type = DCI_Content->DCIN1.type;
orderIndicator = DCI_Content->DCIN1.orderIndicator;
Sched_delay = DCI_Content->DCIN1.Scheddly;
ResAssign = DCI_Content->DCIN1.ResAssign;
mcs = DCI_Content->DCIN1.mcs;
RepNum = DCI_Content->DCIN1.RepNum;
ndi = DCI_Content->DCIN1.ndi;
HARQackRes = DCI_Content->DCIN1.HARQackRes;
DCIRep = DCI_Content->DCIN1.DCIRep;
//add_dci_NB_IoT(eNB->DCI_pdu,DLSCH_DCI_NB_IoT,rnti,sizeof(DCIN1_t),aggregation,sizeof_DCIN1_t,DCIFormatN1,npdcch_start_symbol);
/*Now configure the npdcch structure*/
ndlcch->A[ncce_index] = sizeof_DCIN1_t; // number of bits in DCI
// ndlcch->ncce_index = NCCE_index;
// ndlcch->aggregation_level = aggregation;
//ndlcch->subframe_tx[subframe] = 1; // check if it's OK
ndlcch->rnti[ncce_index] = rnti; //we store the RNTI (e.g. for RNTI will be used later)
ndlcch->active[ncce_index] = 1;//will be activated by the corresponding NDSLCH pdu
// use this value to configure PHY both harq_processes and resource mapping.
ndlcch->scheduling_delay[ncce_index] = Idelay_to_K0(Sched_delay,4);
ndlcch->resource_assignment[ncce_index] = resource_to_subframe[ResAssign]; //from Isf of DCI to the number of subframe
ndlcch->repetition_number[ncce_index] = Irep_to_Nrep[RepNum]; // repetition number for NPDSCH
ndlcch->dci_repetitions[ncce_index] = DCIrep_to_real_rep(DCIRep,4); ////??????? should be repalce by the value in spec table 16.6-3, check also Rmax
ndlcch->modulation[ncce_index] = 2; //QPSK
//if(ndlcch->round == 0){ //this should be set from initialization (init-lte)
//ndlcch->status[ncce_index] = ACTIVE_NB_IoT;
ndlcch->mcs[ncce_index] = mcs;
ndlcch->TBS[ncce_index] = TBStable_NB_IoT[mcs][ResAssign]; // this table should be rewritten for nb-iot
//ndlcch->pdu[ncce_index] = DLSCH_DCI_NB_IoT;
DCI_flip = (uint8_t*)malloc(3*sizeof(uint8_t));
for(i=0; i<3; ++i){
DCI_flip[i] = 0x0;
}
DCI_flip[0] = (type << 7) | (orderIndicator << 6) | (Sched_delay<<2) | ResAssign ;
DCI_flip[1] = (mcs << 4) | RepNum;
DCI_flip[2] = (ndi << 7) | (HARQackRes << 3) | (DCIRep <<1);
//DCI_flip[0] = 129;
//DCI_flip[0] = DCI_tmp[2]*2;
//DCI_flip[1] = DCI_tmp[1]*2;
//DCI_flip[2] = DCI_tmp[0]*2;
//DCI_flip[2] = 4;
ndlcch->pdu[ncce_index] = DCI_flip;
printf("DCI N1 PDU content:");
for (tmp =0;tmp<3;tmp++)
printf("%d ",DCI_flip[tmp]);
printf("\n");
ndlcch->counter_repetition_number[ncce_index] = DCIrep_to_real_rep(DCIRep,4); ////??????? should be repalce by the value in spec table 16.6-3, check also Rmax
//}
//ndlcch->frame[ncce_index] = frame;
//ndlcch->subframe[ncce_index] = subframe;
break;
case DCIFormatN2_Ind: //MP: for the moment is not implemented
type = DCI_Content->DCIN2_Ind.type;
directIndInf = DCI_Content->DCIN2_Ind.directIndInf;
resInfoBits = DCI_Content->DCIN2_Ind.resInfoBits;
//add_dci_NB_IoT(eNB->DCI_pdu,DLSCH_DCI_NB_IoT,rnti,sizeof(DCIN2_Ind_t),aggregation,sizeof_DCIN2_Ind_t,DCIFormatN2_Ind,npdcch_start_symbol);
// use this value to configure PHY both harq_processes and resource mapping.
break;
case DCIFormatN2_Pag: //MP: for the moment is not implemented
type = DCI_Content->DCIN2_Pag.type;
ResAssign = DCI_Content->DCIN2_Pag.ResAssign;
mcs = DCI_Content->DCIN2_Pag.mcs;
RepNum = DCI_Content->DCIN2_Pag.RepNum;
DCIRep = DCI_Content->DCIN2_Pag.DCIRep;
//add_dci_NB_IoT(eNB->DCI_pdu,DLSCH_DCI_NB_IoT,rnti,sizeof(DCIN2_Pag_t),aggregation,sizeof_DCIN2_Pag_t,DCIFormatN2_Pag,npdcch_start_symbol);
// use this value to configure PHY both harq_processes and resource mapping.
break;
default:
LOG_E(PHY,"Unknown DCI format\n");
return(-1);
break;
}
// compute DL power control parameters
//free(DLSCH_DCI_NB_IoT);
return(0);
}
uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe)
{
//MAC_xface_NB_IoT *mac_xface_NB_IoT; //test_xface
/*
#ifdef DEBUG_DCI
if (frame_parms->frame_type == TDD)
printf("dci_tools.c: subframe2_harq_pid, subframe %d for TDD configuration %d\n",subframe,frame_parms->tdd_config);
else
printf("dci_tools.c: subframe2_harq_pid, subframe %d for FDD \n",subframe);
#endif
*/
uint8_t ret = 255;
if (frame_parms->frame_type == FDD_NB_IoT) {
ret = (((frame<<1)+subframe)&7);
} else {
switch (frame_parms->tdd_config) {
case 1:
if ((subframe==2) ||
(subframe==3) ||
(subframe==7) ||
(subframe==8))
switch (subframe) {
case 2:
case 3:
ret = (subframe-2);
break;
case 7:
case 8:
ret = (subframe-5);
break;
default:
LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
ret = (255);
break;
}
break;
case 2:
if ((subframe!=2) && (subframe!=7)) {
LOG_E(PHY,"subframe2_harq_pid, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
//mac_xface_NB_IoT->macphy_exit("subframe2_harq_pid_NB_IoT, Illegal subframe");
ret = (255);
}
ret = (subframe/7);
break;
case 3:
if ((subframe<2) || (subframe>4)) {
LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
ret = (255);
}
ret = (subframe-2);
break;
case 4:
if ((subframe<2) || (subframe>3)) {
LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
ret = (255);
}
ret = (subframe-2);
break;
case 5:
if (subframe!=2) {
LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Illegal subframe %d for TDD mode %d\n",subframe,frame_parms->tdd_config);
ret = (255);
}
ret = (subframe-2);
break;
default:
LOG_E(PHY,"subframe2_harq_pid_NB_IoT, Unsupported TDD mode %d\n",frame_parms->tdd_config);
ret = (255);
}
}
if (ret == 255) {
LOG_E(PHY, "invalid harq_pid(%d) at SFN/SF = %d/%d\n", ret, frame, subframe);
//mac_xface_NB_IoT->macphy_exit("invalid harq_pid");
}
return ret;
}

View File

@@ -15,11 +15,11 @@
#define __LTE_TRANSPORT_DEFS_NB_IOT__H__
////#include "PHY/defs.h"
//#include "PHY/defs_nb_iot.h"
#include "PHY/LTE_TRANSPORT/dci_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/dci_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "openair2/COMMON/platform_types.h"
//#include "dci.h"
#include "PHY/LTE_TRANSPORT/uci_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/uci_NB_IoT.h"
//#include "dci.h"
//#include "uci.h"
//#ifndef STANDALONE_COMPILE
@@ -41,7 +41,13 @@
//// maximum of 3 segments before each coding block if data length exceeds 6144 bits.
//
#define MAX_NUM_DLSCH_SEGMENTS_NB_IoT 16
#define MAX_NUM_ULSCH_SEGMENTS_NB_IoT MAX_NUM_DLSCH_SEGMENTS_NB_IoT
#define MAX_NUM_BITS_IN_DL_PER_SF_NB_IoT 284 // case one NB-IoT antenna && one LTE antenna
//#define MAX_NUM_ULSCH_SEGMENTS MAX_NUM_DLSCH_SEGMENTS
//#define MAX_DLSCH_PAYLOAD_BYTES (MAX_NUM_DLSCH_SEGMENTS*768)
//#define MAX_ULSCH_PAYLOAD_BYTES (MAX_NUM_ULSCH_SEGMENTS*768)
//
@@ -71,11 +77,17 @@
//
//// for NB-IoT
#define MAX_NUM_CHANNEL_BITS_NB_IoT 3360 //14 symbols * 12 sub-carriers * 10 SF * 2bits/RE // to check during real tests
#define MAX_DL_SIZE_BITS_NB_IoT 680 // in release 13 // in release 14 = 2048 // ??? **** not sure
#define MAX_NUM_DL_CHANNEL_BITS_NB_IoT 2840 //284* 10 SF // case In-band operation mode witn 1 NB-IoT antenna && 1 LTE antenna //
#define MAX_TBS_DL_SIZE_BITS_NB_IoT 680 // in release 13 // in release 14 = 2048 // ??? **** not sure
////#define MAX_NUM_CHANNEL_BITS_NB_IOT 3*680 /// ??? ****not sure
//
//// to be created LTE_eNB_DLSCH_t --> is duplicated for each number of UE and then indexed in the table
//
//typedef struct { // LTE_DL_eNB_HARQ_t
// /// Status Flag indicating for this DLSCH (idle,active,disabled)
// SCH_status_t status;
@@ -135,6 +147,7 @@
// uint8_t first_layer;
//} NB_IoT_DL_eNB_HARQ_t;
typedef enum {
SCH_IDLE_NB_IoT,
@@ -161,15 +174,16 @@ typedef struct {
/// modulation always QPSK Qm = 2
uint8_t modulation;
/// Concatenated "e"-sequences (for definition see 36-212 V8.6 2009-03, p.17-18)
uint8_t e[MAX_NUM_CHANNEL_BITS_NB_IoT];
uint8_t e[MAX_NUM_DL_CHANNEL_BITS_NB_IoT];
/// data after scrambling
uint8_t s_e[MAX_NUM_CHANNEL_BITS_NB_IoT];
uint8_t s_e[MAX_NUM_DL_CHANNEL_BITS_NB_IoT];
//length of the table e
uint16_t length_e; // new parameter
/// Tail-biting convolutional coding outputs
uint8_t d[96+(3*(24+MAX_DL_SIZE_BITS_NB_IoT))]; // new parameter
uint8_t d[96+(3*(24+MAX_TBS_DL_SIZE_BITS_NB_IoT))]; // new parameter
/// Sub-block interleaver outputs
uint8_t w[3*3*(MAX_DL_SIZE_BITS_NB_IoT+24)]; // new parameter
uint8_t w[3*3*(MAX_TBS_DL_SIZE_BITS_NB_IoT+24)]; // new parameter
/// Status Flag indicating for this DLSCH (idle,active,disabled)
//SCH_status_t status;
@@ -197,6 +211,7 @@ typedef struct {
} NB_IoT_DL_eNB_HARQ_t;
typedef struct { // LTE_eNB_DLSCH_t
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
uint32_t *txdataF[8];
@@ -217,7 +232,7 @@ typedef struct { // LTE_eNB_DLSCH_t
/// First-round error threshold for fine-grain rate adaptation
uint8_t error_threshold;
/// Pointers to 8 HARQ processes for the DLSCH
NB_IoT_DL_eNB_HARQ_t harq_process;
NB_IoT_DL_eNB_HARQ_t *harq_process;
/// circular list of free harq PIDs (the oldest come first)
/// (10 is arbitrary value, must be > to max number of DL HARQ processes in LTE)
int harq_pid_freelist[10];
@@ -245,6 +260,7 @@ typedef struct { // LTE_eNB_DLSCH_t
} NB_IoT_eNB_DLSCH_t;
typedef struct {
/// HARQ process id
uint8_t harq_id;
@@ -434,7 +450,7 @@ typedef struct {
/// HARQ-ACKs
harq_status_NB_IoT_t harq_ack;
/// Pointers to up to 8 HARQ processes
NB_IoT_DL_UE_HARQ_t *harq_process;
NB_IoT_DL_UE_HARQ_t *harq_processes[8];
/// Maximum number of HARQ processes(for definition see 36-212 V8.6 2009-03, p.17
uint8_t Mdlharq;
/// MIMO transmission mode indicator for this sub-frame (for definition see 36-212 V8.6 2009-03, p.17)
@@ -467,26 +483,6 @@ typedef enum
typedef struct {
rnti_t rnti;
//array containing the pdus of DCI
uint8_t *a[2];
//Array containing encoded DCI data
uint8_t *e[2];
//UE specific parameters
uint16_t npdcch_NumRepetitions;
uint16_t repetition_number;
//indicate the corresponding subframe within the repetition (set to 0 when a new NPDCCH pdu is received)
uint16_t repetition_idx;
// uint16_t npdcch_Offset_USS;
// uint16_t npdcch_StartSF_USS;
}NB_IoT_eNB_NPDCCH_t;
typedef struct{
@@ -526,6 +522,8 @@ typedef struct {
///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDCCH transmission
/// see FAPI/NFAPI specs Table 4-45
uint8_t npdcch_start_symbol;
uint8_t Num_ue_spec_dci;
uint8_t Num_common_dci;
uint8_t Num_dci;
DCI_ALLOC_NB_IoT_t dci_alloc[2] ;
@@ -533,33 +531,45 @@ typedef struct {
typedef struct {
/// TX buffers for UE-spec transmission (antenna ports 5 or 7..14, prior to precoding)
int32_t *txdataF[8];
/// dl channel estimates (estimated from ul channel estimates)
int32_t **calib_dl_ch_estimates;
/// Allocated RNTI (0 means DLSCH_t is not currently used)
uint16_t rnti;
uint32_t rnti;
/// Active flag for baseband transmitter processing
uint8_t active;
/// Active flag when msg2 is transmitted
uint8_t active_msg2;
/// Indicator of TX activation per subframe. Used during PUCCH detection for ACK/NAK.
uint8_t subframe_tx[10];
/// First CCE of last PDSCH scheduling per subframe. Again used during PUCCH detection for ACK/NAK.
uint8_t nCCE[10];
/*in NB-IoT there is only 1 HARQ process for each UE therefore no pid is required*/
///in NB-IoT there is only 1 HARQ process for each UE therefore no pid is required///
/// The only HARQ process for the DLSCH
NB_IoT_DL_eNB_HARQ_t *harq_processes[8];
NB_IoT_DL_eNB_HARQ_t *harq_process;
/// Number of soft channel bits
// NB_IoT_DL_eNB_SIB1_t harq_process_sib1;
SCH_status_NB_IoT_t status;
///////////////////////////////////
uint32_t rnti_type;
uint32_t resource_assignment; // for NDLSCH // this value point to --> number of subframes needed
uint32_t repetition_number;
uint32_t modulation;
uint32_t number_of_subframes_for_resource_assignment; // for NDLSCH //table 16.4.1.3-1 // TS 36.213
uint32_t counter_repetition_number;
uint32_t counter_current_sf_repetition;
uint32_t pointer_to_subframe;
///////////////////////////////////
uint32_t repetition_number_SIB1; //4 8 16
uint32_t resource_assignment_SIB1; // always 8
/// Number of soft channel bits
uint32_t G;
/// Maximum number of HARQ rounds
uint8_t Mlimit;
/// Nsoft parameter related to UE Category
uint32_t Nsoft;
/// amplitude of PDSCH (compared to RS) in symbols without pilots
int16_t sqrt_rho_a;
/// amplitude of PDSCH (compared to RS) in symbols containing pilots
int16_t sqrt_rho_b;
///NB-IoT
/// may use in the npdsch_procedures
uint16_t scrambling_sequence_intialization;
@@ -571,7 +581,10 @@ typedef struct {
///indicates the starting OFDM symbol in the first slot of a subframe k for the NPDSCH transmission
/// see FAPI/NFAPI specs Table 4-47
uint8_t npdsch_start_symbol;
/*SIB1-NB related parameters*/
///SIB1-NB related parameters//
///flag for indicate if the current frame is the start of a new SIB1-NB repetition within the SIB1-NB period (0 = FALSE, 1 = TRUE)
uint8_t sib1_rep_start;
///the number of the frame within the 16 continuous frame in which sib1-NB is transmitted (1-8 = 1st, 2nd ecc..) (0 = not foresees a transmission)
@@ -580,6 +593,9 @@ typedef struct {
//(used inside the ndlsch procedure for distinguish the different type of data to manage also in term of repetitions and transmission over more subframes
ndlsch_flag_t ndlsch_type;
/// Maximum number of HARQ rounds
uint8_t Mlimit;
} NB_IoT_eNB_NDLSCH_t;
typedef struct {
@@ -605,6 +621,12 @@ typedef struct {
uint16_t first_rb;
/// Current Number of RBs
uint16_t nb_rb;
uint8_t new_data_indication;
/// Determined the subcarrier spacing for NPUSCH (15 kHz or 3.75 KHz)
uint8_t subcarrier_spacing; /////////////////////////TODO: to be set using msg2 PDU content
/// Determined the subcarrier allocation for the NPUSCH.(15, 3.75 KHz)
uint8_t subcarrier_indication;
/// Determined the number of resource unit for the NPUSCH
@@ -613,6 +635,10 @@ typedef struct {
uint8_t scheduling_delay;
/// The number of the repetition number for NPUSCH Transport block
uint8_t repetition_number;
////////// counter for repetitions ///////////////////////
uint8_t rep_tmp;
/// Determined the repetition number value 0-3
uint8_t dci_subframe_repetitions;
/// Flag indicating that this ULSCH has been allocated by a DCI (otherwise it is a retransmission based on PHICH NAK)
@@ -648,6 +674,12 @@ typedef struct {
int8_t o_w[(MAX_CQI_BITS_NB_IoT+8)*3];
/// coded CQI bits
int8_t o_d[96+((MAX_CQI_BITS_NB_IoT+8)*3)];
/// soft bits for each received segment ("w"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
int16_t w[MAX_NUM_ULSCH_SEGMENTS_NB_IoT][3*(6144+64)];
/// soft bits for each received segment ("d"-sequence)(for definition see 36-212 V8.6 2009-03, p.15)
int16_t *d[MAX_NUM_ULSCH_SEGMENTS_NB_IoT];
///
uint32_t C;
/// Number of "small" code segments (for definition see 36-212 V8.6 2009-03, p.10)
@@ -666,6 +698,12 @@ typedef struct {
uint8_t srs_active;
/// Pointer to the payload
uint8_t *b;
/// Pointers to transport block segments
uint8_t *c[MAX_NUM_ULSCH_SEGMENTS_NB_IoT];
/// RTC values for each segment (for definition see 36-212 V8.6 2009-03, p.15)
uint32_t RTC[MAX_NUM_ULSCH_SEGMENTS_NB_IoT];
/// Current Number of Symbols
uint8_t Nsymb_pusch;
/// Index of current HARQ round for this ULSCH
@@ -704,11 +742,23 @@ typedef struct {
uint16_t I_sc;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// First Allocated RB - previous scheduling
/// This is needed for PHICH generation which
/// is done after a new scheduling
uint16_t previous_first_rb;
/// Subframe cba scheduling indicator (i.e. CBA Transmission opportunity indicator)
uint8_t subframe_cba_scheduling_flag;
} NB_IoT_UL_eNB_HARQ_t;
typedef struct {
/// Pointers to the HARQ processes for the NULSCH
NB_IoT_UL_eNB_HARQ_t *harq_processes[8];
NB_IoT_UL_eNB_HARQ_t *harq_process;
/// Maximum number of HARQ rounds
uint8_t Mlimit;
@@ -719,7 +769,9 @@ typedef struct {
/// Flag to indicate that eNB should decode UE Msg3
uint8_t Msg3_flag;
/// Subframe for Msg3
uint8_t Msg3_subframe;
uint32_t Msg3_subframe;
/// Frame for Msg3
uint32_t Msg3_frame;
/// RNTI attributed to this ULSCH
@@ -734,12 +786,21 @@ typedef struct {
uint8_t scrambling_re_intialization_batch_index;
/// number of cell specific TX antenna ports assumed by the UE
uint8_t nrs_antenna_ports;
///
uint16_t scrambling_sequence_intialization;
///
uint16_t sf_index;
//////// nfapi param //////////////////////////////////////////
uint16_t C_init;
//////// nfapi param //////////////////////////////////////////////////
uint16_t SF_idx;
/// Determined the ACK/NACK delay and the subcarrier allocation TS 36.213 Table 16.4.2
uint8_t HARQ_ACK_resource;
//////////////////////////////////////////////////////////////////
/// Flag to trigger the storage of values
uint8_t flag_vars;
uint16_t counter_sf;
uint16_t counter_repetitions;
// uint16_t sf_number;
// uint16_t rep_number;
///////////// kept from LTE ///////////////////////////////////////////////////
@@ -784,4 +845,58 @@ typedef struct {
} NB_IoT_eNB_NPBCH_t;
#define NPDCCH_A 23
#define MAX_BITS_IN_SF 284 // maximum number of bits over one subframe
typedef struct {
//the 2 LSB of the hsfn (the MSB are indicated by the SIB1-NB)
rnti_t rnti[2];
////////////////////////////////////////////////////////
/// Active flag for baseband transmitter processing
uint8_t A[2]; // DCI length in bits
uint8_t active[2];
uint8_t modulation[2];
uint32_t length[2];
uint32_t ncce_index[2];
uint32_t aggregation_level[2];
uint32_t rnti_type[2];
uint32_t dci_format[2];
uint32_t scheduling_delay[2];
uint32_t resource_assignment[2];
// uint32_t repetition_number[2];
uint32_t mcs[2];
uint32_t TBS[2];
uint32_t new_data_indicator[2];
uint32_t harq_ack_resource[2];
uint32_t npdcch_order_indication[2];
uint32_t dci_subframe_repetition_number[2];
////////////////////////////////////////////////////////
//UE specific parameters
uint16_t dci_repetitions[2];
uint16_t npdcch_NumRepetitions[2];
uint16_t repetition_number[2];
//indicate the corresponding subframe within the repetition (set to 0 when a new NPDCCH pdu is received)
uint16_t repetition_idx[2];
//////////////////////////////////////
uint32_t counter_repetition_number[2];
// uint32_t counter_current_sf_repetition[2];
// uint32_t pointer_to_subframe[2];
//////////////////////////////////////
uint16_t h_sfn_lsb;
uint8_t npdcch_d[2][96+(3*(16+NPDCCH_A))];
uint8_t npdcch_w[2][3*3*(16+NPDCCH_A)];
uint8_t npdcch_e[2][MAX_BITS_IN_SF];
///pdu of the npbch message
uint8_t *pdu[2];
} NB_IoT_eNB_NPDCCH_t;
#endif

View File

@@ -0,0 +1,314 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/dlsch_coding_NB_IoT.c
* \brief Top-level routines for implementing Tail-biting convolutional coding for transport channels (NPDSCH) for NB_IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#include <string.h>
//#include "PHY/impl_defs_lte.h"
//#include "openair2/COMMON/openair_defs.h"
//#include "PHY/defs.h"
//#include "PHY/extern_NB_IoT.h"
#include "PHY/CODING/defs_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
//#include "SCHED/defs_NB_IoT.h"
//#include "defs_nb_iot.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
#include "PHY/TOOLS/time_meas_NB_IoT.h"
unsigned char ccodelte_table2_NB_IoT[128];
unsigned short glte2_NB_IoT[] = { 0133, 0171, 0165 };
void free_eNB_dlsch_NB_IoT(NB_IoT_eNB_NDLSCH_t *dlsch)
{
if (dlsch) {
/*
#ifdef DEBUG_DLSCH_FREE
printf("Freeing dlsch %p\n",dlsch);
#endif*/
if (dlsch->harq_process) {
if (dlsch->harq_process->b) {
free16(dlsch->harq_process->b,300);
dlsch->harq_process->b = NULL;
}
if (dlsch->harq_process->d) {
free16(dlsch->harq_process->d,96+(3*(24+MAX_TBS_DL_SIZE_BITS_NB_IoT)));
// dlsch->harq_process->d = NULL;
}
free16(dlsch->harq_process,sizeof(NB_IoT_DL_eNB_HARQ_t));
dlsch->harq_process = NULL;
}
free16(dlsch,sizeof(NB_IoT_eNB_NDLSCH_t));
dlsch = NULL;
}
}
void free_eNB_dlcch_NB_IoT(NB_IoT_eNB_NPDCCH_t *dlcch)
{
if (dlcch) {
free16(dlcch,sizeof(NB_IoT_eNB_NPDCCH_t));
dlcch = NULL;
}
}
void ccode_encode_npdsch_NB_IoT (int32_t numbits,
uint8_t *inPtr,
uint8_t *outPtr,
uint32_t crc)
{
uint32_t state;
uint8_t c, out, first_bit;
int8_t shiftbit = 0;
/* The input bit is shifted in position 8 of the state.
Shiftbit will take values between 1 and 8 */
state = 0;
first_bit = 2;
c = ((uint8_t*)&crc)[0];
// Perform Tail-biting
// get bits from last byte of input (or crc)
for (shiftbit = 0 ; shiftbit <(8-first_bit) ; shiftbit++) {
if ((c&(1<<(7-first_bit-shiftbit))) != 0)
state |= (1<<shiftbit);
}
state = state & 0x3f; // true initial state of Tail-biting CCode
state<<=1; // because of loop structure in CCode
while (numbits > 0) { // Tail-biting is applied to input bits , input 34 bits , output 102 bits
c = *inPtr++;
for (shiftbit = 7; (shiftbit>=0) && (numbits>0); shiftbit--,numbits--) {
state >>= 1;
if ((c&(1<<shiftbit)) != 0) {
state |= 64;
}
out = ccodelte_table2_NB_IoT[state];
*outPtr++ = out & 1;
*outPtr++ = (out>>1)&1;
*outPtr++ = (out>>2)&1;
}
}
}
///////////////////////////////////////////////////////////////////////////////
int32_t dlsch_encoding_NB_IoT(unsigned char *a,
NB_IoT_eNB_NDLSCH_t *dlsch,
uint8_t Nsf, // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table)
unsigned int G // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation)
){
uint32_t crc = 1;
//unsigned char harq_pid = dlsch->current_harq_pid; // to check during implementation if harq_pid is required in the NB_IoT_eNB_DLSCH_t structure in defs_NB_IoT.h
//uint8_t option1,option2,option3,option4;
unsigned int A=0;
A = dlsch->harq_process->TBS / 8;
uint8_t RCC;
uint8_t npbch_a[A];
uint8_t npbch_a_crc[A+3];
bzero(npbch_a,A);
bzero(npbch_a_crc,A+3);
dlsch->harq_process->length_e = G*Nsf; // G*Nsf (number_of_subframes) = total number of bits to transmit G=236
for (int i=0; i<A; i++)
{
npbch_a[i] = a[i];
}
int32_t numbits = (A*8)+24;
crc = crc24a_NB_IoT(npbch_a,A*8)>>8;
for (int j=0; j<A; j++)
{
npbch_a_crc[j] = npbch_a[j];
}
npbch_a_crc[A] = ((uint8_t*)&crc)[2];
npbch_a_crc[A+1] = ((uint8_t*)&crc)[1];
npbch_a_crc[A+2] = ((uint8_t*)&crc)[0];
dlsch->harq_process->B = numbits; // The length of table b in bits
//memcpy(dlsch->b,a,numbits/8); // comment if option 2
memset(dlsch->harq_process->d,LTE_NULL_NB_IoT,96);
ccode_encode_npdsch_NB_IoT(numbits,npbch_a_crc,dlsch->harq_process->d+96,crc);
RCC = sub_block_interleaving_cc_NB_IoT(numbits,dlsch->harq_process->d+96,dlsch->harq_process->w); // step 2 interleaving
lte_rate_matching_cc_NB_IoT(RCC,dlsch->harq_process->length_e,dlsch->harq_process->w,dlsch->harq_process->e); // step 3 Rate Matching
return(0);
}
///////////////////////////////////////////////////////////////////////////
NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(uint8_t length, NB_IoT_DL_FRAME_PARMS* frame_parms)
{
NB_IoT_eNB_NDLSCH_t *dlsch;
unsigned char exit_flag = 0,r;
dlsch = (NB_IoT_eNB_NDLSCH_t *)malloc16(sizeof(NB_IoT_eNB_NDLSCH_t));
if (dlsch) {
bzero(dlsch,sizeof(NB_IoT_eNB_NDLSCH_t));
dlsch->harq_process = (NB_IoT_DL_eNB_HARQ_t *)malloc16(sizeof(NB_IoT_DL_eNB_HARQ_t));
if (dlsch->harq_process) {
bzero(dlsch->harq_process,sizeof(NB_IoT_DL_eNB_HARQ_t));
// dlsch->harq_process[i]->first_tx=1;
dlsch->harq_process->b = (unsigned char*)malloc(300); // to set a new one that replace 300 , MAX_DLSCH_PAYLOAD_BYTES/bw_scaling
if (dlsch->harq_process->b) {
bzero(dlsch->harq_process->b,300);
} else {
printf("Can't get b\n");
exit_flag=1;
}
if (dlsch->harq_process->d) {
bzero((void *)dlsch->harq_process->d,96+(3*(24+MAX_TBS_DL_SIZE_BITS_NB_IoT)));
} else {
printf("Can't get d\n");
exit_flag=2;
}
// }
} else {
exit_flag=3;
}
if (exit_flag==0) {
dlsch->harq_process->round=0;
// for (r=0; r<(96+(3*(24+MAX_TBS_DL_SIZE_BITS_NB_IoT))); r++) {
//
// if (dlsch->harq_process->d)
// dlsch->harq_process->d[0]= LTE_NULL_NB_IoT;
// }
return(dlsch);
}
}
/// LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of %ld\n",
// exit_flag, sizeof(NB_IoT_eNB_NDLSCH_t));
free_eNB_dlsch_NB_IoT(dlsch);
return(NULL);
}
///////////////////////////////////////////////////////////////////////////
NB_IoT_eNB_NPDCCH_t *new_eNB_dlcch_NB_IoT(NB_IoT_DL_FRAME_PARMS* frame_parms)
{
NB_IoT_eNB_NPDCCH_t *dlcch;
dlcch = (NB_IoT_eNB_NPDCCH_t *)malloc16(sizeof(NB_IoT_eNB_NPDCCH_t));
if (dlcch) {
bzero(dlcch,sizeof(NB_IoT_eNB_NPDCCH_t));
return(dlcch);
}
/// LOG_D(PHY,"new_eNB_dlsch exit flag %d, size of %ld\n",
// exit_flag, sizeof(NB_IoT_eNB_NDLSCH_t));
free_eNB_dlcch_NB_IoT(dlcch);
return(NULL);
}
/*************************************************************************
Functions to initialize the code tables
*************************************************************************/
/* Basic code table initialization for constraint length 7 */
/* Input in MSB, followed by state in 6 LSBs */
void ccodelte_init2_NB_IoT(void)
{
unsigned int i, j, k, sum;
for (i = 0; i < 128; i++) {
ccodelte_table2_NB_IoT[i] = 0;
/* Compute 3 output bits */
for (j = 0; j < 3; j++) {
sum = 0;
for (k = 0; k < 7; k++)
if ((i & glte2_NB_IoT[j]) & (1 << k))
sum++;
/* Write the sum modulo 2 in bit j */
ccodelte_table2_NB_IoT[i] |= (sum & 1) << j;
}
}
}

View File

@@ -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.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/dlsch_modulation_NB_IoT.c
* \brief Top-level routines for generating the NPDSCH physical channel for NB_IoT,
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#include <math.h>
//#include "PHY/defs.h"
//#include "PHY/defs_NB_IoT.h"
//#include "PHY/extern_NB_IoT.h"
//#include "PHY/impl_defs_lte.h"
//#include "PHY/CODING/defs_nb_iot.h"
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/impl_defs_top_NB_IoT.h"
//#include "defs.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
int allocate_REs_in_RB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
int16_t amp,
unsigned short id_offset,
uint8_t pilot_shift,
uint32_t *re_allocated) // not used variable ??!!
{
MIMO_mode_t mimo_mode = (frame_parms->mode1_flag==1)? SISO:ALAMOUTI;
uint32_t tti_offset,aa;
uint8_t re;
int16_t gain_lin_QPSK;
uint8_t first_re,last_re;
int32_t tmp_sample1,tmp_sample2;
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
first_re = 0;
last_re = 12;
for (re=first_re; re<last_re; re++) { // re varies between 0 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || (re%6 != ((id_offset + 3*pilot_shift) % 6) ) ) // if re is not a pilot
{
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
return(0);
}
int dlsch_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
NB_IoT_eNB_NDLSCH_t *dlsch0, //NB_IoT_eNB_NDLSCH_t
int G, // number of bits per subframe
unsigned int npdsch_data_subframe, // subframe index of the data table of npdsch channel (G*Nsf) , values are between 0..Nsf
unsigned int subframe,
unsigned short NB_IoT_RB_ID)
{
//uint8_t harq_pid = dlsch0->current_harq_pid;
//NB_IoT_DL_eNB_HARQ_t *dlsch0_harq = dlsch0->harq_processes[harq_pid];
uint32_t jj = 0;
uint32_t re_allocated,symbol_offset;
uint16_t l;
uint8_t id_offset,pilot_shift,pilots = 0;
unsigned short bandwidth_even_odd;
unsigned short NB_IoT_start, RB_IoT_ID;
re_allocated = 0;
id_offset = 0;
pilot_shift = 0;
// testing if the total number of RBs is even or odd
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
RB_IoT_ID = NB_IoT_RB_ID;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for (l=control_region_size; l<14; l++) { // loop on OFDM symbols
if((l>=4 && l<=7) || (l>=11 && l<=13))
{
pilots = 1;
if(l==4 || l==6 || l==11 || l==13)
{
pilot_shift = 1;
}
} else {
pilots = 0;
}
id_offset = frame_parms->Nid_cell % 6; // Cell_ID_NB_IoT % 6
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID % (int)(ceil(frame_parms->N_RB_DL/(float)2)));
}
symbol_offset = (14*subframe*frame_parms->ofdm_symbol_size) + frame_parms->ofdm_symbol_size*l + NB_IoT_start; // symbol_offset = 512 * L + NB_IOT_RB start
allocate_REs_in_RB_NB_IoT(frame_parms,
txdataF,
&jj,
symbol_offset,
&dlsch0->harq_process->s_e[G*npdsch_data_subframe],
pilots,
amp,
id_offset,
pilot_shift,
&re_allocated);
}
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION, VCD_FUNCTION_OUT);
return (re_allocated);
}

View File

@@ -0,0 +1,97 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/dlsch_scrambling_NB_IoT.c
* \brief Routines for the scrambling procedure of the NPDSCH physical channel for NB_IoT, TS 36-211, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
//#define DEBUG_SCRAMBLING 1
//#include "PHY/defs.h"
//#include "PHY/defs_NB_IoT.h"
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
//#include "defs.h"
//#include "extern_NB_IoT.h"
//#include "PHY/extern_NB_IoT.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/impl_defs_lte.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "openair1/PHY/NBIoT_TRANSPORT/extern_NB_IoT.h"
void dlsch_scrambling_Gen_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_NDLSCH_t *dlsch,
int tot_bits, // total number of bits to transmit
uint16_t Nf, // Nf is the frame number (0..9)
uint8_t Ns,
uint32_t rnti,
uint8_t release_v13_5_0,
uint8_t SIB)
{
int i,j,k=0;
uint32_t x1,x2, s=0;
uint8_t *e = dlsch->harq_process->e; //uint8_t *e=dlsch->harq_processes[dlsch->current_harq_pid]->e;
if(release_v13_5_0 == 1 && SIB == 1) /// for SIBs from release 13.5.0 and above
{
x2 = (rnti<<15) + (frame_parms->Nid_cell + 1) * ( (Nf % 61) + 1 ) ;
} else {
x2 = (rnti<<14) + ((Nf%2)<<13) + ((Ns>>1)<<9) + frame_parms->Nid_cell;
}
s = lte_gold_generic_NB_IoT(&x1, &x2, 1);
for (i=0; i<(1+(tot_bits>>5)); i++) {
for (j=0; j<32; j++,k++) {
dlsch->harq_process->s_e[k] = (e[k]&1) ^ ((s>>j)&1);
}
s = lte_gold_generic_NB_IoT(&x1, &x2, 0);
}
}
void init_unscrambling_lut_NB_IoT() {
uint32_t s;
int i=0,j;
for (s=0;s<=65535;s++) {
for (j=0;j<16;j++) {
unscrambling_lut_NB_IoT[i++] = (int16_t)((((s>>j)&1)<<1)-1);
}
}
}

View File

@@ -0,0 +1,56 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __DLSCH_TBS_FULL_NB_IOT_H__
#define __DLSCH_TBS_FULL_NB_IOT_H__
/** \brief "Transport block size table"
* (Table 7.1.7.2.1-1 in 3GPP TS 36.213 V8.6.0)
*/
// NB-IoT------------------
// TBS table for the case not containing SIB1-NB, Table 16.4.1.5.1-1 in TS 36.213 v14.2
unsigned int TBStable_NB_IoT[14][8] ={ //[ITBS][ISF]
{16,32,56,88,120.152,208,256},
{24,56,88,144,176,208,256,344},
{32,72,144,176,208,256,328,424},
{40,104,176,208,256,328,440,568},
{56,120,208,256,328,408,552,680},
{72,144,244,328,424,504,680,872},
{88,176,256,392,504,600,808,1032},
{104,224,328,472,584,680,968,1224},
{120,256,392,536,680,808,1096,1352},
{136,296,456,616,776,936,1256,1544},
{144,328,504,680,872,1032,1384,1736},
{176,376,584,776,1000,1192,1608,2024},
{208,440,680,904,1128,1352,1800,2280},
{224,488,744,1128,1256,1544,2024,2536}
};
//TBS table for the case containing S1B1-NB, Table 16.4.1.5.2-1 in TS 36.213 v14.2 (Itbs = 12 ~ 15 is reserved field
//mapping ITBS to SIB1-NB
unsigned int TBStable_NB_IoT_SIB1[16] = {208,208,208,328,328,328,440,440,440,680,680,680,0,0,0,0};
#endif

View File

@@ -0,0 +1,70 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __PHY_LTE_TRANSPORT_EXTERN_NB_IOT__H__
#define __PHY_LTE_TRANSPORT_EXTERN_NB_IOT__H__
extern unsigned int TBStable_NB_IoT[14][8];
extern unsigned int TBStable_NB_IoT_SIB1[16];
extern unsigned char cs_ri_normal_NB_IoT[4];
extern unsigned char cs_ri_extended_NB_IoT[4];
extern unsigned char cs_ack_normal_NB_IoT[4];
extern unsigned char cs_ack_extended_NB_IoT[4];
extern int8_t wACK_RX_NB_IoT[5][4];
extern int G_tab[18];
extern short conjugate[8],conjugate2[8];
extern short *ul_ref_sigs_rx_NB_IoT[30][4]; // NB-IoT: format 1 pilots
extern short *ul_ref_sigs_f2_rx_NB_IoT[16]; // NB-IoT: format 2 pilots
//extern unsigned short dftsizes[33];
extern int16_t unscrambling_lut_NB_IoT[65536*16];
extern int16_t e_phi_re_m6[120];
extern int16_t e_phi_im_m6[120];
extern int16_t e_phi_re_m5[120];
extern int16_t e_phi_im_m5[120];
extern int16_t e_phi_re_m4[120];
extern int16_t e_phi_im_m4[120];
extern int16_t e_phi_re_m3[120];
extern int16_t e_phi_im_m3[120];
extern int16_t e_phi_re_m2[120];
extern int16_t e_phi_im_m2[120];
extern int16_t e_phi_re_m1[120];
extern int16_t e_phi_im_m1[120];
extern int16_t e_phi_re_0[120];
extern int16_t e_phi_im_0[120];
extern int16_t e_phi_re_p1[120];
extern int16_t e_phi_im_p1[120];
extern int16_t e_phi_re_p2[120];
extern int16_t e_phi_im_p2[120];
extern int16_t e_phi_re_p3[120];
extern int16_t e_phi_im_p3[120];
extern int16_t e_phi_re_p4[120];
extern int16_t e_phi_im_p4[120];
extern int16_t e_phi_re_p5[120];
extern int16_t e_phi_im_p5[120];
#endif

View File

@@ -0,0 +1,120 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
int16_t s_n11_re[336] = {23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, -1, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, 0, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039};
int16_t s_n11_im[336] = {23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, 0, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, 0, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, 0, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852};
int16_t s_n10_re[336] = {-23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, -1, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, 0, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, -1, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, -1, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962};
int16_t s_n10_im[336] = {23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, -1, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, 0, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786};
int16_t s_n9_re[336] = {-23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, -1, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, 0, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808};
int16_t s_n9_im[336] = {-23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, 0, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, 0, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, 0, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413};
int16_t s_n8_re[336] = {23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, -1, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, 0, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, -1, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, -1, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608};
int16_t s_n8_im[336] = {-23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, -1, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, 0, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728};
int16_t s_n7_re[336] = {23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, -1, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, -1, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, 0, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607};
int16_t s_n7_im[336] = {23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, -1, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, 0, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728};
int16_t s_n6_re[336] = {-23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, -1, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, 0, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, -1, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, 0, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807};
int16_t s_n6_im[336] = {23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, -1, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, 0, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413};
int16_t s_n5_re[336] = {-23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, -1, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, -1, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, 0, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961};
int16_t s_n5_im[336] = {-23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, -1, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, 0, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786};
int16_t s_n4_re[336] = {23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, 0, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, -1, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038};
int16_t s_n4_im[336] = {-23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, 0, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, -1, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, -1, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852};
int16_t s_n3_re[336] = {23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, -1, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, -1, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, 0, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, -1, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009};
int16_t s_n3_im[336] = {23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, -1, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, 0, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622};
int16_t s_n2_re[336] = {-23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, -1, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, 0, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, -1, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, 0, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845};
int16_t s_n2_im[336] = {23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, -1, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, 0, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106};
int16_t s_n1_re[336] = {-23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, -1, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, -1, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, 0, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, -1, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519};
int16_t s_n1_im[336] = {-23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, -1, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, 0, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319};
int16_t s_n0_re[336] = {23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004};
int16_t s_n0_im[336] = {-23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, 0, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279};
int16_t s_n_12_re[4032] = {23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004,
-23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, -1, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, -1, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, 0, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, -1, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519,
-23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, -1, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, 0, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, -1, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, 0, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845,
23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, -1, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, -1, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, 0, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, -1, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009,
23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, 0, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, -1, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038,
-23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, -1, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, -1, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, 0, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961,
-23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, -1, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, 0, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, -1, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, 0, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807,
23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, -1, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, -1, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, 0, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607,
23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, -1, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, 0, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, -1, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, -1, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608,
-23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, -1, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, 0, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808,
-23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, -1, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, 0, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, -1, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, -1, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962,
23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, -1, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, 0, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039};
int16_t s_n_12_im[4032] = {-23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, 0, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279, 0, 24278, -32610, 19519, 6392, -28106, 31356, -14010, -12540, 30851, -28898, 7961, 18204, -32413, 25329, -1608, -23170, 32727, -20788, -4808, 27244, -31786, 15446, 11038, -30273, 29621, -9512, -16846, 32137, -26319, 3211, 22004, -32767, 22004, 3211, -26319, 32137, -16846, -9512, 29621, -30273, 11038, 15446, -31786, 27244, -4808, -20788, 32727, -23170, -1608, 25329, -32413, 18204, 7961, -28898, 30851, -12540, -14010, 31356, -28106, 6392, 19519, -32610, 24278, -1, -24279, 32609, -19520, -6393, 28105, -31357, 14009, 12539, -30852, 28897, -7962, -18205, 32412, -25330, 1607, 23169, -32728, 20787, 4807, -27245, 31785, -15447, -11039, 30272, -29622, 9511, 16845, -32138, 26318, -3212, -22005, 32767, -22005, -3212, 26318, -32138, 16845, 9511, -29622, 30272, -11039, -15447, 31785, -27245, 4807, 20787, -32728, 23169, 1607, -25330, 32412, -18205, -7962, 28897, -30852, 12539, 14009, -31357, 28105, -6393, -19520, 32609, -24279,
-23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, -1, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319, 0, 26318, -31357, 11038, 18204, -32728, 20787, 7961, -30273, 28105, -3212, -24279, 32137, -14010, -15447, 32412, -23170, -4808, 28897, -29622, 6392, 22004, -32610, 16845, 12539, -31786, 25329, 1607, -27245, 30851, -9512, -19520, 32767, -19520, -9512, 30851, -27245, 1607, 25329, -31786, 12539, 16845, -32610, 22004, 6392, -29622, 28897, -4808, -23170, 32412, -15447, -14010, 32137, -24279, -3212, 28105, -30273, 7961, 20787, -32728, 18204, 11038, -31357, 26318, 0, -26319, 31356, -11039, -18205, 32727, -20788, -7962, 30272, -28106, 3211, 24278, -32138, 14009, 15446, -32413, 23169, 4807, -28898, 29621, -6393, -22005, 32609, -16846, -12540, 31785, -25330, -1608, 27244, -30852, 9511, 19519, -32767, 19519, 9511, -30852, 27244, -1608, -25330, 31785, -12540, -16846, 32609, -22005, -6393, 29621, -28898, 4807, 23169, -32413, 15446, 14009, -32138, 24278, 3211, -28106, 30272, -7962, -20788, 32727, -18205, -11039, 31356, -26319,
23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, -1, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106, 0, 28105, -28898, 1607, 27244, -29622, 3211, 26318, -30273, 4807, 25329, -30852, 6392, 24278, -31357, 7961, 23169, -31786, 9511, 22004, -32138, 11038, 20787, -32413, 12539, 19519, -32610, 14009, 18204, -32728, 15446, 16845, -32767, 16845, 15446, -32728, 18204, 14009, -32610, 19519, 12539, -32413, 20787, 11038, -32138, 22004, 9511, -31786, 23169, 7961, -31357, 24278, 6392, -30852, 25329, 4807, -30273, 26318, 3211, -29622, 27244, 1607, -28898, 28105, 0, -28106, 28897, -1608, -27245, 29621, -3212, -26319, 30272, -4808, -25330, 30851, -6393, -24279, 31356, -7962, -23170, 31785, -9512, -22005, 32137, -11039, -20788, 32412, -12540, -19520, 32609, -14010, -18205, 32727, -15447, -16846, 32767, -16846, -15447, 32727, -18205, -14010, 32609, -19520, -12540, 32412, -20788, -11039, 32137, -22005, -9512, 31785, -23170, -7962, 31356, -24279, -6393, 30851, -25330, -4808, 30272, -26319, -3212, 29621, -27245, -1608, 28897, -28106,
23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, -1, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622, 0, 29621, -25330, -7962, 32137, -19520, -15447, 32727, -12540, -22005, 31356, -4808, -27245, 28105, 3211, -30852, 23169, 11038, -32610, 16845, 18204, -32413, 9511, 24278, -30273, 1607, 28897, -26319, -6393, 31785, -20788, -14010, 32767, -14010, -20788, 31785, -6393, -26319, 28897, 1607, -30273, 24278, 9511, -32413, 18204, 16845, -32610, 11038, 23169, -30852, 3211, 28105, -27245, -4808, 31356, -22005, -12540, 32727, -15447, -19520, 32137, -7962, -25330, 29621, 0, -29622, 25329, 7961, -32138, 19519, 15446, -32728, 12539, 22004, -31357, 4807, 27244, -28106, -3212, 30851, -23170, -11039, 32609, -16846, -18205, 32412, -9512, -24279, 30272, -1608, -28898, 26318, 6392, -31786, 20787, 14009, -32767, 14009, 20787, -31786, 6392, 26318, -28898, -1608, 30272, -24279, -9512, 32412, -18205, -16846, 32609, -11039, -23170, 30851, -3212, -28106, 27244, 4807, -31357, 22004, 12539, -32728, 15446, 19519, -32138, 7961, 25329, -29622,
-23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, 0, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, -1, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852, 0, 30851, -20788, -16846, 32137, -4808, -28898, 24278, 12539, -32728, 9511, 26318, -27245, -7962, 32609, -14010, -23170, 29621, 3211, -31786, 18204, 19519, -31357, 1607, 30272, -22005, -15447, 32412, -6393, -28106, 25329, 11038, -32767, 11038, 25329, -28106, -6393, 32412, -15447, -22005, 30272, 1607, -31357, 19519, 18204, -31786, 3211, 29621, -23170, -14010, 32609, -7962, -27245, 26318, 9511, -32728, 12539, 24278, -28898, -4808, 32137, -16846, -20788, 30851, -1, -30852, 20787, 16845, -32138, 4807, 28897, -24279, -12540, 32727, -9512, -26319, 27244, 7961, -32610, 14009, 23169, -29622, -3212, 31785, -18205, -19520, 31356, -1608, -30273, 22004, 15446, -32413, 6392, 28105, -25330, -11039, 32767, -11039, -25330, 28105, 6392, -32413, 15446, 22004, -30273, -1608, 31356, -19520, -18205, 31785, -3212, -29622, 23169, 14009, -32610, 7961, 27244, -26319, -9512, 32727, -12540, -24279, 28897, 4807, -32138, 16845, 20787, -30852,
-23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, -1, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786, 0, 31785, -15447, -24279, 27244, 11038, -32610, 4807, 30272, -19520, -20788, 29621, 6392, -32728, 9511, 28105, -23170, -16846, 31356, 1607, -32138, 14009, 25329, -26319, -12540, 32412, -3212, -30852, 18204, 22004, -28898, -7962, 32767, -7962, -28898, 22004, 18204, -30852, -3212, 32412, -12540, -26319, 25329, 14009, -32138, 1607, 31356, -16846, -23170, 28105, 9511, -32728, 6392, 29621, -20788, -19520, 30272, 4807, -32610, 11038, 27244, -24279, -15447, 31785, 0, -31786, 15446, 24278, -27245, -11039, 32609, -4808, -30273, 19519, 20787, -29622, -6393, 32727, -9512, -28106, 23169, 16845, -31357, -1608, 32137, -14010, -25330, 26318, 12539, -32413, 3211, 30851, -18205, -22005, 28897, 7961, -32767, 7961, 28897, -22005, -18205, 30851, 3211, -32413, 12539, 26318, -25330, -14010, 32137, -1608, -31357, 16845, 23169, -28106, -9512, 32727, -6393, -29622, 20787, 19519, -30273, -4808, 32609, -11039, -27245, 24278, 15446, -31786,
23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, -1, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413, 0, 32412, -9512, -29622, 18204, 24278, -25330, -16846, 30272, 7961, -32610, 1607, 32137, -11039, -28898, 19519, 23169, -26319, -15447, 30851, 6392, -32728, 3211, 31785, -12540, -28106, 20787, 22004, -27245, -14010, 31356, 4807, -32767, 4807, 31356, -14010, -27245, 22004, 20787, -28106, -12540, 31785, 3211, -32728, 6392, 30851, -15447, -26319, 23169, 19519, -28898, -11039, 32137, 1607, -32610, 7961, 30272, -16846, -25330, 24278, 18204, -29622, -9512, 32412, 0, -32413, 9511, 29621, -18205, -24279, 25329, 16845, -30273, -7962, 32609, -1608, -32138, 11038, 28897, -19520, -23170, 26318, 15446, -30852, -6393, 32727, -3212, -31786, 12539, 28105, -20788, -22005, 27244, 14009, -31357, -4808, 32767, -4808, -31357, 14009, 27244, -22005, -20788, 28105, 12539, -31786, -3212, 32727, -6393, -30852, 15446, 26318, -23170, -19520, 28897, 11038, -32138, -1608, 32609, -7962, -30273, 16845, 25329, -24279, -18205, 29621, 9511, -32413,
23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, -1, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728, 0, 32727, -3212, -32413, 6392, 31785, -9512, -30852, 12539, 29621, -15447, -28106, 18204, 26318, -20788, -24279, 23169, 22004, -25330, -19520, 27244, 16845, -28898, -14010, 30272, 11038, -31357, -7962, 32137, 4807, -32610, -1608, 32767, -1608, -32610, 4807, 32137, -7962, -31357, 11038, 30272, -14010, -28898, 16845, 27244, -19520, -25330, 22004, 23169, -24279, -20788, 26318, 18204, -28106, -15447, 29621, 12539, -30852, -9512, 31785, 6392, -32413, -3212, 32727, 0, -32728, 3211, 32412, -6393, -31786, 9511, 30851, -12540, -29622, 15446, 28105, -18205, -26319, 20787, 24278, -23170, -22005, 25329, 19519, -27245, -16846, 28897, 14009, -30273, -11039, 31356, 7961, -32138, -4808, 32609, 1607, -32767, 1607, 32609, -4808, -32138, 7961, 31356, -11039, -30273, 14009, 28897, -16846, -27245, 19519, 25329, -22005, -23170, 24278, 20787, -26319, -18205, 28105, 15446, -29622, -12540, 30851, 9511, -31786, -6393, 32412, 3211, -32728,
-23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, -1, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728, 0, 32727, 3211, -32413, -6393, 31785, 9511, -30852, -12540, 29621, 15446, -28106, -18205, 26318, 20787, -24279, -23170, 22004, 25329, -19520, -27245, 16845, 28897, -14010, -30273, 11038, 31356, -7962, -32138, 4807, 32609, -1608, -32767, -1608, 32609, 4807, -32138, -7962, 31356, 11038, -30273, -14010, 28897, 16845, -27245, -19520, 25329, 22004, -23170, -24279, 20787, 26318, -18205, -28106, 15446, 29621, -12540, -30852, 9511, 31785, -6393, -32413, 3211, 32727, 0, -32728, -3212, 32412, 6392, -31786, -9512, 30851, 12539, -29622, -15447, 28105, 18204, -26319, -20788, 24278, 23169, -22005, -25330, 19519, 27244, -16846, -28898, 14009, 30272, -11039, -31357, 7961, 32137, -4808, -32610, 1607, 32767, 1607, -32610, -4808, 32137, 7961, -31357, -11039, 30272, 14009, -28898, -16846, 27244, 19519, -25330, -22005, 23169, 24278, -20788, -26319, 18204, 28105, -15447, -29622, 12539, 30851, -9512, -31786, 6392, 32412, -3212, -32728,
-23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, 0, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, 0, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413, 0, 32412, 9511, -29622, -18205, 24278, 25329, -16846, -30273, 7961, 32609, 1607, -32138, -11039, 28897, 19519, -23170, -26319, 15446, 30851, -6393, -32728, -3212, 31785, 12539, -28106, -20788, 22004, 27244, -14010, -31357, 4807, 32767, 4807, -31357, -14010, 27244, 22004, -20788, -28106, 12539, 31785, -3212, -32728, -6393, 30851, 15446, -26319, -23170, 19519, 28897, -11039, -32138, 1607, 32609, 7961, -30273, -16846, 25329, 24278, -18205, -29622, 9511, 32412, -1, -32413, -9512, 29621, 18204, -24279, -25330, 16845, 30272, -7962, -32610, -1608, 32137, 11038, -28898, -19520, 23169, 26318, -15447, -30852, 6392, 32727, 3211, -31786, -12540, 28105, 20787, -22005, -27245, 14009, 31356, -4808, -32767, -4808, 31356, 14009, -27245, -22005, 20787, 28105, -12540, -31786, 3211, 32727, 6392, -30852, -15447, 26318, 23169, -19520, -28898, 11038, 32137, -1608, -32610, -7962, 30272, 16845, -25330, -24279, 18204, 29621, -9512, -32413,
23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, -1, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786, 0, 31785, 15446, -24279, -27245, 11038, 32609, 4807, -30273, -19520, 20787, 29621, -6393, -32728, -9512, 28105, 23169, -16846, -31357, 1607, 32137, 14009, -25330, -26319, 12539, 32412, 3211, -30852, -18205, 22004, 28897, -7962, -32767, -7962, 28897, 22004, -18205, -30852, 3211, 32412, 12539, -26319, -25330, 14009, 32137, 1607, -31357, -16846, 23169, 28105, -9512, -32728, -6393, 29621, 20787, -19520, -30273, 4807, 32609, 11038, -27245, -24279, 15446, 31785, 0, -31786, -15447, 24278, 27244, -11039, -32610, -4808, 30272, 19519, -20788, -29622, 6392, 32727, 9511, -28106, -23170, 16845, 31356, -1608, -32138, -14010, 25329, 26318, -12540, -32413, -3212, 30851, 18204, -22005, -28898, 7961, 32767, 7961, -28898, -22005, 18204, 30851, -3212, -32413, -12540, 26318, 25329, -14010, -32138, -1608, 31356, 16845, -23170, -28106, 9511, 32727, 6392, -29622, -20788, 19519, 30272, -4808, -32610, -11039, 27244, 24278, -15447, -31786,
23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, 0, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, 0, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852, 0, 30851, 20787, -16846, -32138, -4808, 28897, 24278, -12540, -32728, -9512, 26318, 27244, -7962, -32610, -14010, 23169, 29621, -3212, -31786, -18205, 19519, 31356, 1607, -30273, -22005, 15446, 32412, 6392, -28106, -25330, 11038, 32767, 11038, -25330, -28106, 6392, 32412, 15446, -22005, -30273, 1607, 31356, 19519, -18205, -31786, -3212, 29621, 23169, -14010, -32610, -7962, 27244, 26318, -9512, -32728, -12540, 24278, 28897, -4808, -32138, -16846, 20787, 30851, -1, -30852, -20788, 16845, 32137, 4807, -28898, -24279, 12539, 32727, 9511, -26319, -27245, 7961, 32609, 14009, -23170, -29622, 3211, 31785, 18204, -19520, -31357, -1608, 30272, 22004, -15447, -32413, -6393, 28105, 25329, -11039, -32767, -11039, 25329, 28105, -6393, -32413, -15447, 22004, 30272, -1608, -31357, -19520, 18204, 31785, 3211, -29622, -23170, 14009, 32609, 7961, -27245, -26319, 9511, 32727, 12539, -24279, -28898, 4807, 32137, 16845, -20788, -30852};

View File

@@ -0,0 +1,252 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/lte_mcs_NB_IoT.c
* \brief Some support routines for subcarrier start into UL RB for ULSCH
* \author M. KANJ
* \date 2017
* \version 0.1
* \company b<>com
* \email:
* \note
* \warning
*/
//#include "PHY/defs.h"
//#include "PHY/extern.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
uint8_t tab_ack_15khz[16]= {0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3};
uint8_t tab_ack_3_75khz[16]= {38,39,40,41,42,43,44,45,38,39,40,41,42,43,44,45};
uint8_t tab_I_ru_N_ru_UL[8]= {1,2,3,4,5,6,8,10};
uint8_t tab_I_rep_N_rep_UL[8]={1,2,4,8,16,32,64,128};
///
uint8_t tab_ack_sc_format1[16]={0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3};
uint8_t tab_ack_sc_format2[16]={38,39,40,41,42,43,44,45,38,39,40,41,42,43,44,45};
/*
// Section 16.5.1.1 in 36.213
uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc)
{
if (0<=I_sc && I_sc<=11)
{
return I_sc;
} else if (12<=I_sc && I_sc<=15) {
return 3*(I_sc-12);
} else if (16<=I_sc && I_sc<=17) {
return 6*(I_sc-16);
} else if (I_sc==18){
return 0;
} else if (I_sc>18 || I_sc<0){
return -1; /// error msg is needed for this case
} else {
return -1; /// error msg is needed for this case
}
}
*/
uint16_t get_UL_N_rep_NB_IoT(uint8_t I_rep)
{
return tab_I_rep_N_rep_UL[I_rep];
}
uint16_t get_UL_N_ru_NB_IoT(uint8_t I_mcs, uint8_t I_ru, uint8_t flag_msg3)
{
if(flag_msg3 ==1) // msg3
{
if(I_mcs == 0)
{
return 4;
} else if(I_mcs == 1) {
return 3;
} else if(I_mcs == 2) {
return 1;
} else {
//printf("error in I_mcs value from nfapi");
return 0;
}
} else { // other NPUSCH
return tab_I_ru_N_ru_UL[I_ru];
}
}
uint16_t get_UL_sc_ACK_NB_IoT(uint8_t subcarrier_spacing,uint16_t harq_ack_resource)
{
if(subcarrier_spacing == 1) /// 15KHz
{
return tab_ack_sc_format1[harq_ack_resource];
} else { // 3.75 KHz
return tab_ack_sc_format2[harq_ack_resource];
}
}
uint16_t get_UL_sc_index_start_NB_IoT(uint8_t subcarrier_spacing, uint16_t I_sc, uint8_t npush_format)
{
if(npush_format == 0) // format 1
{
if(subcarrier_spacing == 1) ////////// 15 KHz
{
if (0<=I_sc && I_sc<12)
{
return I_sc;
} else if (12<=I_sc && I_sc<16) {
return 3*(I_sc-12);
} else if (16<=I_sc && I_sc<18) {
return 6*(I_sc-16);
} else if (I_sc==18){
return 0;
} else {
return -1;
printf("Error in passed nfapi parameters (I_sc)");
}
} else { //////////// 3.75 KHz
return I_sc; /// values 0-47
}
} else { /////////////////////////////////////// format 2
if(subcarrier_spacing == 1) ////////// 15 KHz
{
return(tab_ack_15khz[I_sc]);
} else { //////////// 3.75 KHz
return(tab_ack_3_75khz[I_sc]);
}
}
}
///////////////////////////////////////////////
uint8_t get_numb_UL_sc_NB_IoT(uint8_t subcarrier_spacing, uint8_t I_sc, uint8_t npush_format)
{
if(npush_format == 0) // format 1
{
if(subcarrier_spacing == 1) // 15 KHz
{
if(I_sc >= 0 && I_sc < 12)
{
return 1;
} else if (I_sc >= 12 && I_sc < 16) {
return 3;
} else if (I_sc >= 16 && I_sc < 18) {
return 6;
} else if (I_sc == 18) {
return 12;
} else {
return 0;
}
} else {
return 1;
}
} else {
return 1;
}
}
////////////////////////////////////////////////////
uint8_t get_UL_slots_per_RU_NB_IoT(uint8_t subcarrier_spacing, uint8_t subcarrier_indcation, uint8_t UL_format)
{
uint8_t subcarrier_number = get_numb_UL_sc_NB_IoT(subcarrier_spacing, subcarrier_indcation, UL_format);
if(UL_format == 0) // format 1
{
if(subcarrier_spacing == 1) // 15 KHz
{
if (subcarrier_number == 1 )
{
return 16;
} else if (subcarrier_number == 3) {
return 8;
} else if (subcarrier_number == 6) {
return 4;
} else {
return 2;
}
} else { // 3.75 KHz
return 16;
}
} else { // format 2
return 4;
}
}

View File

@@ -0,0 +1,267 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/lte_mcs_NB_IoT.c
* \brief Some support routines for MCS computations
* \author M. KANJ
* \date 2017
* \version 0.1
* \company b<>com
* \email:
* \note
* \warning
*/
//#include "PHY/defs.h"
//#include "PHY/extern.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "proto_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/extern_NB_IoT.h"
#include "vars_NB_IoT.h"
uint8_t get_Qm_UL_NB_IoT(unsigned char I_mcs, uint8_t N_sc_RU, uint8_t I_sc, uint8_t Msg3_flag)
{
if (Msg3_flag == 1) /////////////////////////// case of Msg3
{
if(I_mcs > 0)
{
return 2;
} else if (I_mcs == 0 && I_sc <12) {
return 1;
} else { ////// I_mcs == 0 && I_sc >11
return 2;
}
} else { /////////////////////// case of other NPUSCH config
if(N_sc_RU == 1)
{
if(I_mcs <2)
{
return 1;
} else {
return 2;
}
} else { /////////////// N_sc_RU > 1
return 2;
}
}
}
int get_G_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms)
{
uint16_t num_ctrl_symbols = frame_parms->control_region_size; // eutra_control_region_size values are 0,1,2
uint8_t nb_antennas_tx_LTE = frame_parms->nb_antennas_tx;
uint8_t nb_antennas_tx_NB_IoT = frame_parms->nb_antennas_tx_NB_IoT;
int G_value=0;
switch (nb_antennas_tx_NB_IoT + (2*nb_antennas_tx_LTE)) {
case 10:
G_value = G_tab[(1*3)-num_ctrl_symbols-1];
break;
case 6:
G_value = G_tab[(2*3)-num_ctrl_symbols-1];
break;
case 4 :
G_value = G_tab[(3*3)-num_ctrl_symbols-1];
break;
case 9 :
G_value = G_tab[(4*3)-num_ctrl_symbols-1];
break;
case 5:
G_value = G_tab[(5*3)-num_ctrl_symbols-1];
break;
case 3 :
G_value = G_tab[(6*3)-num_ctrl_symbols-1];
break;
default:
printf("Error getting G");
}
return(G_value);
}
int get_G_SIB1_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, uint8_t operation_mode_info)
{
uint16_t num_ctrl_symbols = 0; // eutra_control_region_size values are 0,1,2
if(operation_mode_info<2) /// operation_mode_info, in-band (two value 0,1), stand-alone(3), guard band (2)
{
num_ctrl_symbols = 2;
}
uint8_t nb_antennas_tx_LTE = frame_parms->nb_antennas_tx;
uint8_t nb_antennas_tx_NB_IoT = frame_parms->nb_antennas_tx_NB_IoT;
int G_value=0;
switch (nb_antennas_tx_NB_IoT + (2*nb_antennas_tx_LTE)) {
case 10:
G_value = G_tab[(1*3)-num_ctrl_symbols-1];
break;
case 6:
G_value = G_tab[(2*3)-num_ctrl_symbols-1];
break;
case 4 :
G_value = G_tab[(3*3)-num_ctrl_symbols-1];
break;
case 9 :
G_value = G_tab[(4*3)-num_ctrl_symbols-1];
break;
case 5:
G_value = G_tab[(5*3)-num_ctrl_symbols-1];
break;
case 3 :
G_value = G_tab[(6*3)-num_ctrl_symbols-1];
break;
default:
printf("Error getting G");
}
return(G_value);
}
int get_rep_num_SIB1_NB_IoT(uint8_t scheduling_info_sib1)
{
int value=0;
if(scheduling_info_sib1 >11)
{
printf("value not allowed for schedulinginfo for sib1");
} else {
switch(scheduling_info_sib1 % 3)
{
case 0:
value =4;
break;
case 1:
value =8;
break;
case 2:
value =16;
break;
}
}
return(value);
}
int get_start_frame_SIB1_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint8_t repetition)
{
int value=0;
uint16_t cell_id = frame_parms->Nid_cell ;
if(repetition == 4)
{
switch(cell_id %4)
{
case 0:
value =0;
break;
case 1:
value =16;
break;
case 2:
value =32;
break;
case 3:
value =48;
break;
}
} else if(repetition == 8) {
switch(cell_id %2)
{
case 0:
value =0;
break;
case 1:
value =16;
break;
}
} else if(repetition == 16) {
switch(cell_id %2)
{
case 0:
value =0;
break;
case 1:
value =1;
break;
}
} else {
printf("Error in getting the starting frame of SIB1 ");
}
return(value);
}

View File

@@ -0,0 +1,366 @@
/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/npbch_NB_IoT.c
* \Fucntions for the generation of broadcast channel (NPBCH) for NB_IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ, V. Savaux
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com , vincent.savaux@b-com.com
* \note
* \warning
*/
//#include "PHY/defs.h"
//#include "PHY/defs_NB_IoT.h"
//#include "PHY/CODING/extern.h"
//#include "PHY/CODING/lte_interleaver_inline.h"
//#include "extern_NB_IoT.h"
//#include "PHY/extern_NB_IoT.h"
//#include "PHY/sse_intrin.h"
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
#include "PHY/CODING/defs_NB_IoT.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
//#include "PHY/impl_defs_top_NB_IoT.h"
//#include "PHY/impl_defs_lte.h"
//#ifdef PHY_ABSTRACTION
//#include "SIMULATION/TOOLS/defs.h"
//#endif
//#ifdef OPENAIR2
//#include "PHY_INTERFACE/defs.h"
//#endif
#define NPBCH_A 34 // 34 for NB-IoT and 24 for LTE
int scrambling_npbch_REs_rel_13_5_0(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
int l,
uint32_t symbol_offset,
uint8_t pilots,
unsigned short id_offset,
uint8_t *reset,
uint32_t *x1,
uint32_t *x2,
uint32_t *s,
uint8_t *flag_32)
{
uint32_t tti_offset,aa;
uint8_t re;
uint8_t first_re,last_re;
uint8_t c_even,c_odd;
int16_t theta_re,theta_im;
int16_t data_re[frame_parms->nb_antennas_tx],data_im[frame_parms->nb_antennas_tx];
uint32_t mem_jj=0;
first_re = 0;
last_re = 12;
for (re=first_re; re<last_re; re++) { // re varies between 0 and 12 sub-carriers
if ((*jj)%32 == 0 && *flag_32 == 0){
*s = lte_gold_generic_NB_IoT(x1, x2, *reset);
*reset = 0;
mem_jj = *jj;
}
c_even = (*s>>*jj)&1;
c_odd = (*s>>(*jj+1))&1;
if (c_even == c_odd){
if(c_even){
theta_re = 0;
theta_im = -32767;
}else{
theta_re = 32767;
theta_im = 0;
}
}else{
if(c_even){
theta_re = 0;
theta_im = 32767;
}else{
theta_re = -32767;
theta_im = 0;
}
}
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || re%3 != id_offset) // if re is not a pilot
{
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
data_re[aa] = ((int16_t*)&txdataF[aa][tti_offset])[0];
data_im[aa] = ((int16_t*)&txdataF[aa][tti_offset])[1];
}
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] = (int16_t) (((int32_t) data_re[aa] * (int32_t) theta_re -
(int32_t) data_im[aa] * (int32_t) theta_im)>>15); //I //b_i
((int16_t*)&txdataF[aa][tti_offset])[1] = (int16_t) (((int32_t) data_im[aa] * (int32_t) theta_re +
(int32_t) data_re[aa] * (int32_t) theta_im)>>15); //Q //b_{i+1}
}
*jj = *jj + 2;
}
if (mem_jj == *jj) // avoid to shift lte_gold_generic_NB_IoT 2 times
{*flag_32 = 1;
}else
{*flag_32 = 0;
}
}
return(0);
}
int allocate_npbch_REs_in_RB(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
int16_t amp,
unsigned short id_offset,
uint32_t *re_allocated) // not used variable ??!!
{
MIMO_mode_t mimo_mode = (frame_parms->mode1_flag==1)?SISO:ALAMOUTI;
uint32_t tti_offset,aa;
uint8_t re;
int16_t gain_lin_QPSK;
uint8_t first_re,last_re;
int32_t tmp_sample1,tmp_sample2;
gain_lin_QPSK = (int16_t)((amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
first_re = 0;
last_re = 12;
for (re=first_re; re<last_re; re++) { // re varies between 0 and 12 sub-carriers
tti_offset = symbol_offset + re; // symbol_offset = 512 * L , re_offset = 512 - 3*12 , re
if (pilots != 1 || re%3 != id_offset) // if re is not a pilot
{
// diff_re = re%3 - id_offset;
if (mimo_mode == SISO) { //SISO mapping
*re_allocated = *re_allocated + 1; // variable incremented but never used
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[0] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
}
*jj = *jj + 1;
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
((int16_t*)&txdataF[aa][tti_offset])[1] += (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
}
*jj = *jj + 1;
} else if (mimo_mode == ALAMOUTI) {
*re_allocated = *re_allocated + 1;
((int16_t*)&tmp_sample1)[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample1)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// second antenna position n -> -x1*
((int16_t*)&tmp_sample2)[0] = (x0[*jj]==1) ? (gain_lin_QPSK) : -gain_lin_QPSK;
*jj=*jj+1;
((int16_t*)&tmp_sample2)[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK;
*jj=*jj+1;
// normalization for 2 tx antennas
((int16_t*)&txdataF[0][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample1)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[0][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample1)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[0] += (int16_t)((((int16_t*)&tmp_sample2)[0]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
((int16_t*)&txdataF[1][tti_offset])[1] += (int16_t)((((int16_t*)&tmp_sample2)[1]*ONE_OVER_SQRT2_Q15_NB_IoT)>>15);
// fill in the rest of the ALAMOUTI precoding
if ( pilots != 1 || (re+1)%3 != id_offset) {
((int16_t *)&txdataF[0][tti_offset+1])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+1])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+1])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+1])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
} else {
((int16_t *)&txdataF[0][tti_offset+2])[0] += -((int16_t *)&txdataF[1][tti_offset])[0]; //x1
((int16_t *)&txdataF[0][tti_offset+2])[1] += ((int16_t *)&txdataF[1][tti_offset])[1];
((int16_t *)&txdataF[1][tti_offset+2])[0] += ((int16_t *)&txdataF[0][tti_offset])[0]; //x0*
((int16_t *)&txdataF[1][tti_offset+2])[1] += -((int16_t *)&txdataF[0][tti_offset])[1];
re++; // skip pilots
*re_allocated = *re_allocated + 1;
}
re++; // adjacent carriers are taken care of by precoding
*re_allocated = *re_allocated + 1; // incremented variable but never used
}
}
}
return(0);
}
/**********************************************************
**********************************************************/
int generate_npbch(NB_IoT_eNB_NPBCH_t *eNB_npbch,
int32_t **txdataF,
int amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t *npbch_pdu,
uint8_t frame_mod64,
unsigned short NB_IoT_RB_ID,
uint8_t release_v13_5_0)
{
int i, l;
int id_offset;
uint32_t npbch_D,npbch_E;
uint8_t npbch_a[5]; // 34/8 =4.25 => 4 bytes and 2 bits
uint8_t RCC;
unsigned short bandwidth_even_odd;
unsigned short NB_IoT_start, RB_IoT_ID;
uint32_t pilots;
uint32_t jj=0;
uint32_t re_allocated=0;
uint32_t symbol_offset;
uint16_t amask=0;
///////////////////////////// for release 13.5.0 and above ////////////////////////
uint32_t ii=0;
uint8_t reset=1,flag_32=0;
uint32_t x1_v13_5_0, x2_v13_5_0 =0, s_v13_5_0 =0;
x2_v13_5_0 = (((frame_parms->Nid_cell+1) * (frame_mod64%8 + 1) * (frame_mod64%8 + 1) * (frame_mod64%8 + 1)) <<9) + frame_parms->Nid_cell;
//////////////////////////////////////////////////////////////////////////////////
frame_parms->flag_free_sf =1;
npbch_D = 16 + NPBCH_A;
npbch_E = 1600;
if (frame_mod64==0) {
bzero(npbch_a,5); // initializing input data stream , filling with zeros
bzero(eNB_npbch->npbch_e,npbch_E); // filling with "0" the table pbch_e[1600]
memset(eNB_npbch->npbch_d,LTE_NULL_NB_IoT,96); // filling with "2" the first 96 elements of table pbch_d[216]
for (i=0; i<5; i++) // set input bits stream
{
npbch_a[i] = npbch_pdu[i]; // in LTE 24 bits with 3 bytes, but in NB_IoT 34 bits will require 4 bytes+2 bits !! to verify
}
if (frame_parms->mode1_flag == 1) // setting CRC mask depending on the number of used eNB antennas
amask = 0x0000;
else {
switch (frame_parms->nb_antennas_tx) { // *****???? better replacing nb_antennas_tx_eNB by nb_antennas_tx_eNB_NB_IoT
case 1:
amask = 0x0000;
break;
case 2:
amask = 0xffff;
break;
}
}
ccode_encode_NB_IoT(NPBCH_A,2,npbch_a,eNB_npbch->npbch_d+96,amask); // step 1 CRC Attachment
RCC = sub_block_interleaving_cc_NB_IoT(npbch_D,eNB_npbch->npbch_d+96,eNB_npbch->npbch_w); // step 2 Channel Coding
lte_rate_matching_cc_NB_IoT(RCC,npbch_E,eNB_npbch->npbch_w,eNB_npbch->npbch_e); // step 3 Rate Matching
npbch_scrambling(frame_parms, // step 4 Scrambling
eNB_npbch->npbch_e,
npbch_E);
}
// testing if the total number of RBs is even or odd
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
RB_IoT_ID = NB_IoT_RB_ID;
// step 5, 6, 7 // modulation and mapping (slot 1, symbols 0..3)
for (l=3; l<14; l++) { // loop on OFDM symbols
if((l>=4 && l<=8) || (l>=11 && l<=13))
{
pilots =1;
} else {
pilots=0;
}
id_offset = frame_parms->Nid_cell % 3; // Cell_ID_NB_IoT % 3
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
}
symbol_offset = frame_parms->ofdm_symbol_size*l + NB_IoT_start; // symbol_offset = 512 * L + NB_IOT_RB start
allocate_npbch_REs_in_RB(frame_parms,
txdataF,
&jj,
symbol_offset,
&eNB_npbch->npbch_e[(frame_mod64/8)*(npbch_E>>3)],
pilots,
amp,
id_offset,
&re_allocated);
if(release_v13_5_0 == 1)
{
scrambling_npbch_REs_rel_13_5_0(frame_parms,
txdataF,
&ii,
l,
symbol_offset,
pilots,
id_offset,
&reset,
&x1_v13_5_0,
&x2_v13_5_0,
&s_v13_5_0,
&flag_32);
}
}
return(0);
}
/**********************************************************
**********************************************************/
void npbch_scrambling(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t *npbch_e,
uint32_t length) // 1600
{
int i;
uint8_t reset;
uint32_t x1, x2, s=0;
reset = 1;
x2 = frame_parms->Nid_cell;
for (i=0; i<length; i++) {
if ((i&0x1f)==0) {
s = lte_gold_generic_NB_IoT(&x1, &x2, reset);
reset = 0;
}
npbch_e[i] = (npbch_e[i]&1) ^ ((s>>(i&0x1f))&1);
}
}

View File

@@ -0,0 +1,493 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/nprach_eNb_NB_IoT.c
* function for NPRACH signal detection and Timing Advance estimation
* \author V. Savaux
* \date 2018
* \version 0.1
* \company b<>com
* \email: vincent.savaux@b-com.com
* \note
* \warning
*/
//#include "PHY/sse_intrin.h"
#include "PHY/defs_L1_NB_IoT.h"
#include "PHY/TOOLS/tools_defs.h" // to take into account the dft functions
#include "tables_nprach_NB_IoT.h"
#include "first_sc_NB_IoT.h"
//#include "PHY/extern.h"
//#include "prach.h"
//#include "PHY/LTE_TRANSPORT/if4_tools.h"
//#include "SCHED/defs.h"
//#include "SCHED/extern.h"
//#include "UTIL/LOG/vcd_signal_dumper.h"
int filter_xx[40] = {-2161, 453, 489, 570, 688, 838, 1014, 1209, 1420, 1639,
1862, 2082, 2295, 2495, 2677, 2837, 2969, 3072, 3142, 3178,
3178, 3142, 3072, 2969, 2837, 2677, 2495, 2295, 2082, 1862,
1639, 1420, 1209, 1014, 838, 688, 570, 489, 453, -2161}; // this is a low-pass filter
int16_t buffer_nprach[153600];
int16_t filtered_buffer[153600];
int16_t signal_compensed_re[153600];
int16_t signal_compensed_im[153600];
int16_t output_buffer[4800];
uint8_t NPRACH_detection_NB_IoT(int16_t *input_buffer,uint32_t input_length){
uint8_t cp_type = 0; // 0: short ; 1: extended
uint32_t nb_signal_samples,nb_noise_samples,n1,n2;
uint64_t energy_signal=0,energy_noise=0;
uint32_t n;
if(cp_type){
}else{
nb_signal_samples = (uint32_t)(((uint64_t) 62670*input_length)/100000);
nb_noise_samples = input_length - nb_signal_samples;
}
n1 = nb_signal_samples;
n2 = nb_noise_samples;
// printf("n samples = %i %i\n",FRAME_LENGTH_COMPLEX_SAMPLESx,nb_signal_samples);
for(n=0;n<nb_signal_samples;n++){
energy_signal += (((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/n1);
//energy_signal += (uint64_t)(((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/10);
}
for(n=nb_signal_samples;n<input_length;n++){
energy_noise += (((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/n2);
//energy_noise += (uint64_t)(((uint64_t)input_buffer[2*n]*input_buffer[2*n] + (uint64_t)input_buffer[2*n+1]*input_buffer[2*n+1])/10);
}
//printf("energies = %ld %ld\n",energy_signal,energy_noise);
if ((uint64_t)(((uint64_t) energy_signal))<(uint64_t)energy_noise>>6){
return 1;
}else{
return 0;
}
}
/*uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB *eNB,
int16_t *Rx_sub_sampled_buffer,
uint16_t sub_sampling_rate,
uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
uint32_t estimated_TA_coarse,
uint8_t coarse){
uint16_t length_seq_NPRACH,length_CP,length_symbol; // in number of samples, per NPRACH preamble: 4 sequences ; length of CP in number of samples
uint16_t length_CP_0 = 2048;//eNB->frame_parms.prach_config_common.nprach_CP_Length; //NB-IoT: 0: short, 1: long
uint32_t fs=30720000; //NB-IoT: sampling frequency of Rx_buffer, must be defined somewhere
uint32_t fs_sub_sampled;
uint16_t length_correl_window,base_length;
int64_t *vec_correlation;
int64_t max_correlation = 0;
//int16_t **matrix_received_signal_re, **matrix_received_signal_im;
uint16_t offset_estimation, offset_start; // offset due to first coarse estimation
// double *** mat_to_phase_estimation_re, *** mat_to_phase_estimation_im;
int64_t average_mat_to_phase_re, average_mat_to_phase_im;
float estimated_phase, estimated_CFO, CFO_correction, CFO_correction_k;
// int16_t *vec_CFO_compensation_re, *vec_CFO_compensation_im;
// int16_t *vec_received_signal_re, *vec_received_signal_im;
int16_t *signal_CFO_compensed_re, *signal_CFO_compensed_im;
int32_t **sub_sequence_reference_re, **sub_sequence_reference_im;
int32_t *sequence_reference_re, *sequence_reference_im;
uint32_t TA_sample_estimated = 0;
int32_t A;//,B;
int n,k,m,o;
int32_t pow_n1 = 1;
uint32_t index_av_ph1, index_av_ph2;
if (coarse){ // coarse = 1: first estimation at 240 kHz
length_seq_NPRACH = (length_CP_0+5*8192)/128;
length_CP = length_CP_0/128;
length_symbol = 64;
offset_start = 0;
length_correl_window = 80; //20512/sub_sampling_rate; // corresponds to the max TA, i.e. 667.66 micro s //FRAME_LENGTH_COMPLEX_SUB_SAMPLES - 4*length_seq_NPRACH+1;
fs_sub_sampled = (uint32_t)fs/128;
}else{
length_seq_NPRACH = (length_CP_0+5*8192)/16;
length_CP = length_CP_0/16;
length_symbol = 8192/16;
offset_estimation = 8 * estimated_TA_coarse;
base_length = 32;
// we arbitrarily define the length of correl window as base_length samples.
// Check if offset_estimation is close to zero or 1282 (max lentgh of delays)
if (offset_estimation-base_length/2 <0){
offset_start = 0;
length_correl_window = offset_estimation + base_length/2;
}
if (offset_estimation+base_length/2 >1281){
offset_start = offset_estimation-base_length/2;
length_correl_window = base_length;// 512 - (1282-offset_estimation);
}
if ((offset_estimation-base_length/2 >=0) && (offset_estimation+base_length/2 <=1281)){
offset_start = offset_estimation-base_length/2;
length_correl_window = base_length;
}
err
fs_sub_sampled = (uint32_t)fs/16;
}
//fs_sub_sampled = (uint32_t)fs/sub_sampling_rate;
// Method: MMSE (sub-optimal) CFO estimation -> CFO compensation -> ML (sub-optimal) TA estimation /============================================================/
//matrix_received_signal_re = (int16_t **)malloc(4*sizeof(int16_t *));
//matrix_received_signal_im = (int16_t **)malloc(4*sizeof(int16_t *));
// for (k=0;k<4;k++){ // # sequence
// matrix_received_signal_re[k] = (int16_t *)malloc((length_seq_NPRACH-length_CP)*sizeof(int16_t)); // avoid CP in this process
// matrix_received_signal_im[k] = (int16_t *)malloc((length_seq_NPRACH-length_CP)*sizeof(int16_t)); // avoid CP in this process
// }
signal_CFO_compensed_re = (int16_t *)malloc(4*length_seq_NPRACH*sizeof(int16_t)); /////to do : exact size of tables
signal_CFO_compensed_im = (int16_t *)malloc(4*length_seq_NPRACH*sizeof(int16_t));
sub_sequence_reference_re = (int32_t **)malloc(4*sizeof(int32_t *));
sub_sequence_reference_im = (int32_t **)malloc(4*sizeof(int32_t *));
for (k=0;k<4;k++){
sub_sequence_reference_re[k] = (int32_t *)calloc(length_symbol,sizeof(int32_t));
sub_sequence_reference_im[k] = (int32_t *)calloc(length_symbol,sizeof(int32_t));
}
sequence_reference_re = (int32_t *)malloc(4*length_seq_NPRACH*sizeof(int32_t));
sequence_reference_im = (int32_t *)malloc(4*length_seq_NPRACH*sizeof(int32_t));
vec_correlation = (int64_t *)calloc(length_correl_window,sizeof(int64_t));
for (n=0;n<length_correl_window;n++){ // loops over samples %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// MMSE (sub-optimal) CFO estimation /============================================================/
average_mat_to_phase_re = 0;
average_mat_to_phase_im = 0;
for (k=0;k<4;k++){ // # sequence
for (o=0;o<4;o++){ // # symbol in sequence
for (m=0;m<length_symbol;m++){ ///// creation of two variables for tab indexes "n+offset_start+k*length_seq_NPRACH+length_CP+o*length_symbol+m"
index_av_ph1 = (n+offset_start+k*length_seq_NPRACH+length_CP+o*length_symbol+m)<<1;
index_av_ph2 = index_av_ph1 + (length_symbol<<1);
average_mat_to_phase_re = average_mat_to_phase_re
- (int64_t)(Rx_sub_sampled_buffer[index_av_ph1]
* Rx_sub_sampled_buffer[index_av_ph2])
- (int64_t)(Rx_sub_sampled_buffer[index_av_ph1+1]
* Rx_sub_sampled_buffer[index_av_ph2+1]);
average_mat_to_phase_im = average_mat_to_phase_im
- (int64_t)(Rx_sub_sampled_buffer[index_av_ph1+1]
* Rx_sub_sampled_buffer[index_av_ph2])
+ (int64_t)(Rx_sub_sampled_buffer[index_av_ph1]
* Rx_sub_sampled_buffer[index_av_ph2+1]);
}
}
}
average_mat_to_phase_re = average_mat_to_phase_re/(16*length_symbol);
average_mat_to_phase_im = average_mat_to_phase_im/(16*length_symbol);
estimated_phase = atan2f(average_mat_to_phase_im,average_mat_to_phase_re);
estimated_CFO = ((float)fs*estimated_phase)/(8192*2*(float)M_PI);
CFO_correction = 2*(float)M_PI*estimated_CFO/fs_sub_sampled;
// CFO compensation /============================================================/
for (k=0;k<4*length_seq_NPRACH;k++){ ///// creation of two variables for tab indexes /// replace "2*(float)M_PI*estimated_CFO*k/fs_sub_sampled" and "2*(n+offset_start+k)"
CFO_correction_k = (float)k*CFO_correction;
signal_CFO_compensed_re[k] = (int16_t)((Rx_sub_sampled_buffer[(n+offset_start+k)<<1] * (int32_t)(cosf(CFO_correction_k)*32767)
- Rx_sub_sampled_buffer[((n+offset_start+k)<<1)+1] * (int32_t)(sinf(CFO_correction_k)*32767))>>15);
signal_CFO_compensed_im[k] = (int16_t)((Rx_sub_sampled_buffer[(n+offset_start+k)<<1] * (int32_t)(sinf(CFO_correction_k)*32767)
+ Rx_sub_sampled_buffer[((n+offset_start+k)<<1)+1] * (int32_t)(cosf(CFO_correction_k)*32767))>>15);
}
// sub-optimal ML TA estimation /============================================================/
for (k=0;k<4;k++){ // loop over the 4 sequences of a preamble
pow_n1 = 1;
for (o=0;o<5;o++){ // loop over the symbols of a sequence
for (m=0;m<length_symbol;m++){
// mon_variable=k*length_seq_NPRACH + o*length_symbol + length_CP + m ///////////////////////////////////////////////////////////////////////////////////////////////
sub_sequence_reference_re[k][m] = sub_sequence_reference_re[k][m] + pow_n1 * signal_CFO_compensed_re[k*length_seq_NPRACH + o*length_symbol + length_CP + m] / 5; // average over the 5 symbols of a group
sub_sequence_reference_im[k][m] = sub_sequence_reference_im[k][m] + pow_n1 * signal_CFO_compensed_im [k*length_seq_NPRACH + o*length_symbol + length_CP + m]/ 5; // average over the 5 symbols of a group
}
pow_n1 = -pow_n1;
}
}
pow_n1 = 1;
for (k=0;k<4;k++){ // loop over the 4 sequences of a preamble
pow_n1 = 1;
for (o=0;o<5;o++){ // loop over the symbols of a sequence // mon_variable=k*length_seq_NPRACH+o*length_symbol +length_CP +m///////////////////////////////////////////////
for (m=0;m<length_symbol;m++){
sequence_reference_re[k*length_seq_NPRACH+o*length_symbol +length_CP +m] = pow_n1 * sub_sequence_reference_re[k][m];
sequence_reference_im[k*length_seq_NPRACH+o*length_symbol +length_CP +m] = pow_n1 * sub_sequence_reference_im[k][m];
}
pow_n1 = -pow_n1;
}
}
for (k=0;k<4;k++){ // loop over the 4 sequences of a preamble
for (m=0;m<length_CP;m++){
sequence_reference_re[k*length_seq_NPRACH+m] = -sub_sequence_reference_re[k][length_symbol-length_CP+m];
sequence_reference_im[k*length_seq_NPRACH+m] = -sub_sequence_reference_im[k][length_symbol-length_CP+m];
}
}
// for (m=0;m<length_seq_NPRACH;m++){
// vec_correlation[n] = vec_correlation[n] + (double)signal_CFO_compensed_re[m] * sequence_reference_re[m] + (double)signal_CFO_compensed_im[m] * sequence_reference_im[m];
// printf("seq=%i\n",sequence_reference_re[m]);
// }
for (m=0;m<4*length_seq_NPRACH;m++){
A = (int64_t)((signal_CFO_compensed_re[m] * sequence_reference_re[m]
+ signal_CFO_compensed_im[m] * sequence_reference_im[m]));
//B = -(int32_t)(((int64_t)signal_CFO_compensed_re[m] * (int64_t)sequence_reference_im[m]
// - (int64_t)signal_CFO_compensed_im[m] * (int64_t)sequence_reference_re[m])>>32);
vec_correlation[n] = vec_correlation[n] + A;//(int32_t)(((int64_t)A*(int64_t)A + 2*(int64_t)B*(int64_t)B)>>32);
}
for (k=0;k<4;k++){ // re-initialize sub_sequence_reference matrices ////////////////////////////////////////////
for (m=0;m<length_symbol;m++){
sub_sequence_reference_re[k][m] = 0;
sub_sequence_reference_im[k][m] = 0;
}
}
}
for (n=0;n<length_correl_window;n++){
//printf("\ncorr=%li \n",vec_correlation[n]);
if(vec_correlation[n]>=max_correlation){
max_correlation = vec_correlation[n];
TA_sample_estimated = offset_start+ n;
}
}
free(vec_correlation);
for (k=0;k<4;k++){ // # sequence
//free(matrix_received_signal_re[k]);
err//free(matrix_received_signal_im[k]);
free(sub_sequence_reference_re[k]);
free(sub_sequence_reference_im[k]);
}
//free(matrix_received_signal_re);
//free(matrix_received_signal_im);
free(signal_CFO_compensed_re);
free(signal_CFO_compensed_im);
free(sub_sequence_reference_re);
free(sub_sequence_reference_im);
return TA_sample_estimated;
} */
uint16_t subcarrier_estimation(int16_t *input_buffer){
uint16_t estimated_sc=0;
int16_t *s_n_re, *s_n_im;
uint16_t k,m,n;
int64_t max_correl_sc_m = 0;
int64_t max_correl_sc_k = 0;
int64_t max_correl_sc_glob = 0;
int n_start_offset = 1920; // start at t=8 ms
for (k=0;k<12;k++){
s_n_re = &s_n_12_re[k*336];
s_n_im = &s_n_12_im[k*336];
for (m=0;m<20;m++){
for (n=0;n<336;n++){
max_correl_sc_m = max_correl_sc_m +
(int16_t)(((int32_t)input_buffer[(m<<1)+((n+n_start_offset)<<1)]*(int32_t)s_n_re[n] )>>15)
+ (int16_t)(((int32_t)input_buffer[(m<<1)+((n+n_start_offset)<<1)+1]*(int32_t)s_n_im[n])>>15);
}
if (max_correl_sc_m>max_correl_sc_k){
max_correl_sc_k = max_correl_sc_m;
}
max_correl_sc_m = 0;
}
//printf("correl = %li\n",max_correl_sc_k);
if (max_correl_sc_k>max_correl_sc_glob){
max_correl_sc_glob = max_correl_sc_k;
estimated_sc = k;
}
max_correl_sc_k = 0;
}
return estimated_sc;
}
int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate){ // void function ////// adding flag for switching between output_buffers
int k;
uint32_t L;
//int16_t *output_buffer;
int16_t *p_output_buffer;
L = (uint32_t)(length_input / sub_sampling_rate);
*length_ouput = L; ///// to remove
for (k=0;k<L;k++){
output_buffer[k<<1] = input_buffer[sub_sampling_rate*(k<<1)];
output_buffer[(k<<1)+1] = input_buffer[sub_sampling_rate*(k<<1)+1];
}
// for (k=0;k<2*L;k++){
// printf("%i\n",output_buffer[k]);
// }
p_output_buffer=output_buffer;
return p_output_buffer;
}
void filtering_signal(int16_t *input_buffer, int16_t *filtered_buffer, uint32_t FRAME_LENGTH_COMPLEX_SAMPLESx){
int n;
//int k;
//float f_s_RB22 = 1807.5;
//float f_s = 7680;
//int16_t *signal_compensed_re, *signal_compensed_im;
int16_t *cos_x, *sin_x;
cos_x = cos_x_rb22;
sin_x = sin_x_rb22;
for (n=0;n<FRAME_LENGTH_COMPLEX_SAMPLESx;n++){
signal_compensed_re[n] = (int16_t)((input_buffer[n<<1] * (int32_t)(cos_x[n])
+ input_buffer[(n<<1)+1] * (int32_t)(sin_x[n]))>>15);
signal_compensed_im[n] = (int16_t)((- input_buffer[n<<1] * (int32_t)(sin_x[n])
+ input_buffer[(n<<1)+1] * (int32_t)(cos_x[n]))>>15);
filtered_buffer[n<<1] = signal_compensed_re[n];
filtered_buffer[(n<<1)+1] = signal_compensed_im[n];
}
/*for (n=0;n<FRAME_LENGTH_COMPLEX_SAMPLESx-10;n++){
if (n<20){
for (k=-n;k<20;k++){
filtered_buffer[n<<1] = filtered_buffer[n<<1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_re[n+k])>>15);
filtered_buffer[(n<<1)+1] = filtered_buffer[(n<<1)+1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_im[n+k])>>15);
}
}else{
for (k=-20;k<20;k++){
filtered_buffer[n<<1] = filtered_buffer[n<<1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_re[n+k])>>15);
filtered_buffer[(n<<1)+1] = filtered_buffer[(n<<1)+1] + (int16_t)(((int32_t)filter_xx[20+k]*(int32_t)signal_compensed_im[n+k])>>15);
}
}
}*/
}
uint32_t process_nprach_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int frame, uint8_t subframe, uint16_t *rnti, uint16_t *preamble_index, uint16_t *timing_advance){
//uint32_t estimated_TA_coarse=0;
//uint32_t estimated_TA;
int16_t *Rx_sub_sampled_buffer_128; // *Rx_sub_sampled_buffer_16;
uint16_t sub_sampling_rate; //NB-IoT: to be defined somewhere
uint32_t FRAME_LENGTH_COMPLEX_SAMPLESx; // NB-IoT: length of input buffer, to be defined somewhere
uint32_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES; // Length of buffer after sub-sampling
uint32_t *length_ouput; // Length of buffer after sub-sampling
// uint8_t coarse=1; // flag that indicate the level of TA estimation
int16_t *Rx_buffer;
//int16_t *filtered_buffer;
//int n;
//// 1. Coarse TA estimation using sub sampling rate = 128, i.e. fs = 240 kHz
FRAME_LENGTH_COMPLEX_SAMPLESx = 10*eNB->frame_parms.samples_per_tti;
Rx_buffer = (int16_t*)&eNB->common_vars.rxdata[0][0][0]; // get the whole frame
memcpy(&buffer_nprach[0],&Rx_buffer[0],307200);
//filtered_buffer = (int16_t *)calloc(2*FRAME_LENGTH_COMPLEX_SAMPLESx,sizeof(int16_t)); // calcule du taille exacte du tableau 76800
memset(filtered_buffer,0,307200);
filtering_signal(buffer_nprach,filtered_buffer,FRAME_LENGTH_COMPLEX_SAMPLESx);
// Sub-sampling stage /============================================================/
sub_sampling_rate = FRAME_LENGTH_COMPLEX_SAMPLESx/2400; // gives the sub-sampling rate leading to f=240 kHz
length_ouput = &FRAME_LENGTH_COMPLEX_SUB_SAMPLES;
Rx_sub_sampled_buffer_128 = sub_sampling_NB_IoT(filtered_buffer,FRAME_LENGTH_COMPLEX_SAMPLESx,length_ouput, sub_sampling_rate);
// Detection and TA estimation stage /============================================================/
if (NPRACH_detection_NB_IoT(Rx_sub_sampled_buffer_128,*length_ouput)){
/* estimated_TA_coarse = TA_estimation_NB_IoT(eNB,
Rx_sub_sampled_buffer_128,
sub_sampling_rate,
FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
estimated_TA_coarse,
coarse);
// 2. Fine TA estimation using sub sampling rate = 16, i.e. fs = 1.92 MHz
// Sub-sampling stage /============================================================/
//// sub_sampling_rate = FRAME_LENGTH_COMPLEX_SAMPLESx/(2400*8);
Rx_sub_sampled_buffer_16 = sub_sampling_NB_IoT(filtered_buffer,FRAME_LENGTH_COMPLEX_SAMPLESx,length_ouput, sub_sampling_rate);
// Fine TA estimation stage /============================================================/
// start1 = clock();
coarse = 0;
estimated_TA = TA_estimation_NB_IoT(eNB,
Rx_sub_sampled_buffer_16,
sub_sampling_rate,
FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
estimated_TA_coarse,
coarse); //
// Needs to be stored in a variable in PHY_VARS_eNB_NB_IoT structure
//for (n=0;n<FRAME_LENGTH_COMPLEX_SAMPLESx;n++){
//printf(" buf%i= %i",n,Rx_sub_sampled_buffer_128[2*n]);
// fprintf(f," %i %i ",Rx_buffer[2*n],Rx_buffer[2*n+1]);
//fprintf(f,"%i \n",Rx_buffer[2*n+1]);
//}*/
printf("\ndetection !!! at frame %i \n",frame);
//eNB->preamble_index_NB_IoT = subcarrier_estimation(Rx_sub_sampled_buffer_128); // c'est un uint16_t
*preamble_index = subcarrier_estimation(Rx_sub_sampled_buffer_128);
*timing_advance = 0;
*rnti = 1 + frame/4;
printf("estimated subaccier = %i\n",*preamble_index);
return 1;//estimated_TA;
}else{
return 0;
}
// }
return 0;
}

View File

@@ -0,0 +1,187 @@
/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/npss_NB_IoT.c
* \Generation of Narrowband Primary Synchronisation Signal(NPSS) for NB-IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
//#include "PHY/defs.h"
///////////////#include "PHY/defs_nb_iot.h"
//#include "PHY/extern.h"
#include <math.h>
#include "proto_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
//#include "PHY/impl_defs_top_NB_IoT.h"
//or #include "PHY/defs_nb_iot.h"
#include "PHY/LTE_REFSIG/primary_synch_NB_IoT.h"
int generate_npss_NB_IoT(int32_t **txdataF,
short amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
unsigned short symbol_offset, // symbol_offset should equal to 3 for NB-IoT
unsigned short slot_offset,
unsigned short RB_IoT_ID) // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
{
unsigned short c,aa,a,s;
unsigned short slot_id;
short *primary_sync;
unsigned short NB_IoT_start; // Index of the first RE in the RB dedicated for NB-IoT
unsigned short bandwidth_even_odd;
frame_parms->flag_free_sf =1;
slot_id = slot_offset; // The id(0..19) of the slot including the NPSS signal // For NB-IoT, slod_id should be 10 (SF5)
primary_sync = primary_synch_NB_IoT; // primary_synch_NB_IoT[264] of primary_synch_NB_IoT.h
// Signal amplitude
a = (frame_parms->nb_antennas_tx == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15;
// Testing if the total number of RBs is even or odd (i.e. Identification of the bandwidth: 1.4, 3, 5, 10, ... MHz)
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 for even, 1 for odd
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
}
// For the In-band or Stand-alone case the REs of NPSS signal have the same positions
for (s=0; s<11; s++ ) // loop on OFDM symbols
{
for (c=0; c<12; c++) { // loop on NB-IoT carriers
((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )] =
(a * primary_sync[2*c + (2*12*s)]) >> 15;
((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )+1] =
(a * primary_sync[2*c + (2*12*s) + 1]) >> 15;
}
}
}
return(0);
}
// int generate_npss_NB_IoT(int32_t **txdataF,
// short amp,
// LTE_DL_FRAME_PARMS *frame_parms,
// unsigned short symbol_offset, // symbol_offset should equal to 3 for NB-IoT
// unsigned short slot_offset,
// unsigned short RB_IoT_ID) // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
// {
// unsigned short c,aa,a,s;
// unsigned short slot_id;
// short *primary_sync;
// unsigned short NB_IoT_start; // Index of the first RE in the RB dedicated for NB-IoT
// unsigned short bandwidth_even_odd;
// unsigned short UL_RB_ID_NB_IoT; // index of the NB-IoT RB
// unsigned char poffset=0, pilot=0; // poffset: base frequency offset of pilots; pilot: LTE pilot flag
// UL_RB_ID_NB_IoT = frame_parms->NB_IoT_RB_ID; // index of RB dedicated to NB-IoT
// slot_id = slot_offset; // The id(0..19) of the slot including the NPSS signal // For NB-IoT, slod_id should be 10 (SF5)
// primary_sync = primary_synch_NB_IoT; // primary_synch_NB_IoT[264] of primary_synch_NB_IoT.h
// // Signal amplitude
// a = (frame_parms->nb_antennas_tx == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15;
// // Testing if the total number of RBs is even or odd (i.e. Identification of the bandwidth: 1.4, 3, 5, 10, ... MHz)
// bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 for even, 1 for odd
// for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
// if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
// { // RB in first half (below DC)
// // NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
// NB_IoT_start = UL_RB_ID_NB_IoT*12 + frame_parms->first_carrier_offset;
// } else { // RB in the second half (above DC): DC is taken into account
// // NB_IoT_start = 1+ (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
// NB_IoT_start = 1 + bandwidth_even_odd*6 + 6*(2*UL_RB_ID_NB_IoT - (frame_parms->N_RB_DL+bandwidth_even_odd));
// }
// // For the In-band or Stand-alone case the REs of NPSS signal have the same positions
// for (s=0; s<11; s++ ) // loop on OFDM symbols
// {
// // CRS (LTE pilot) position within subframe in time
// // Note that pilot position takes into account symbol_offset value
// if (frame_parms->mode1_flag==1){ // SISO mode
// if (s==1 || s==4 || s==8){
// pilot = 1;
// if (s==1 || s==8){
// poffset = 3;
// }
// }
// }
// if (pilot == 0){
// for (c=0; c<12; c++) { // loop on NB-IoT carriers
// ((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )] =
// (a * primary_sync[2*c + (2*12*s)]) >> 15;
// ((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )+1] =
// (a * primary_sync[2*c + (2*12*s) + 1]) >> 15;
// }
// }
// else{
// for (c=0; c<12; c++) { // loop on NB-IoT carriers
// if ((c!=(frame_parms->nushift+poffset)) &&
// (c!=((frame_parms->nushift+poffset+6)%12)))
// {
// ((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )] =
// (a * primary_sync[2*c + (2*12*s)]) >> 15;
// ((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )+1] =
// (a * primary_sync[2*c + (2*12*s) + 1]) >> 15;
// }
// }
// }
// pilot = 0;
// poffset = 0;
// }
// }
// return(0);
// }
/* (for LTE)
int generate_pss_emul(PHY_VARS_eNB_NB_IoT *phy_vars_eNb,uint8_t sect_id)
{
msg("[PHY] EMUL eNB generate_pss_emul eNB %d, sect_id %d\n",phy_vars_eNb->Mod_id,sect_id);
eNB_transport_info[phy_vars_eNb->Mod_id][phy_vars_eNb->CC_id].cntl.pss=sect_id;
return(0);
}
*/

View File

@@ -0,0 +1,295 @@
/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/nsss_NB_IoT.c
* \Generation of Narrowband Secondary Synchronisation Signal(NSSS) for NB-IoT, TS 36-212, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
//#include <math.h>
#include "PHY/defs_L1_NB_IoT.h"
#include "proto_NB_IoT.h"
//#include "PHY/defs_NB_IoT.h" // not can be replaced by impl_defs_lte_NB_IoT & impl_defs_top_NB_IoT if "msg" function is not used
//#include "defs.h"
//#include "PHY/extern_NB_IoT.h"
//#include "PHY/extern.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
//#include "PHY/impl_defs_top_NB_IoT.h"
#include "nsss_NB_IoT.h"
int generate_sss_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint16_t symbol_offset, // symbol_offset = 3 for NB-IoT
uint16_t slot_offset,
unsigned short frame_number, // new attribute (Get value from higher layer), it does not exist for LTE
unsigned short RB_IoT_ID) // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
{
uint8_t aa,Nid2,f,q,s,c,u;
int16_t *d;
uint16_t n_f,Nid_NB_IoT;
unsigned short a;
uint16_t slot_id; // slot_id = 17 in NB_IoT
unsigned short bandwidth_even_odd;
unsigned short NB_IoT_start;
frame_parms->flag_free_sf =1;
n_f = frame_number;
Nid_NB_IoT = frame_parms->Nid_cell; // supposing Cell_Id of LTE = Cell_Id of NB-IoT // if different , NB_IOT_DL_FRAME_PARMS should be includes as attribute
f = (n_f/2) % 4; // f = 0, 1, 2, 3
q = Nid_NB_IoT/126; // q = 0, 1, 2, 3
u = (Nid_NB_IoT % 126);
Nid2 = q*4 + f; // Nid2 = 0..15
switch (Nid2) {
case 0:
d = d0f0;
break;
case 1:
d = d0f1;
break;
case 2:
d = d0f2;
break;
case 3:
d = d0f3;
break;
case 4:
d = d1f0;
break;
case 5:
d = d1f1;
break;
case 6:
d = d1f2;
break;
case 7:
d = d1f3;
break;
case 8:
d = d2f0;
break;
case 9:
d = d2f1;
break;
case 10:
d = d2f2;
break;
case 11:
d = d2f3;
case 12:
d = d3f0;
break;
case 13:
d = d3f1;
break;
case 14:
d = d3f2;
break;
case 15:
d = d3f3;
break;
default:
msg("[NSSS] ERROR\n");
return(-1);
}
slot_id = slot_offset;
// Signal amplitude
a = (frame_parms->nb_antennas_tx == 1) ? amp: (amp*ONE_OVER_SQRT2_Q15_NB_IoT)>>15;
// Testing if the total number of RBs is even or odd (i.e. Identification of the bandwidth: 1.4, 3, 5, 10, ... MHz)
bandwidth_even_odd = frame_parms->N_RB_DL % 2; // 0 even, 1 odd
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
if(RB_IoT_ID < (frame_parms->N_RB_DL/2))
{
NB_IoT_start = frame_parms->ofdm_symbol_size - 12*(frame_parms->N_RB_DL/2) - (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
} else {
NB_IoT_start = 1 + (bandwidth_even_odd*6) + 12*(RB_IoT_ID%(int)(ceil(frame_parms->N_RB_DL/(float)2)));
}
// For the In-band or Stand-alone case the REs of NPSS signal have the same positions
for (s=0; s<11; s++ ) // loop on OFDM symbols
{
for (c=0; c<12; c++) { // loop on NB-IoT carriers
((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )] =
(a * d[(2*u*132) + (2*c) + (2*s*12) ]) >> 15;
((short*)txdataF[aa])[2*( (slot_id*7*frame_parms->ofdm_symbol_size) + ((symbol_offset+s)*frame_parms->ofdm_symbol_size) + NB_IoT_start + c )+1] =
(a * d[(2*u*132) + (2*c) + (2*s*12) + 1]) >> 15;
}
}
}
return(0);
}
int rx_nsss_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int32_t *tot_metric)
{
uint8_t Nid2,q_est,u_est;
NB_IoT_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
int l,k,m;
int toto=0;
int16_t *d, *nsss_sf;
int32_t nsss_ext[2][132]; // up to 2 rx antennas ?
int32_t metric; // correlation metric
// we suppose we are in NSSS subframe, after DFT
// this could be changed in further version
for (l=0;l<11;l++){
toto = nsss_extract_NB_IoT(ue,frame_parms,nsss_ext,l);
}
// now do the Cell ID estimation based on the precomputed sequences in PHY/LTE_TRANSPORT/nsss_NB_IoT.h
*tot_metric = -99999999;
nsss_sf = (int16_t*)&nsss_ext[0][0];
for (Nid2=0;Nid2<16;Nid2++){
switch (Nid2) {
case 0:
d = d0f0;
break;
case 1:
d = d0f1;
break;
case 2:
d = d0f2;
break;
case 3:
d = d0f3;
break;
case 4:
d = d1f0;
break;
case 5:
d = d1f1;
break;
case 6:
d = d1f2;
break;
case 7:
d = d1f3;
break;
case 8:
d = d2f0;
break;
case 9:
d = d2f1;
break;
case 10:
d = d2f2;
break;
case 11:
d = d2f3;
case 12:
d = d3f0;
break;
case 13:
d = d3f1;
break;
case 14:
d = d3f2;
break;
case 15:
d = d3f3;
break;
default:
msg("[NSSS] ERROR\n");
return(-1);
}
for (k=0;k<126;k++){ // corresponds to u in standard
metric = 0;
for (m=0;m<132;m++){ // 132 resource elements in NSSS subframe
metric += (int32_t)d[(k*126+m)<<1] * (int32_t)nsss_sf[(k*126+m)<<1] +
(int32_t)d[((k*126+m)<<1)+1] * (int32_t)nsss_sf[((k*126+m)<<1)+1]; // real part of correlation
}
if (metric > *tot_metric){
q_est = Nid2/4;
u_est = k;
ue->frame_parms.Nid_cell = q_est*126 + u_est;
}
}
}
return(0);
}
int nsss_extract_NB_IoT(PHY_VARS_UE_NB_IoT *ue,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **nsss_ext,
int l)
{
uint8_t i,aarx;
unsigned short UL_RB_ID_NB_IoT; // index of RB dedicated to NB-IoT
int32_t *nsss_rxF,*nsssF_ext;
int32_t **rxdataF;
int first_symbol_offset = 3; // NSSS starts at third symbol in subframe
UL_RB_ID_NB_IoT = frame_parms->NB_IoT_RB_ID;
for (aarx=0; aarx<frame_parms->nb_antennas_rx; aarx++) {
rxdataF = ue->common_vars.common_vars_rx_data_per_thread[0].rxdataF; // Note that
nsssF_ext = &nsss_ext[aarx][l*12];
if (UL_RB_ID_NB_IoT <= (frame_parms->N_RB_DL>>1)) { // NB-IoT RB is in the first half
nsss_rxF = &rxdataF[aarx][(UL_RB_ID_NB_IoT*12 + frame_parms->first_carrier_offset + ((l+first_symbol_offset)*(frame_parms->ofdm_symbol_size)))];
}// For second half of RBs skip DC carrier
else{ // NB-IoT RB is in the second half
nsss_rxF = &rxdataF[aarx][(1 + 6*(2*UL_RB_ID_NB_IoT - frame_parms->N_RB_DL) + ((l+first_symbol_offset)*(frame_parms->ofdm_symbol_size)))];
//dl_ch0++;
}
for (i=0; i<12; i++) {
nsssF_ext[i]=nsss_rxF[i];
}
}
return(0);
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,133 @@
clear all
% nsss_gen / matlab
% Copyright 2016 b<>com. All rights reserved.
% description: generation of NSSS subframe
% Reference: 3GPP TS36.211 release 13
% author: Vincent Savaux, b<>com, Rennes, France
% email: vincent.savaux@b-com.com
% Input : \
% Output : matrix NSSS_frame
% Parameters
% frame_number = 100;
% cellID = 200;
% % % Mapping results to estimated u-3
SNR_start = -10;
SNR_end = 2;
vec_SNR = SNR_start : 2 : SNR_end;
N_loop = 40;
Proba_fail = zeros(1,length(vec_SNR));
mat_bn = zeros(4,128); % mat_bn contains the 4 possible Hadamard sequences defined in the standard
mat_bn(1,:) = ones(1,128);
mat_bn(2,:) = [1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 ...
-1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 ...
1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 ...
-1 1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 -1 ...
1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 ...
-1 1 1 -1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 ...
1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1];
mat_bn(3,:) = [1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 ...
-1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 ...
-1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 ...
1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 ...
1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 ...
-1 1 1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 ...
-1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1];
mat_bn(4,:) = [1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 1 ...
-1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 ...
-1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 ...
1 -1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 1 -1 -1 1 1 ...
-1 -1 1 -1 1 1 -1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 ...
1 -1 -1 1 1 -1 -1 1 -1 1 1 -1 -1 1 1 -1 1 -1 -1 ...
1 -1 1 1 -1 1 -1 -1 1 1 -1 -1 1 -1 1 1 -1];
mat_bn = [mat_bn,mat_bn(:,1:4)]; % see the definition of m in stadard
mat_theta_f = zeros(4,132); % mat_bn contains the 4 possible phase sequences defined in the standard
mat_theta_f(1,:) = ones(1,132);
mat_theta_f(2,:) = repmat([1,-j,-1,j],1,33);
mat_theta_f(3,:) = repmat([1,-1],1,66);
mat_theta_f(4,:) = repmat([1,j,-1,-j],1,33);
mat_16_theta = round(kron(mat_theta_f,ones(4,1))); % mat_bn contains the 4x4=16 possible pseudo-random sequences
mat_16_bn = repmat(mat_bn,4,1);
mat_16 = mat_16_theta.*mat_16_bn;
corresponding_values = zeros(16,2); % first column for q, second for theta_f
corresponding_values(:,1) = repmat([0;1;2;3],4,1); % mapping column to q
corresponding_values(:,2) = kron([0;1;2;3],ones(4,1)); % mapping column to theta_f
for k = 1 : length(vec_SNR) % loop on the SNR
N_fail = 0;
for loop = 1 : N_loop
SNR = vec_SNR(k);
frame_number = 2*randi([0,3],1);
cellID = randi([0,503],1);
% function NSSS_subframe = nsss_gen(frame_number,cellID)
theta_f = 33/132*mod(frame_number/2,4); % as defined in stadard
u = mod(cellID,126) + 3; % root of ZC sequence, defined in standard
q = floor(cellID/126);
size_RB = 12; % number of sub-carrier per RB
N_ZC = 131;
L_sub_frame = 14; % number of OFDM symbols per subframe
j = 1i;
vec_n = 0:N_ZC;
vec_n1 = mod(vec_n,131);
vec_bq = mat_bn(q+1,:);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Creation of the signal
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ZC sequence in frequency domain
ZC_sequence = exp(-j*pi*u*vec_n1.*(vec_n1+1)/N_ZC);
had_sequence = exp(-j*2*pi*theta_f*vec_n);
vec_bq_had = vec_bq.*had_sequence;
P_noise = 10^(-SNR/10); % SNR in dB to noise power
noise = sqrt(P_noise/2)*randn(1,132)+sqrt(P_noise/2)*j*randn(1,132);
vec_d = vec_bq.*had_sequence.*ZC_sequence + noise;
mat_NSSS = flipud(reshape(vec_d,size_RB,L_sub_frame-3));
NSSS_subframe = [zeros(size_RB,3),mat_NSSS];
% end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Exhaustive cell ID research
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sequence_r = repmat(vec_d,16,1).*conj(mat_16); % this remove the phase component
vec_u = 3 : 128;
mat_u = repmat(vec_u.',1,length(vec_n1));
mat_n1 = repmat(vec_n1,126,1);
sequence_ZC = exp(-j*pi*mat_u.*mat_n1.*(mat_n1+1)/N_ZC);
matrix_max_correl = zeros(126,16); % this will be filled by the maximum of correlation value
for s_ = 1 : 16
seq_ref = sequence_r(s_,:);
for u_ = 1 : 126
correl = xcorr(seq_ref,sequence_ZC(u_,:));
[val_max,ind_max] = max(abs(correl));
matrix_max_correl(u_,s_) = val_max;
end
end
max_correl = max(max(matrix_max_correl)); % get the max of all correlation values
index_max = find(matrix_max_correl==max_correl);
estim_u_ = mod(index_max,126)-1;
index_column = (index_max-mod(index_max,126))/126+1;
estim_q_ = corresponding_values(index_column);
estim_cell_ID = q*126 + estim_u_;
if cellID ~= estim_cell_ID
N_fail = N_fail + 1;
end
end
Proba_fail(k) = N_fail/N_loop;
end
plot(vec_SNR,Proba_fail)

View File

@@ -0,0 +1,218 @@
/***********************************************************************
**********************************************************************/
/*! \file PHY/LTE_TRANSPORT/pilots_NB_IoT.c
* \Generation of Reference signal (RS) for NB-IoT, TS 36-211, V13.4.0 2017-02
* \author M. KANJ
* \date 2017
* \version 0.0
* \company bcom
* \email: matthieu.kanj@b-com.com
* \note
* \warning
*/
#include "PHY/defs_eNB.h"
//#include "PHY/defs.h"
//#include "PHY/defs_NB_IoT.h"
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "proto_NB_IoT.h"
void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
int32_t **txdataF,
int16_t amp,
uint16_t Ntti, // Ntti = 0..9
unsigned short RB_ID, // RB reserved for NB-IoT
unsigned short With_NSSS) // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal
{
NB_IoT_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms;
uint16_t subframe = Ntti;
uint32_t tti_offset,slot_offset,Nsymb,samples_per_symbol; // tti,
uint8_t first_pilot,second_pilot;
unsigned short RB_IoT_ID = RB_ID;
Nsymb = 14;
first_pilot = 5; // first pilot position
second_pilot = 6; // second pilot position
slot_offset = (Ntti*2)%20;
if(subframe !=5 && ((With_NSSS*subframe)!= 9) ) // condition to avoid NPSS and NSSS signals
{
tti_offset = subframe*frame_parms->ofdm_symbol_size*Nsymb; // begins with 0
samples_per_symbol = frame_parms->ofdm_symbol_size; // ex. 512
//Generate Pilots for slot 0 and 1
//antenna 0 symbol 5 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,
&txdataF[0][tti_offset + (first_pilot*samples_per_symbol)], // tti_offset 512 x 32 bits
amp,
slot_offset,
0,
0,
RB_IoT_ID);
//antenna 0 symbol 6 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[0][tti_offset + (second_pilot*samples_per_symbol)],
amp,
slot_offset,
1,
0,
RB_IoT_ID);
//antenna 0 symbol 5 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[0][tti_offset + (7*samples_per_symbol) + (first_pilot*samples_per_symbol)],
amp,
1+slot_offset,
0,
0,
RB_IoT_ID);
//antenna 0 symbol 6 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[0][tti_offset + (7*samples_per_symbol) + (second_pilot*samples_per_symbol)],
amp,
1+slot_offset,
1,
0,
RB_IoT_ID);
if (frame_parms->nb_antennas_tx > 1) { // Pilots generation with two antennas
// antenna 1 symbol 5 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (first_pilot*samples_per_symbol)],
amp,
slot_offset,
0,
1,
RB_IoT_ID);
// antenna 1 symbol 6 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (second_pilot*samples_per_symbol)],
amp,
slot_offset,
1,
1,
RB_IoT_ID);
//antenna 1 symbol 5 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (7*samples_per_symbol) + (first_pilot*samples_per_symbol)],
amp,
1+slot_offset,
0,
1,
RB_IoT_ID);
// antenna 1 symbol 6 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (7*samples_per_symbol) + (second_pilot*samples_per_symbol)],
amp,
1+slot_offset,
1,
1,
RB_IoT_ID);
}
}
}
//////////////////////////////////////////////////////
/*
void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
int32_t **txdataF,
int16_t amp,
uint16_t Ntti, // Ntti = 10
unsigned short RB_IoT_ID, // RB reserved for NB-IoT
unsigned short With_NSSS) // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal
{
NB_IoT_DL_FRAME_PARMS *frame_parms = &phy_vars_eNB->frame_parms_NB_IoT;
uint32_t tti,tti_offset,slot_offset,Nsymb,samples_per_symbol;
uint8_t first_pilot,second_pilot;
Nsymb = 14;
first_pilot = 5; // first pilot position
second_pilot = 6; // second pilot position
for (tti=0; tti<Ntti; tti++) { // loop on sub-frames
tti_offset = tti*frame_parms->ofdm_symbol_size*Nsymb; // begins with 0
samples_per_symbol = frame_parms->ofdm_symbol_size; // ex. 512
slot_offset = (tti*2)%20; // 0, 2, 4, ....... 18
if((slot_offset != 10) && ((With_NSSS*slot_offset) != 18)) { // condition to avoid NPSS and NSSS signals
//Generate Pilots for slot 0 and 1
//antenna 0 symbol 5 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,
&txdataF[0][tti_offset + (first_pilot*samples_per_symbol)], // tti_offset 512 x 32 bits
amp,
RB_IoT_ID,
slot_offset,
0, //p
0);
//antenna 0 symbol 6 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[0][tti_offset + (second_pilot*samples_per_symbol)],
amp,
RB_IoT_ID,
slot_offset,
1,
0);
//antenna 0 symbol 5 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[0][tti_offset + (7*samples_per_symbol) + (first_pilot*samples_per_symbol)],
amp,
RB_IoT_ID,
1+slot_offset,
0,
0);
//antenna 0 symbol 6 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[0][tti_offset + (7*samples_per_symbol) + (second_pilot*samples_per_symbol)],
amp,
RB_IoT_ID,
1+slot_offset,
1,
0);
if (frame_parms->nb_antennas_tx > 1) { // Pilots generation with two antennas
// antenna 1 symbol 5 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (first_pilot*samples_per_symbol)],
amp,
RB_IoT_ID,
slot_offset,
0,
1);
// antenna 1 symbol 6 slot 0
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (second_pilot*samples_per_symbol)],
amp,
RB_IoT_ID,
slot_offset,
1,
1);
//antenna 1 symbol 5 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (7*samples_per_symbol) + (first_pilot*samples_per_symbol)],
amp,
RB_IoT_ID,
1+slot_offset,
0,
1);
// antenna 1 symbol 6 slot 1
lte_dl_cell_spec_NB_IoT(phy_vars_eNB,&txdataF[1][tti_offset + (7*samples_per_symbol) + (second_pilot*samples_per_symbol)],
amp,
RB_IoT_ID,
1+slot_offset,
1,
1);
}
}
}
}
*/

View File

@@ -0,0 +1,708 @@
/*
* 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
*/
/*! \file PHY/LTE_TRANSPORT/proto.h
* \brief Function prototypes for PHY physical/transport channel processing and generation V8.6 2009-03
* \author R. Knopp, F. Kaltenberger
* \date 2011
* \version 0.1
* \company Eurecom
* \email: knopp@eurecom.fr
* \note
* \warning
*/
#ifndef __NBIOT_TRANSPORT_PROTO__H__
#define __NBIOT_TRANSPORT_PROTO__H__
#include "PHY/defs_L1_NB_IoT.h"
#include "PHY/impl_defs_lte.h"
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
//#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
//#include <math.h>
//NPSS
void free_eNB_dlsch_NB_IoT(NB_IoT_eNB_NDLSCH_t *dlsch);
void free_eNB_dlcch_NB_IoT(NB_IoT_eNB_NPDCCH_t *dlcch);
void init_unscrambling_lut_NB_IoT(void);
int generate_npss_NB_IoT(int32_t **txdataF,
short amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
unsigned short symbol_offset, // symbol_offset should equal to 3 for NB-IoT
unsigned short slot_offset,
unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
//NSSS
int generate_sss_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint16_t symbol_offset, // symbol_offset = 3 for NB-IoT
uint16_t slot_offset,
unsigned short frame_number, // new attribute (Get value from higher layer), it does not exist for LTE
unsigned short RB_IoT_ID); // new attribute (values are between 0.. Max_RB_number-1), it does not exist for LTE
//*****************Vincent part for Cell ID estimation from NSSS ******************//
int rx_nsss_NB_IoT(PHY_VARS_UE_NB_IoT *ue,int32_t *tot_metric);
int nsss_extract_NB_IoT(PHY_VARS_UE_NB_IoT *ue,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **nsss_ext,
int l);
//NRS
void generate_pilots_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,
int32_t **txdataF,
int16_t amp,
uint16_t Ntti, // Ntti = 10
unsigned short RB_IoT_ID, // RB reserved for NB-IoT
unsigned short With_NSSS); // With_NSSS = 1; if the frame include a sub-Frame with NSSS signal
//NPBCH
int allocate_npbch_REs_in_RB(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
int16_t amp,
unsigned short id_offset,
uint32_t *re_allocated);
// NPDSCH
int allocate_REs_in_RB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
int16_t amp,
unsigned short id_offset,
uint8_t pilot_shift,
uint32_t *re_allocated);
int generate_NDLSCH_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_eNB_NDLSCH_t *RAR,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID,
uint8_t release_v13_5_0);
int generate_NPDCCH_NB_IoT(NB_IoT_eNB_NPDCCH_t *DCI_1,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID);
int generate_SIB23(NB_IoT_eNB_NDLSCH_t *SIB23,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID,
uint8_t release_v13_5_0);
int generate_SIB1(NB_IoT_eNB_NDLSCH_t *sib1_struct,
int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint32_t frame,
uint32_t subframe,
int RB_IoT_ID,
uint8_t operation_mode,
uint8_t release_v13_5_0);
int generate_npbch(NB_IoT_eNB_NPBCH_t *eNB_npbch,
int32_t **txdataF,
int amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t *npbch_pdu,
uint8_t frame_mod64,
unsigned short NB_IoT_RB_ID,
uint8_t release_v13_5_0);
void npbch_scrambling(NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t *npbch_e,
uint32_t length);
void dlsch_scrambling_Gen_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_NDLSCH_t *dlsch,
int tot_bits, // total number of bits to transmit
uint16_t Nf, // Nf is the frame number (0..9)
uint8_t Ns,
uint32_t rnti,
uint8_t release_v13_5_0,
uint8_t SIB);
NB_IoT_eNB_NDLSCH_t *new_eNB_dlsch_NB_IoT(uint8_t length, NB_IoT_DL_FRAME_PARMS* frame_parms);
NB_IoT_eNB_NPDCCH_t *new_eNB_dlcch_NB_IoT(NB_IoT_DL_FRAME_PARMS* frame_parms);
/*void dlsch_scrambling_Gen_NB_IoT(LTE_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_NDLSCH_t *dlsch,
int tot_bits, // total number of bits to transmit
uint16_t Nf, // Nf is the frame number (0..9)
uint8_t Ns,
uint32_t rnti, /// for SIB1 the SI_RNTI should be get from the DL request
uint8_t type);*/
/*
int scrambling_npbch_REs_rel_14(LTE_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
int l,
uint32_t symbol_offset,
uint8_t pilots,
unsigned short id_offset,
uint8_t *reset,
uint32_t *x1,
uint32_t *x2,
uint32_t *s);
*/
// Functions below implement 36-211 and 36-212
/*Function to pack the DCI*/
// newly added function for NB-IoT , does not exist for LTE
void add_dci_NB_IoT(DCI_PDU_NB_IoT *DCI_pdu,
void *pdu,
rnti_t rnti,
unsigned char dci_size_bytes,
unsigned char aggregation,
unsigned char dci_size_bits,
unsigned char dci_fmt,
uint8_t npdcch_start_symbol);
/*Use the UL DCI Information to configure PHY and also Pack the DCI*/
int generate_eNB_ulsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int frame,
uint8_t subframe,
DCI_CONTENT *DCI_Content,
uint16_t rnti,
NB_IoT_eNB_NPDCCH_t *ndlcch,
uint8_t aggregation,
uint8_t npdcch_start_symbol,
uint8_t ncce_index);
/*Use the DL DCI Information to configure PHY and also Pack the DCI*/
int generate_eNB_dlsch_params_from_dci_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int frame,
uint8_t subframe,
DCI_CONTENT *DCI_Content,
uint16_t rnti,
DCI_format_NB_IoT_t dci_format,
NB_IoT_eNB_NPDCCH_t *ndlcch,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t aggregation,
uint8_t npdcch_start_symbol,
uint8_t ncce_index);
/*Function for DCI encoding, scrambling, modulation*/
uint8_t generate_dci_top_NB_IoT(NB_IoT_eNB_NPDCCH_t *npdcch,
uint8_t Num_dci,
DCI_ALLOC_NB_IoT_t *dci_alloc,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *fp,
int32_t **txdataF,
uint32_t subframe,
uint8_t npdcch_start_symbol);
/*!
\brief Decoding of PUSCH/ACK/RI/ACK from 36-212.
@param phy_vars_eNB Pointer to eNB top-level descriptor
@param proc Pointer to RXTX proc variables
@param UE_id ID of UE transmitting this PUSCH
@param subframe Index of subframe for PUSCH
@param control_only_flag Receive PUSCH with control information only
@param Nbundled Nbundled parameter for ACK/NAK scrambling from 36-212/36-213
@param llr8_flag If 1, indicate that the 8-bit turbo decoder should be used
@returns 0 on success
*/
/*unsigned int ulsch_decoding_NB_IoT(PHY_VARS_eNB *phy_vars_eNB,
eNB_rxtx_proc_t *proc,
uint8_t UE_id,
uint8_t control_only_flag,
uint8_t Nbundled,
uint8_t llr8_flag);
*/
// NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t abstraction_flag);
int ulsch_decoding_data_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int UE_id,
int harq_pid,
int llr8_flag);
uint8_t subframe2harq_pid_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t frame,uint8_t subframe);
/** \brief Compute Q (modulation order) based on I_MCS for PUSCH. Implements table 8.6.1-1 from 36.213.
@param I_MCS */
//uint8_t get_Qm_ul_NB_IoT(uint8_t I_MCS);
/** \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
*/
int dci_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size,
NB_IoT_eNB_NPDCCH_t *dlcch,
unsigned int npdsch_data_subframe,
uint8_t agr_level,
uint8_t ncce_index,
unsigned int subframe,
unsigned short NB_IoT_RB_ID);
int dci_allocate_REs_in_RB_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **txdataF,
uint32_t *jj,
uint32_t symbol_offset,
uint8_t *x0,
uint8_t pilots,
uint8_t pilot_shift,
int16_t amp,
unsigned short id_offset,
uint8_t ncce_index,
uint8_t agr_level,
uint32_t *re_allocated);
void dci_encoding_NB_IoT(uint8_t *a,
NB_IoT_eNB_NPDCCH_t *dlcch,
uint8_t A,
uint16_t G,
uint8_t ncce_index,
uint8_t agr_level);
void npdcch_scrambling_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
NB_IoT_eNB_NPDCCH_t *dlcch, // Input data
int G, // Total number of bits to transmit in one subframe(case of DCI = G)
uint8_t Ns, //XXX we pass the subframe // Slot number (0..19)
uint8_t ncce_index,
uint8_t agr_level);
int dlsch_modulation_NB_IoT(int32_t **txdataF,
int16_t amp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
NB_IoT_eNB_NDLSCH_t *dlsch0, //NB_IoT_eNB_NDLSCH_t
int G, // number of bits per subframe
unsigned int npdsch_data_subframe, // subframe index of the data table of npdsch channel (G*Nsf) , values are between 0..Nsf
unsigned int subframe,
unsigned short NB_IoT_RB_ID);
/*
int dlsch_modulation_rar_NB_IoT(int32_t **txdataF,
int16_t amp,
LTE_DL_FRAME_PARMS *frame_parms,
uint8_t control_region_size, // control region size for LTE , values between 0..3, (0 for stand-alone / 1, 2 or 3 for in-band)
NB_IoT_DL_eNB_HARQ_t *dlsch0, //NB_IoT_eNB_NDLSCH_t
int G, // number of bits per subframe
unsigned int npdsch_data_subframe, // subframe index of the data table of npdsch channel (G*Nsf) , values are between 0..Nsf
unsigned int subframe,
unsigned short NB_IoT_RB_ID,
uint8_t option);
*/
int32_t dlsch_encoding_NB_IoT(unsigned char *a,
NB_IoT_eNB_NDLSCH_t *dlsch, // NB_IoT_eNB_NDLSCH_t
uint8_t Nsf, // number of subframes required for npdsch pdu transmission calculated from Isf (3GPP spec table)
unsigned int G); // G (number of available RE) is implicitly multiplied by 2 (since only QPSK modulation)
void get_pilots_position(uint8_t npusch_format,uint8_t subcarrier_spacing,uint8_t *pilot_pos1,uint8_t *pilot_pos2,uint8_t *pilots_slot);
void UL_channel_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *fp,
uint16_t UL_RB_ID_NB_IoT,
uint16_t Nsc_RU,
uint8_t pilot_pos1,
uint8_t pilot_pos2,
uint16_t ul_sc_start,
uint8_t Qm,
uint16_t N_SF_per_word,
uint8_t rx_subframe);
void get_llr_per_sf_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *fp,
uint8_t npusch_format,
uint8_t counter_sf,
uint16_t N_SF_per_word,
uint8_t pilot_pos1,
uint8_t pilot_pos2,
uint16_t ul_sc_start,
uint16_t Nsc_RU);
void descrambling_NPUSCH_data_NB_IoT(NB_IoT_DL_FRAME_PARMS *fp,
int16_t *ulsch_llr,
int16_t *y,
uint8_t Qm,
unsigned int Cmux,
uint32_t rnti_tmp,
uint8_t rx_subframe,
uint32_t rx_frame);
void descrambling_NPUSCH_ack_NB_IoT(NB_IoT_DL_FRAME_PARMS *fp,
int32_t *y_msg5,
int32_t *llr_msg5,
uint32_t rnti_tmp,
uint16_t *counter_ack,
uint8_t rx_subframe,
uint32_t rx_frame);
uint32_t turbo_decoding_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_eNB_NULSCH_t *ulsch_NB_IoT,
eNB_rxtx_proc_NB_IoT_t *proc,
uint8_t npusch_format,
unsigned int G,
uint8_t rvdx,
uint8_t Qm,
uint32_t rx_frame,
uint8_t rx_subframe);
void decode_NPUSCH_msg_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *fp,
eNB_rxtx_proc_NB_IoT_t *proc,
uint8_t npusch_format,
uint16_t N_SF_per_word,
uint16_t Nsc_RU,
uint16_t N_UL_slots,
uint8_t Qm,
uint8_t pilots_slot,
uint32_t rnti_tmp,
uint8_t rx_subframe,
uint32_t rx_frame);
void deinterleaving_NPUSCH_data_NB_IoT(NB_IoT_UL_eNB_HARQ_t *ulsch_harq, int16_t *y, unsigned int G);
uint8_t rx_ulsch_Gen_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
uint8_t eNB_id, // this is the effective sector id
uint8_t UE_id,
uint16_t UL_RB_ID_NB_IoT, // 22 , to be included in // to be replaced by NB_IoT_start ??
uint8_t subframe,
uint32_t frame);
void ulsch_extract_rbs_single_NB_IoT(int32_t **rxdataF,
int32_t **rxdataF_ext,
uint16_t UL_RB_ID_NB_IoT, // index of UL NB_IoT resource block !!! may be defined twice : in frame_parms and in NB_IoT_UL_eNB_HARQ_t
uint16_t N_sc_RU, // number of subcarriers in UL
uint8_t l,
uint8_t Ns,
NB_IoT_DL_FRAME_PARMS *frame_parms);
void ulsch_channel_level_NB_IoT(int32_t **drs_ch_estimates_ext,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t *avg,
uint16_t nb_rb);
void ulsch_channel_compensation_NB_IoT(int32_t **rxdataF_ext,
int32_t **ul_ch_estimates_ext,
int32_t **ul_ch_mag,
int32_t **ul_ch_magb,
int32_t **rxdataF_comp,
NB_IoT_DL_FRAME_PARMS *frame_parms,
uint8_t symbol,
uint8_t Qm,
uint16_t nb_rb,
uint8_t output_shift);
void lte_idft_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint32_t *z, uint16_t Msc_PUSCH);
void extract_CQI_NB_IoT(void *o,UCI_format_NB_IoT_t uci_format,NB_IoT_eNB_UE_stats *stats,uint8_t N_RB_DL, uint16_t * crnti, uint8_t * access_mode);
//*****************Vincent part for nprach ******************//
uint32_t process_nprach_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB, int frame, uint8_t subframe,uint16_t *rnti, uint16_t *preamble_index, uint16_t *timing_advance);
uint32_t TA_estimation_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
int16_t *Rx_sub_sampled_buffer,
uint16_t sub_sampling_rate,
uint16_t FRAME_LENGTH_COMPLEX_SUB_SAMPLES,
uint32_t estimated_TA_coarse,
uint8_t coarse);
uint8_t NPRACH_detection_NB_IoT(int16_t *input_buffer,uint32_t FRAME_LENGTH_COMPLEX_SAMPLESx);
int16_t* sub_sampling_NB_IoT(int16_t *input_buffer, uint32_t length_input, uint32_t *length_ouput, uint16_t sub_sampling_rate);
void filtering_signal(int16_t *input_buffer, int16_t *filtered_buffer, uint32_t FRAME_LENGTH_COMPLEX_SAMPLESx);
//************************************************************//
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//uint8_t get_UL_I_TBS_from_MCS_NB_IoT(uint8_t I_mcs, uint8_t N_sc_RU, uint8_t Msg3_flag);
uint8_t get_Qm_UL_NB_IoT(unsigned char I_mcs, uint8_t N_sc_RU, uint8_t I_sc, uint8_t Msg3_flag);
//uint16_t get_UL_sc_start_NB_IoT(uint16_t I_sc);
uint16_t get_UL_sc_ACK_NB_IoT(uint8_t subcarrier_spacing,uint16_t harq_ack_resource);
uint16_t get_UL_sc_index_start_NB_IoT(uint8_t subcarrier_spacing, uint16_t I_sc, uint8_t npush_format);
uint16_t get_UL_N_ru_NB_IoT(uint8_t I_mcs, uint8_t I_ru, uint8_t flag_msg3);
uint16_t get_UL_N_rep_NB_IoT(uint8_t I_rep);
uint8_t get_numb_UL_sc_NB_IoT(uint8_t subcarrier_spacing, uint8_t I_sc, uint8_t npush_format);
uint8_t get_UL_slots_per_RU_NB_IoT(uint8_t subcarrier_spacing, uint8_t subcarrier_indcation, uint8_t UL_format);
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
void generate_grouphop_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms);
void init_ul_hopping_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms);
void rotate_single_carrier_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint8_t eNB_id,
uint8_t symbol, //symbol within subframe
uint8_t counter_msg3, /// to be replaced by the number of received part
uint16_t ul_sc_start,
uint8_t Qm,
uint16_t N_SF_per_word,
uint8_t option);
void fill_rbs_zeros_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint16_t ul_sc_start,
uint8_t UE_id,
uint8_t symbol);
int32_t ulsch_bpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint16_t ul_sc_start,
uint8_t UE_id,
int16_t **llrp);
int32_t ulsch_qpsk_llr_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *ulsch_llr,
uint8_t symbol,
uint8_t UE_id,
uint16_t ul_sc_start,
uint8_t Nsc_RU,
int16_t *llrp);
void rotate_bpsk_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
uint16_t ul_sc_start,
uint8_t UE_id,
uint8_t symbol);
//************************************************************//
int rx_npdsch_NB_IoT(PHY_VARS_UE_NB_IoT *ue,
PDSCH_t type,
unsigned char eNB_id,
unsigned char eNB_id_i, //if this == ue->n_connected_eNB, we assume MU interference
uint32_t frame,
uint8_t subframe,
unsigned char symbol,
unsigned char first_symbol_flag,
unsigned char i_mod,
unsigned char harq_pid);
unsigned short dlsch_extract_rbs_single_NB_IoT(int **rxdataF,
int **dl_ch_estimates,
int **rxdataF_ext,
int **dl_ch_estimates_ext,
unsigned short pmi,
unsigned char *pmi_ext,
unsigned int *rb_alloc,
unsigned char symbol,
unsigned char subframe,
uint32_t frame,
uint32_t high_speed_flag,
NB_IoT_DL_FRAME_PARMS *frame_parms);
void dlsch_channel_level_NB_IoT(int **dl_ch_estimates_ext,
NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t *avg,
uint8_t symbol,
unsigned short nb_rb);
void dlsch_channel_compensation_NB_IoT(int **rxdataF_ext,
int **dl_ch_estimates_ext,
int **dl_ch_mag,
int **dl_ch_magb,
int **rxdataF_comp,
int **rho,
NB_IoT_DL_FRAME_PARMS *frame_parms,
unsigned char symbol,
uint8_t first_symbol_flag,
unsigned char mod_order,
unsigned short nb_rb,
unsigned char output_shift,
PHY_MEASUREMENTS_NB_IoT *measurements);
int dlsch_qpsk_llr_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,
int32_t **rxdataF_comp,
int16_t *dlsch_llr,
uint8_t symbol,
uint8_t first_symbol_flag,
uint16_t nb_rb,
int16_t **llr32p,
uint8_t beamforming_mode);
/// Vincent: temporary functions
int ul_chest_tmp_NB_IoT(int32_t **rxdataF_ext,
int32_t **ul_ch_estimates,
uint8_t l, //symbol within slot
uint8_t Ns,
uint8_t counter_msg3,
uint8_t pilot_pos1,
uint8_t pilot_pos2,
uint16_t ul_sc_start,
uint8_t Qm,
uint16_t N_SF_per_word,
NB_IoT_DL_FRAME_PARMS *frame_parms);
/// Channel estimation for NPUSCH format 2
int ul_chest_tmp_f2_NB_IoT(int32_t **rxdataF_ext,
int32_t **ul_ch_estimates,
uint8_t l, //symbol within slot
uint8_t Ns,
uint8_t counter_msg3,
uint8_t flag,
uint8_t subframerx,
uint8_t Qm,
uint16_t ul_sc_start,
NB_IoT_DL_FRAME_PARMS *frame_parms);
void rotate_channel_sc_tmp_NB_IoT(int16_t *estimated_channel,
uint8_t l,
uint8_t Qm,
uint8_t counter_msg3,
uint16_t N_SF_per_word,
uint16_t ul_sc_start,
uint8_t flag);
int ul_chequal_tmp_NB_IoT(int32_t **rxdataF_ext,
int32_t **rxdataF_comp,
int32_t **ul_ch_estimates,
uint8_t l, //symbol within slot
uint8_t Ns,
NB_IoT_DL_FRAME_PARMS *frame_parms);
///
////////////////////////////NB-IoT testing ///////////////////////////////
void clean_eNb_ulsch_NB_IoT(NB_IoT_eNB_NULSCH_t *ulsch);
int get_G_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms);
int get_G_SIB1_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms, uint8_t operation_mode_info);
int get_rep_num_SIB1_NB_IoT(uint8_t scheduling_info_sib1);
int get_start_frame_SIB1_NB_IoT(NB_IoT_DL_FRAME_PARMS *frame_parms,uint8_t repetition);
NB_IoT_eNB_NULSCH_t *new_eNB_ulsch_NB_IoT(uint8_t max_turbo_iterations,uint8_t N_RB_UL, uint8_t abstraction_flag);
#endif

View File

@@ -0,0 +1,62 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file PHY/LTE_TRANSPORT/sc_rotation_NB_IoT.c
* \brief Some support routines for MCS computations
* \author V. SAVAUX, M. KANJ
* \date 2017
* \version 0.1
* \company b<>com
* \email:
* \note
* \warning
*/
#ifndef __PHY_LTE_TRANSPORT_SC_ROTATION_NB_IOT__H__
#define __PHY_LTE_TRANSPORT_SC_ROTATION_NB_IOT__H__
int16_t e_phi_re_p5[120] = {32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621};
int16_t e_phi_im_p5[120] = {0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009};
int16_t e_phi_re_m6[120] = {32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621};
int16_t e_phi_im_m6[120] = {0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, 0, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, -1, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010, -1, 21402, 32412, 27683, 9511, -13279, -29622, -32767, -24812, -4808, 17530, 31356, 29955, 14009, 0, -21403, -32413, -27684, -9512, 13278, 29621, 32767, 24811, 4807, -17531, -31357, -29956, -14010};
int16_t e_phi_re_m5[120] = {32767, 13278, -22005, -31114, -3212, 28510, 26318, 0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, -1, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, 0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, -1, 29955, 24278, -10279, -32610, -16151, 19519};
int16_t e_phi_im_m5[120] = {0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, 0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, -1, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, 0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319};
int16_t e_phi_re_m4[120] = {32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, 0, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, -1, -32758, 1607, 32678, -3212, -32521, 4807};
int16_t e_phi_im_m4[120] = {0, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, -1, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413};
int16_t e_phi_re_m3[120] = {32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, 0, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, -1, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039};
int16_t e_phi_im_m3[120] = {0, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, -1, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, -1, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, 0, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, -1, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852};
int16_t e_phi_re_m2[120] = {32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, -1, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279};
int16_t e_phi_im_m2[120] = {0, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, -1, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, 0, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005};
int16_t e_phi_re_m1[120] = {32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, 0, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, -1, 7179, -14010, 20159, -25330, 29268, -31786};
int16_t e_phi_im_m1[120] = {0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, 0, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962};
int16_t e_phi_re_0[120] = {32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, 0, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, -1, 7179, -14010, 20159, -25330, 29268, -31786};
int16_t e_phi_im_0[120] = {0, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, 0, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961, -1, -7180, 14009, -20160, 25329, -29269, 31785, -32767, 31970, -29622, 25831, -20788, 14732, -7962, -1, 7179, -14010, 20159, -25330, 29268, -31786, 32767, -31971, 29621, -25832, 20787, -14733, 7961};
int16_t e_phi_re_p1[120] = {32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, -1, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279};
int16_t e_phi_im_p1[120] = {0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, 0, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, -1, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004, 0, -20160, 31785, -29956, 15446, 5601, -24279, 32767, -25832, 7961, 13278, -28898, 32284, -22005, -1, 20159, -31786, 29955, -15447, -5602, 24278, -32767, 25831, -7962, -13279, 28897, -32285, 22004};
int16_t e_phi_re_p2[120] = {32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, 0, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, -1, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039};
int16_t e_phi_im_p2[120] = {0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, 0, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, 0, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, -1, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, 0, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851, 0, -29269, 26318, 5601, -31357, 22594, 11038, -32767, 14732, 19519, -32285, 9511, 23731, -30852, -1, 29268, -26319, -5602, 31356, -22595, -11039, 32767, -14733, -19520, 32284, -9512, -23732, 30851};
int16_t e_phi_re_p3[120] = {32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, 0, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, -1, -32758, 1607, 32678, -3212, -32521, 4807};
int16_t e_phi_im_p3[120] = {0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, -1, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412, 0, -32758, 1607, 32678, -3212, -32521, 4807, 32767, -805, -32728, 2410, 32609, -4012, -32413, 0, 32757, -1608, -32679, 3211, 32520, -4808, -32767, 804, 32727, -2411, -32610, 4011, 32412};
int16_t e_phi_re_p4[120] = {32767, 13278, -22005, -31114, -3212, 28510, 26318, 0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, -1, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, 0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, -1, 29955, 24278, -10279, -32610, -16151, 19519};
int16_t e_phi_im_p4[120] = {0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, -1, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, -1, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, 0, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318, 0, -29956, -24279, 10278, 32609, 16150, -19520, -32767, -13279, 22004, 31113, 3211, -28511, -26319, -1, 29955, 24278, -10279, -32610, -16151, 19519, 32767, 13278, -22005, -31114, -3212, 28510, 26318};
#endif

File diff suppressed because one or more lines are too long

View File

@@ -321,4 +321,4 @@ HLC_subband_cqi_mcs_CBA_20MHz_NB_IoT;
#define MAX_ACK_PAYLOAD_NB_IoT 18
#define MAX_RI_PAYLOAD_NB_IoT 6
#endif
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
//#include "dlsch_tbs.h"
//#include "dlsch_tbs_full.h"
//#include "sss.h"
#ifndef __PHY_LTE_TRANSPORT_VARS_NB_IOT__H__
#define __PHY_LTE_TRANSPORT_VARS_NB_IOT__H__
unsigned char cs_ri_normal_NB_IoT[4] = {1,4,7,10};
unsigned char cs_ri_extended_NB_IoT[4] = {0,3,5,8};
unsigned char cs_ack_normal_NB_IoT[4] = {2,3,8,9};
unsigned char cs_ack_extended_NB_IoT[4] = {1,2,6,7};
int G_tab[18] = {200,224,240,208,232,256,220,244,268,216,240,256,224,248,264,236,260,284};
int8_t wACK_RX_NB_IoT[5][4] = {{-1,-1,-1,-1},{-1,1,-1,1},{-1,-1,1,1},{-1,1,1,-1},{1,1,1,1}};
#endif

View File

@@ -0,0 +1,158 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __TIME_MEAS_DEFS_NB_IoT__H__
#define __TIME_MEAS_DEFS_NB_IoT__H__
#include <unistd.h>
#include <math.h>
#include <stdint.h>
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <pthread.h>
#include <linux/kernel.h>
#include <linux/types.h>
// global var to enable openair performance profiler
extern int opp_enabled_NB_IoT;
double cpu_freq_GHz;
#if defined(__x86_64__) || defined(__i386__)
typedef struct {
long long in;
long long diff;
long long diff_now;
long long p_time; /*!< \brief absolute process duration */
long long diff_square; /*!< \brief process duration square */
long long max;
int trials;
int meas_flag;
} time_stats_t_NB_IoT;
#elif defined(__arm__)
typedef struct {
uint32_t in;
uint32_t diff_now;
uint32_t diff;
uint32_t p_time; /*!< \brief absolute process duration */
uint32_t diff_square; /*!< \brief process duration square */
uint32_t max;
int trials;
} time_stats_t_NB_IoT;
#endif
static inline void start_meas_NB_IoT(time_stats_t_NB_IoT *ts) __attribute__((always_inline));
static inline void stop_meas_NB_IoT(time_stats_t_NB_IoT *ts) __attribute__((always_inline));
/*
void print_meas_now(time_stats_t *ts, const char* name, FILE* file_name);
void print_meas(time_stats_t *ts, const char* name, time_stats_t * total_exec_time, time_stats_t * sf_exec_time);
double get_time_meas_us(time_stats_t *ts);
double get_cpu_freq_GHz(void);
*/
#if defined(__i386__)
static inline unsigned long long rdtsc_oai_NB_IoT(void) __attribute__((always_inline));
static inline unsigned long long rdtsc_oai_NB_IoT(void)
{
unsigned long long int x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#elif defined(__x86_64__)
static inline unsigned long long rdtsc_oai_NB_IoT(void) __attribute__((always_inline));
static inline unsigned long long rdtsc_oai_NB_IoT(void)
{
unsigned long long a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (d<<32) | a;
}
#elif defined(__arm__)
static inline uint32_t rdtsc_oai_NB_IoT(void) __attribute__((always_inline));
static inline uint32_t rdtsc_oai_NB_IoT(void)
{
uint32_t r = 0;
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(r) );
return r;
}
#endif
static inline void start_meas_NB_IoT(time_stats_t_NB_IoT *ts)
{
if (opp_enabled_NB_IoT) {
if (ts->meas_flag==0) {
ts->trials++;
ts->in = rdtsc_oai_NB_IoT();
ts->meas_flag=1;
}
else {
ts->in = rdtsc_oai_NB_IoT();
}
}
}
static inline void stop_meas_NB_IoT(time_stats_t_NB_IoT *ts)
{
if (opp_enabled_NB_IoT) {
long long out = rdtsc_oai_NB_IoT();
ts->diff_now = (out-ts->in);
ts->diff_now = (out-ts->in);
ts->diff += (out-ts->in);
/// process duration is the difference between two clock points
ts->p_time = (out-ts->in);
ts->diff_square += (out-ts->in)*(out-ts->in);
if ((out-ts->in) > ts->max)
ts->max = out-ts->in;
ts->meas_flag=0;
}
}
static inline void reset_meas_NB_IoT(time_stats_t_NB_IoT *ts) {
ts->trials=0;
ts->diff=0;
ts->diff_now=0;
ts->p_time=0;
ts->diff_square=0;
ts->max=0;
ts->meas_flag=0;
}
static inline void copy_meas_NB_IoT(time_stats_t_NB_IoT *dst_ts,time_stats_t_NB_IoT *src_ts)
{
if (opp_enabled_NB_IoT) {
dst_ts->trials=src_ts->trials;
dst_ts->diff=src_ts->diff;
dst_ts->max=src_ts->max;
}
}
#endif

View File

@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
/*! \file PHY/defs.h
/*! \file PHY/defs_L1_NB_IoT.h
\brief Top-level defines and structure definitions
\author R. Knopp, F. Kaltenberger
\date 2011
@@ -74,52 +74,6 @@
#define openair_free(y,x) free((y))
#define PAGE_SIZE 4096
//#ifdef SHRLIBDEV
//extern int rxrescale;
//#define RX_IQRESCALELEN rxrescale
//#else
//#define RX_IQRESCALELEN 15
//#endif
//! \brief Allocate \c size bytes of memory on the heap with alignment 16 and zero it afterwards.
//! If no more memory is available, this function will terminate the program with an assertion error.
//******************************************************************************************************
/*
static inline void* malloc16_clear( size_t size )
{
#ifdef __AVX2__
void* ptr = memalign(32, size);
#else
void* ptr = memalign(16, size);
#endif
DevAssert(ptr);
memset( ptr, 0, size );
return ptr;
}
*/
// #define PAGE_MASK 0xfffff000
// #define virt_to_phys(x) (x)
// #define openair_sched_exit() exit(-1)
// #define max(a,b) ((a)>(b) ? (a) : (b))
// #define min(a,b) ((a)<(b) ? (a) : (b))
// #define bzero(s,n) (memset((s),0,(n)))
// #define cmax(a,b) ((a>b) ? (a) : (b))
// #define cmin(a,b) ((a<b) ? (a) : (b))
// #define cmax3(a,b,c) ((cmax(a,b)>c) ? (cmax(a,b)) : (c))
// /// suppress compiler warning for unused arguments
// #define UNUSED(x) (void)x;
#include "PHY/impl_defs_top_NB_IoT.h"
//#include "impl_defs_top.h"
@@ -127,17 +81,17 @@ static inline void* malloc16_clear( size_t size )
#include "PHY/impl_defs_lte_NB_IoT.h"
#include "PHY/TOOLS/time_meas.h"
#include "PHY/TOOLS/time_meas_NB_IoT.h"
//#include "PHY/CODING/defs.h"
#include "defs_common.h"
#include "PHY/CODING/defs_NB_IoT.h"
#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
//#include "PHY/TOOLS/defs.h"
//#include "platform_types.h"
///#include "openair1/PHY/LTE_TRANSPORT/defs_nb_iot.h"
////////////////////////////////////////////////////////////////////#ifdef OPENAIR_LTE (check if this is required)
//#include "PHY/LTE_TRANSPORT/defs.h"
#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
#include <pthread.h>
#include "targets/ARCH/COMMON/common_lib.h"
@@ -149,6 +103,7 @@ static inline void* malloc16_clear( size_t size )
#define NB_BANDS_MAX_NB_IoT 8
#define bzero(s,n) (memset((s),0,(n)))
#ifdef OCP_FRAMEWORK
#include <enums.h>
@@ -156,7 +111,7 @@ static inline void* malloc16_clear( size_t size )
typedef enum {normal_txrx_NB_IoT=0,rx_calib_ue_NB_IoT=1,rx_calib_ue_med_NB_IoT=2,rx_calib_ue_byp_NB_IoT=3,debug_prach_NB_IoT=4,no_L2_connect_NB_IoT=5,calib_prach_tx_NB_IoT=6,rx_dump_frame_NB_IoT=7,loop_through_memory_NB_IoT=8} runmode_NB_IoT_t;
#endif
/*
enum transmission_access_mode {
enum transmission_access_mode_NB_IoT {
NO_ACCESS=0,
POSTPONED_ACCESS,
CANCELED_ACCESS,
@@ -254,6 +209,8 @@ typedef struct {
/// Context data structure for RX/TX portion of subframe processing
typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
/// subframe to act upon for transmission
@@ -264,6 +221,9 @@ typedef struct {
int frame_tx;
/// frame to act upon for reception
int frame_rx;
uint16_t HFN;
/// \brief Instance count for RXn-TXnp4 processing thread.
/// \internal This variable is protected by \ref mutex_rxtx.
int instance_cnt_rxtx;
@@ -283,6 +243,24 @@ typedef struct {
pthread_mutex_t mutex_l2;
int instance_cnt_l2;
pthread_attr_t attr_l2;
uint32_t frame_msg5;
uint32_t subframe_msg5;
int subframe_real;
uint8_t flag_scrambling;
uint8_t flag_msg3;
uint8_t counter_msg3;
uint32_t frame_msg3;
uint8_t flag_msg4;
uint8_t counter_msg4;
uint32_t frame_msg4;
uint32_t subframe_msg4;
uint8_t counter_msg5;
uint8_t flag_msg5;
uint32_t frame_dscr_msg5;
uint32_t subframe_dscr_msg5;
uint32_t frame_dscr_msg3; //phy_procedures_lte_eNb_NB_IoT.c
uint32_t subframe_dscr_msg3; //phy_procedures_lte_eNb_NB_IoT.c
} eNB_rxtx_proc_NB_IoT_t;
/*
@@ -303,6 +281,8 @@ typedef struct {
/// Context data structure for eNB subframe processing
typedef struct eNB_proc_NB_IoT_t_s {
/// Component Carrier index
uint8_t CC_id;
/// thread index
int thread_index;
/// timestamp received from HW
@@ -341,6 +321,10 @@ typedef struct eNB_proc_NB_IoT_t_s {
int instance_cnt_asynch_rxtx;
/// pthread structure for FH processing thread
pthread_t pthread_FH;
/// pthread structure for eNB single processing thread
pthread_t pthread_single; //NB-IoT
/// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition
@@ -440,7 +424,10 @@ typedef struct eNB_proc_NB_IoT_t_s {
/// set of scheduling variables RXn-TXnp4 threads
// newly added for NB_IoT
eNB_rxtx_proc_NB_IoT_t proc_rxtx[2];
//samuel
uint16_t HFN;
pthread_mutex_t mutex_rxtx;
int instance_cnt_rxtx;
} eNB_proc_NB_IoT_t;
@@ -448,6 +435,8 @@ typedef struct eNB_proc_NB_IoT_t_s {
typedef struct {
/// index of the current UE RX/TX proc
int proc_id;
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
/// subframe to act upon for transmission
@@ -482,6 +471,8 @@ typedef struct {
/// Context data structure for eNB subframe processing
typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// Last RX timestamp
openair0_timestamp timestamp_rx;
/// pthread attributes for main UE thread
@@ -514,14 +505,19 @@ typedef struct {
typedef struct PHY_VARS_eNB_NB_IoT_s {
/// Module ID indicator for this instance
module_id_t Mod_id;
uint8_t CC_id;
uint8_t configured;
eNB_proc_NB_IoT_t proc;
int num_RU;
RU_t *RU_list[MAX_NUM_RU_PER_eNB];
/// Ethernet parameters for northbound midhaul interface (L1 to Mac)
eth_params_t eth_params_n;
eth_params_t eth_params_n;
eNB_func_NB_IoT_t node_function;
eNB_timing_NB_IoT_t node_timing;
/// Ethernet parameters for fronthaul interface (upper L1 to Radio head)
eth_params_t eth_params;
eth_params_t *eth_params;
int single_thread_flag;
openair0_rf_map rf_map;
int abstraction_flag;
@@ -533,7 +529,7 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
// indicator for precoding function (eNB,3GPP_eNB_BBU)
int do_precoding;
IF_Module_NB_IoT_t *if_inst_NB_IoT;
UL_IND_NB_IoT_t UL_INFO_NB_IoT;
UL_IND_NB_IoT_t UL_INFO;
pthread_mutex_t UL_INFO_mutex;
void (*do_prach)(struct PHY_VARS_eNB_NB_IoT_s *eNB,int frame,int subframe);
void (*fep)(struct PHY_VARS_eNB_NB_IoT_s *eNB,eNB_rxtx_proc_NB_IoT_t *proc);
@@ -732,56 +728,46 @@ typedef struct PHY_VARS_eNB_NB_IoT_s {
// NB-IoT
//------------------------
/*
* NUMBER_OF_UE_MAX_NB_IoT maybe in the future should be dynamic because could be very large and the memory may explode
* (is almost the indication of the number of UE context that we are storing at PHY layer)
*
* reasoning: the following data structure (ndlsch, nulsch ecc..) are used to store the context that should be transmitted in at least n+4 subframe later
* (the minimum interval between NPUSCH and the ACK for this)
* the problem is that in NB_IoT the ACK for the UPLINK is contained in the DCI through the NDI field (if this value change from the previous one then it means ACK)
* but may we could schedule this DCI long time later so may lots of contents shuld be stored (there is no concept of phich channel in NB-IoT)
* For the DL transmission the UE send a proper ACK/NACK message
*
* *the HARQ process should be killed when the NDI change
*
* *In the Structure for nulsch we should also store the information related to the subframe (because each time we should read it and understand what should be done
* in that subframe)
*
*/
/*
* TIMING
* the entire transmission and scheduling are done for the "subframe" concept but the subframe = proc->subframe_tx (that in reality is the subframe_rx +4)
* (see USER/lte-enb/wakeup_rxtx )
*
* Related to FAPI:
* DCI and DL_CONFIG.request (also more that 1) and MAC_PDU are transmitted in the same subframe (our assumption) so will be all contained in the schedule_response getting from the scheduler
* DCI0 and UL_CONFIG.request are transmitted in the same subframe (our assumption) so contained in the schedule_response
*
*/
//TODO: check what should be NUMBER_OF_UE_MAX_NB_IoT value
NB_IoT_eNB_NPBCH_t *npbch;
NB_IoT_eNB_NPDCCH_t *npdcch[NUMBER_OF_UE_MAX_NB_IoT];
NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT][2];
NB_IoT_eNB_NULSCH_t *nulsch[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR
NB_IoT_eNB_NDLSCH_t *ndlsch[NUMBER_OF_UE_MAX_NB_IoT];
NB_IoT_eNB_NULSCH_t *ulsch_NB_IoT[NUMBER_OF_UE_MAX_NB_IoT+1]; //nulsch[0] contains the RAR
NB_IoT_eNB_NDLSCH_t *ndlsch_SI,*ndlsch_ra, *ndlsch_SIB1;
NB_IoT_DL_FRAME_PARMS frame_parms_NB_IoT;
// DCI for at most 2 DCI pdus
DCI_PDU_NB_IoT *DCI_pdu;
NB_IoT_eNB_NDLSCH_t *ndlsch_SIB23,*dlsch_ra;
NB_IoT_eNB_NDLSCH_t *ndlsch_RAR;
NB_IoT_eNB_NPDCCH_t *npdcch_DCI;
uint8_t msg3_pdu[6]; //phy_procedures_lte_eNb_NB_IoT.c
volatile uint16_t preamble_index_NB_IoT; //phy_procedures_lte_eNb_NB_IoT.c
} PHY_VARS_eNB_NB_IoT;
typedef struct{
PHY_VARS_eNB *eNB;
PHY_VARS_eNB_NB_IoT *eNB_NB_IoT;
} eNBs_t;
///////// NB_IoT testing ///////////////////////////
void prach_procedures_NB_IoT(PHY_VARS_eNB_NB_IoT *);
void phy_init_lte_top_NB_IoT(NB_IoT_DL_FRAME_PARMS *);
int init_frame_parms_NB_IoT(NB_IoT_DL_FRAME_PARMS *,uint8_t);
///////////////////////////////////////////////////
//#define debug_msg if (((mac_xface->frame%100) == 0) || (mac_xface->frame < 50)) msg
/// Top-level PHY Data Structure for UE
typedef struct {
/// \brief Module ID indicator for this instance
uint8_t Mod_id;
/// \brief Component carrier ID for this PHY instance
uint8_t CC_id;
/// \brief Mapping of CC_id antennas to cards
openair0_rf_map rf_map;
//uint8_t local_flag;
@@ -861,66 +847,6 @@ typedef struct {
///
char ulsch_no_allocation_counter[NUMBER_OF_CONNECTED_eNB_MAX];
/*
unsigned char ulsch_Msg3_active[NUMBER_OF_CONNECTED_eNB_MAX];
uint32_t ulsch_Msg3_frame[NUMBER_OF_CONNECTED_eNB_MAX];
unsigned char ulsch_Msg3_subframe[NUMBER_OF_CONNECTED_eNB_MAX];
PRACH_RESOURCES_t *prach_resources[NUMBER_OF_CONNECTED_eNB_MAX];
int turbo_iterations, turbo_cntl_iterations;
/// \brief ?.
/// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
uint32_t total_TBS[NUMBER_OF_CONNECTED_eNB_MAX];
/// \brief ?.
/// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
uint32_t total_TBS_last[NUMBER_OF_CONNECTED_eNB_MAX];
/// \brief ?.
/// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
uint32_t bitrate[NUMBER_OF_CONNECTED_eNB_MAX];
/// \brief ?.
/// - first index: eNB [0..NUMBER_OF_CONNECTED_eNB_MAX[ (hard coded)
uint32_t total_received_bits[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_errors[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_errors_last[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_received[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_received_last[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_fer[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_SI_received[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_SI_errors[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_ra_received[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_ra_errors[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_p_received[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_p_errors[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mch_received_sf[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mch_received[NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mcch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mtch_received[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mcch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mtch_errors[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mcch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int dlsch_mtch_trials[MAX_MBSFN_AREA][NUMBER_OF_CONNECTED_eNB_MAX];
int current_dlsch_cqi[NUMBER_OF_CONNECTED_eNB_MAX];
unsigned char first_run_timing_advance[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t generate_prach;
uint8_t prach_cnt;
uint8_t prach_PreambleIndex;
// uint8_t prach_timer;
uint8_t decode_SIB;
uint8_t decode_MIB;
int rx_offset; /// Timing offset
int rx_offset_diff; /// Timing adjustment for ofdm symbol0 on HW USRP
int timing_advance; ///timing advance signalled from eNB
int hw_timing_advance;
int N_TA_offset; ///timing offset used in TDD
/// Flag to tell if UE is secondary user (cognitive mode)
unsigned char is_secondary_ue;
/// Flag to tell if secondary eNB has channel estimates to create NULL-beams from.
unsigned char has_valid_precoder;
/// hold the precoder for NULL beam to the primary eNB
int **ul_precoder_S_UE;
/// holds the maximum channel/precoder coefficient
char log2_maxp;
*/
/// if ==0 enables phy only test mode
int mac_enabled;
/// Flag to initialize averaging of PHY measurements
@@ -935,103 +861,12 @@ typedef struct {
double sinr_eff;
/// N0 (used for abstraction)
double N0;
/*
/// PDSCH Varaibles
PDSCH_CONFIG_DEDICATED pdsch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
/// PUSCH Varaibles
PUSCH_CONFIG_DEDICATED pusch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
/// PUSCH contention-based access vars
PUSCH_CA_CONFIG_DEDICATED pusch_ca_config_dedicated[NUMBER_OF_eNB_MAX]; // lola
/// PUCCH variables
PUCCH_CONFIG_DEDICATED pucch_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
uint8_t ncs_cell[20][7];
/// UL-POWER-Control
UL_POWER_CONTROL_DEDICATED ul_power_control_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
/// TPC
TPC_PDCCH_CONFIG tpc_pdcch_config_pucch[NUMBER_OF_CONNECTED_eNB_MAX];
TPC_PDCCH_CONFIG tpc_pdcch_config_pusch[NUMBER_OF_CONNECTED_eNB_MAX];
/// CQI reporting
CQI_REPORT_CONFIG cqi_report_config[NUMBER_OF_CONNECTED_eNB_MAX];
/// SRS Variables
SOUNDINGRS_UL_CONFIG_DEDICATED soundingrs_ul_config_dedicated[NUMBER_OF_CONNECTED_eNB_MAX];
/// Scheduling Request Config
SCHEDULING_REQUEST_CONFIG scheduling_request_config[NUMBER_OF_CONNECTED_eNB_MAX];
/// Transmission mode per eNB
uint8_t transmission_mode[NUMBER_OF_CONNECTED_eNB_MAX];
time_stats_t phy_proc;
time_stats_t phy_proc_tx;
time_stats_t phy_proc_rx[2];
uint32_t use_ia_receiver;
time_stats_t ofdm_mod_stats;
time_stats_t ulsch_encoding_stats;
time_stats_t ulsch_modulation_stats;
time_stats_t ulsch_segmentation_stats;
time_stats_t ulsch_rate_matching_stats;
time_stats_t ulsch_turbo_encoding_stats;
time_stats_t ulsch_interleaving_stats;
time_stats_t ulsch_multiplexing_stats;
time_stats_t generic_stat;
time_stats_t pdsch_procedures_stat;
time_stats_t dlsch_procedures_stat;
time_stats_t ofdm_demod_stats;
time_stats_t dlsch_rx_pdcch_stats;
time_stats_t rx_dft_stats;
time_stats_t dlsch_channel_estimation_stats;
time_stats_t dlsch_freq_offset_estimation_stats;
time_stats_t dlsch_decoding_stats[2];
time_stats_t dlsch_demodulation_stats;
time_stats_t dlsch_rate_unmatching_stats;
time_stats_t dlsch_turbo_decoding_stats;
time_stats_t dlsch_deinterleaving_stats;
time_stats_t dlsch_llr_stats;
time_stats_t dlsch_unscrambling_stats;
time_stats_t dlsch_rate_matching_stats;
time_stats_t dlsch_turbo_encoding_stats;
time_stats_t dlsch_interleaving_stats;
time_stats_t dlsch_tc_init_stats;
time_stats_t dlsch_tc_alpha_stats;
time_stats_t dlsch_tc_beta_stats;
time_stats_t dlsch_tc_gamma_stats;
time_stats_t dlsch_tc_ext_stats;
time_stats_t dlsch_tc_intl1_stats;
time_stats_t dlsch_tc_intl2_stats;
time_stats_t tx_prach;
/// RF and Interface devices per CC
openair0_device rfdevice;
time_stats_t dlsch_encoding_SIC_stats;
time_stats_t dlsch_scrambling_SIC_stats;
time_stats_t dlsch_modulation_SIC_stats;
time_stats_t dlsch_llr_stripping_unit_SIC_stats;
time_stats_t dlsch_unscrambling_SIC_stats;
#if ENABLE_RAL
hash_table_t *ral_thresholds_timed;
SLIST_HEAD(ral_thresholds_gen_poll_s, ral_threshold_phy_t) ral_thresholds_gen_polled[RAL_LINK_PARAM_GEN_MAX];
SLIST_HEAD(ral_thresholds_lte_poll_s, ral_threshold_phy_t) ral_thresholds_lte_polled[RAL_LINK_PARAM_LTE_MAX];
#endif
*/
} PHY_VARS_UE_NB_IoT;
#include "PHY/INIT/defs_NB_IoT.h"
#include "PHY/LTE_REFSIG/defs_NB_IoT.h"
#include "PHY/LTE_TRANSPORT/proto_NB_IoT.h"
#include "PHY/NBIoT_TRANSPORT/proto_NB_IoT.h"
#endif // __PHY_DEFS__H__

View File

@@ -59,12 +59,12 @@
#include "defs_common.h"
#include "impl_defs_top.h"
#include "LTE_UE_TRANSPORT/transport_ue.h"
#include "PHY/TOOLS/time_meas.h"
#include "PHY/CODING/coding_defs.h"
#include "PHY/TOOLS/tools_defs.h"
#include "platform_types.h"
#include "PHY/LTE_UE_TRANSPORT/transport_ue.h"
#include "LTE_UE_TRANSPORT/transport_ue.h"
#include "PHY/LTE_TRANSPORT/transport_eNB.h" // for SIC
#include <pthread.h>
#include "assertions.h"

View File

@@ -631,6 +631,8 @@ typedef struct {
uint8_t srsX;
/// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0).
uint8_t node_id;
/// flag to indicate SISO transmission
uint8_t mode1_flag;
/// Indicator that 20 MHz channel uses 3/4 sampling frequency
uint8_t threequarter_fs;
/// Size of FFT
@@ -1188,5 +1190,217 @@ static inline int release_thread(pthread_mutex_t *mutex,int *instance_cnt,char *
return(0);
}
typedef struct {
/// Component Carrier index
uint8_t CC_id;
/// timestamp transmitted to HW
openair0_timestamp timestamp_tx;
/// subframe to act upon for transmission
int subframe_tx;
/// subframe to act upon for reception
int subframe_rx;
/// frame to act upon for transmission
int frame_tx;
/// frame to act upon for reception
int frame_rx;
uint16_t HFN;
/// \brief Instance count for RXn-TXnp4 processing thread.
/// \internal This variable is protected by \ref mutex_rxtx.
int instance_cnt_rxtx;
/// pthread structure for RXn-TXnp4 processing thread
pthread_t pthread_rxtx;
/// pthread attributes for RXn-TXnp4 processing thread
pthread_attr_t attr_rxtx;
/// condition variable for tx processing thread
pthread_cond_t cond_rxtx;
/// mutex for RXn-TXnp4 processing thread
pthread_mutex_t mutex_rxtx;
/// scheduling parameters for RXn-TXnp4 thread
struct sched_param sched_param_rxtx;
uint32_t ra_rnti_computed;
uint8_t dci_to_transmit;
uint32_t frame_dscr_msg3;
uint32_t subframe_dscr_msg3;
uint32_t frame_msg5;
uint32_t subframe_msg5;
uint8_t rar_to_transmit;
uint8_t subframe_SP;
uint8_t subframe_SP2;
int next_frame_tx;
int next_subframe_tx;
uint8_t SP;
uint8_t SP2;
uint8_t there_is_sib23;
int next_frame_tx_DCI;
int next_subframe_tx_DCI;
int subframe_delay;
int subframe_real;
uint32_t sheduling_info_rar;
uint8_t flag_scrambling;
uint8_t flag_msg3;
uint8_t counter_msg3;
uint32_t frame_msg3;
uint8_t flag_DCI_msg4;
uint8_t flag_msg4;
uint8_t counter_DCI_msg4;
uint8_t counter_msg4;
uint32_t frame_DCI_msg4;
uint32_t frame_msg4;
uint32_t subframe_DCI_msg4;
uint32_t subframe_msg4;
uint8_t guard;
uint8_t counter_msg5;
uint8_t remaining_dci;
uint8_t remaining_rar;
uint8_t flag_msg5;
uint32_t frame_dscr_msg5;
uint32_t subframe_dscr_msg5;
} eNB_rxtx_proc_NB_IOT_t;
/// Context data structure for eNB subframe processing
typedef struct eNB_proc_t_s {
/// Component Carrier index
uint8_t CC_id;
/// thread index
int thread_index;
/// timestamp received from HW
openair0_timestamp timestamp_rx;
/// timestamp to send to "slave rru"
openair0_timestamp timestamp_tx;
/// subframe to act upon for reception
int subframe_rx;
/// symbol mask for IF4p5 reception per subframe
uint32_t symbol_mask[10];
/// subframe to act upon for PRACH
int subframe_prach;
/// frame to act upon for reception
int frame_rx;
/// frame to act upon for transmission
int frame_tx;
/// frame offset for secondary eNBs (to correct for frame asynchronism at startup)
int frame_offset;
/// frame to act upon for PRACH
int frame_prach;
/// \internal This variable is protected by \ref mutex_fep.
int instance_cnt_fep;
/// \internal This variable is protected by \ref mutex_td.
int instance_cnt_td;
/// \internal This variable is protected by \ref mutex_te.
int instance_cnt_te;
/// \brief Instance count for FH processing thread.
/// \internal This variable is protected by \ref mutex_FH.
int instance_cnt_FH;
/// \brief Instance count for rx processing thread.
/// \internal This variable is protected by \ref mutex_prach.
int instance_cnt_prach;
// instance count for over-the-air eNB synchronization
int instance_cnt_synch;
/// \internal This variable is protected by \ref mutex_asynch_rxtx.
int instance_cnt_asynch_rxtx;
/// pthread structure for FH processing thread
pthread_t pthread_FH;
/// pthread structure for eNB single processing thread
pthread_t pthread_single;
/// pthread structure for asychronous RX/TX processing thread
pthread_t pthread_asynch_rxtx;
/// flag to indicate first RX acquisition
int first_rx;
/// flag to indicate first TX transmission
int first_tx;
/// pthread attributes for parallel fep thread
pthread_attr_t attr_fep;
/// pthread attributes for parallel turbo-decoder thread
pthread_attr_t attr_td;
/// pthread attributes for parallel turbo-encoder thread
pthread_attr_t attr_te;
/// pthread attributes for FH processing thread
pthread_attr_t attr_FH;
/// pthread attributes for single eNB processing thread
pthread_attr_t attr_single;
/// pthread attributes for prach processing thread
pthread_attr_t attr_prach;
/// pthread attributes for over-the-air synch thread
pthread_attr_t attr_synch;
/// pthread attributes for asynchronous RX thread
pthread_attr_t attr_asynch_rxtx;
/// scheduling parameters for parallel fep thread
struct sched_param sched_param_fep;
/// scheduling parameters for parallel turbo-decoder thread
struct sched_param sched_param_td;
/// scheduling parameters for parallel turbo-encoder thread
struct sched_param sched_param_te;
/// scheduling parameters for FH thread
struct sched_param sched_param_FH;
/// scheduling parameters for single eNB thread
struct sched_param sched_param_single;
/// scheduling parameters for prach thread
struct sched_param sched_param_prach;
/// scheduling parameters for over-the-air synchronization thread
struct sched_param sched_param_synch;
/// scheduling parameters for asynch_rxtx thread
struct sched_param sched_param_asynch_rxtx;
/// pthread structure for parallel fep thread
pthread_t pthread_fep;
/// pthread structure for parallel turbo-decoder thread
pthread_t pthread_td;
/// pthread structure for parallel turbo-encoder thread
pthread_t pthread_te;
/// pthread structure for PRACH thread
pthread_t pthread_prach;
/// pthread structure for eNB synch thread
pthread_t pthread_synch;
/// condition variable for parallel fep thread
pthread_cond_t cond_fep;
/// condition variable for parallel turbo-decoder thread
pthread_cond_t cond_td;
/// condition variable for parallel turbo-encoder thread
pthread_cond_t cond_te;
/// condition variable for FH thread
pthread_cond_t cond_FH;
/// condition variable for PRACH processing thread;
pthread_cond_t cond_prach;
// condition variable for over-the-air eNB synchronization
pthread_cond_t cond_synch;
/// condition variable for asynch RX/TX thread
pthread_cond_t cond_asynch_rxtx;
/// mutex for parallel fep thread
pthread_mutex_t mutex_fep;
/// mutex for parallel turbo-decoder thread
pthread_mutex_t mutex_td;
/// mutex for parallel turbo-encoder thread
pthread_mutex_t mutex_te;
/// mutex for FH
pthread_mutex_t mutex_FH;
/// mutex for PRACH thread
pthread_mutex_t mutex_prach;
// mutex for over-the-air eNB synchronization
pthread_mutex_t mutex_synch;
/// mutex for asynch RX/TX thread
pthread_mutex_t mutex_asynch_rxtx;
/// parameters for turbo-decoding worker thread
// td_params tdp;
/// parameters for turbo-encoding worker thread
// te_params tep;
/// set of scheduling variables RXn-TXnp4 threads
eNB_rxtx_proc_NB_IOT_t proc_rxtx[2];
/// number of slave threads
int num_slaves;
/// array of pointers to slaves
struct eNB_proc_t_s **slave_proc;
} eNB_proc_t;
#endif // __PHY_DEFS__H__

View File

@@ -73,7 +73,6 @@
#include "openair2/PHY_INTERFACE/IF_Module.h"
typedef struct RU_proc_t_s {
/// Pointer to associated RU descriptor
struct RU_t_s *ru;
@@ -605,6 +604,12 @@ typedef struct {
/// - first index: tx antenna [0..14[ where 14 is the total supported antenna ports.
/// - second index: sample [0..]
int32_t **txdataF;
/// \brief Holds the beamforming weights
/// - first index: eNB id [0..2] (hard coded)
/// - second index: eNB antenna port index (hard coded)
/// - third index: tx antenna [0..nb_antennas_tx[
/// - fourth index: sample [0..]
int32_t **beam_weights[3][15];
} LTE_eNB_COMMON;
typedef struct {
@@ -764,6 +769,7 @@ typedef struct {
pthread_mutex_t mutex_RUs;
} L1_rxtx_proc_t;
typedef struct {
struct PHY_VARS_eNB_s *eNB;
int UE_id;
@@ -1109,7 +1115,7 @@ typedef struct PHY_VARS_eNB_s {
uint32_t max_peak_val;
int max_eNB_id, max_sync_pos;
int N_TA_offset; ///timing offset used in TDD
/// \brief sinr for all subcarriers of the current link (used only for abstraction).
/// first index: ? [0..N_RB_DL*12[
double *sinr_dB;
@@ -1120,7 +1126,8 @@ typedef struct PHY_VARS_eNB_s {
unsigned char first_run_timing_advance[NUMBER_OF_UE_MAX];
unsigned char first_run_I0_measurements;
unsigned char cooperation_flag; // for cooperative communication
unsigned char is_secondary_eNB; // primary by default
unsigned char is_init_sync; /// Flag to tell if initial synchronization is performed. This affects how often the secondary eNB will listen to the PSS from the primary system.
unsigned char has_valid_precoder; /// Flag to tell if secondary eNB has channel estimates to create NULL-beams from, and this B/F vector is created.

View File

@@ -0,0 +1,139 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __PHY_EXTERN_NB_IOT_H__
#define __PHY_EXTERN_NB_IOT_H__
//#include "PHY/defs.h"
#include "PHY/defs_L1_NB_IoT.h"
//#include "openair2/PHY_INTERFACE/defs_NB_IoT.h"
//#include "PHY_INTERFACE/IF_Module_NB_IoT.h"
/*
extern char* namepointer_chMag ;
extern char* namepointer_log2;
extern char fmageren_name2[512];
extern unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX];
extern unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
*/
#include "PHY/NBIoT_TRANSPORT/extern_NB_IoT.h"
//#include "SIMULATION/ETH_TRANSPORT/extern.h"
extern unsigned int DAQ_MBOX_NB_IoT;
extern int number_of_cards_NB_IoT;
//extern PHY_CONFIG *PHY_config;
//extern PHY_VARS *PHY_vars;
#ifndef OCP_FRAMEWORK
extern PHY_VARS_UE_NB_IoT ***PHY_vars_UE_NB_IoT_g;
extern PHY_VARS_eNB_NB_IoT ***PHY_vars_eNB_NB_IoT_g;
extern PHY_VARS_RN_NB_IoT **PHY_vars_RN_NB_IoT_g;
extern NB_IoT_DL_FRAME_PARMS *nb_iot_frame_parms_g;
#else
#define MAX_UE 10
#define MAX_eNB_NB_IoT 20
extern PHY_VARS_UE_NB_IoT *PHY_vars_UE_NB_IoT_g[MAX_UE][MAX_NUM_CCs];
extern PHY_VARS_eNB_NB_IoT *PHY_vars_eNB_NB_IoT_g[MAX_eNB_NB_IoT][MAX_NUM_CCs];
#endif
//extern MAC_xface_NB_IoT *mac_xface_NB_IoT;
extern short primary_synch_NB_IoT[264];
/*
extern short primary_synch1[144];
extern short primary_synch2[144];
extern unsigned char primary_synch0_tab[72];
extern unsigned char primary_synch1_tab[72];
extern unsigned char primary_synch2_tab[72]; */
extern int16_t *primary_synch0_time_NB_IoT; //!< index: [0..ofdm_symbol_size*2[
// extern int16_t *primary_synch1_time; //!< index: [0..ofdm_symbol_size*2[
// extern int16_t *primary_synch2_time; //!< index: [0..ofdm_symbol_size*2[
extern int *sync_corr_ue0_NB_IoT; //!< index [0..10*samples_per_tti[
/*
extern int *sync_corr_ue1; //!< index [0..10*samples_per_tti[
extern int *sync_corr_ue2; //!< index [0..10*samples_per_tti[
extern int flagMag;
//extern short **txdataF_rep_tmp;
extern char mode_string[4][20];
*/
/*
#ifndef OPENAIR2
extern unsigned char NB_eNB_INST;
extern unsigned char NB_UE_INST;
extern unsigned char NB_RN_INST;
#endif
extern unsigned int ULSCH_max_consecutive_errors;
extern int flag_LA;
extern double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX];
extern double sinr_bler_map_up[MCS_COUNT][2][16];
extern int table_length[MCS_COUNT];
extern double sinr_to_cqi[4][16];
extern int cqi_to_mcs[16];
//for MU-MIMO abstraction using MIESM
//this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively
extern double MI_map_4qam[3][162];
extern double MI_map_16qam[3][197];
extern double MI_map_64qam[3][227];
extern double beta1_dlsch_MI[6][MCS_COUNT];
extern double beta2_dlsch_MI[6][MCS_COUNT];
extern double q_qpsk[8];
extern double q_qam16[8];
extern double q_qam64[8];
extern double p_qpsk[8];
extern double p_qam16[8];
extern double p_qam64[8];
extern double beta1_dlsch[6][MCS_COUNT];
extern double beta2_dlsch[6][MCS_COUNT];
extern char eNB_functions[6][20];
extern char eNB_timing[2][20];
*/
extern int16_t unscrambling_lut_NB_IoT[65536*16];
/*
extern uint8_t scrambling_lut[65536*16];
extern unsigned short msrsb_6_40[8][4];
extern unsigned short msrsb_41_60[8][4];
extern unsigned short msrsb_61_80[8][4];
extern unsigned short msrsb_81_110[8][4];
extern unsigned short Nb_6_40[8][4];
extern unsigned short Nb_41_60[8][4];
extern unsigned short Nb_61_80[8][4];
extern unsigned short Nb_81_110[8][4];
extern uint16_t hundred_times_log10_NPRB[100];
extern uint8_t alpha_lut[8];
*/
#endif /*__PHY_EXTERN_H__ */

View File

@@ -33,7 +33,9 @@
#ifndef __PHY_IMPL_DEFS_NB_IOT__H__
#define __PHY_IMPL_DEFS_NB_IOT__H__
#include "types_NB_IoT.h"
#include "types.h"
//#include "types_NB_IoT.h"
//#include "defs.h"
typedef enum {TDD_NB_IoT=1,FDD_NB_IoT=0} NB_IoT_frame_type_t;
@@ -278,8 +280,10 @@ typedef struct {
int32_t freq_offset;
/// eNb_id user is synched to
int32_t eNb_id;
} NB_IoT_UE_COMMON;
typedef struct {
/// \brief Received frequency-domain signal after extraction.
/// - first index: ? [0..7] (hard coded) FIXME! accessed via \c nb_antennas_rx
@@ -400,7 +404,9 @@ typedef struct NPRACH_Parameters_NB_IoT{
} nprach_parameters_NB_IoT_t;
typedef struct{
nprach_parameters_NB_IoT_t list[3];
nprach_parameters_NB_IoT_t list[3];
}NPRACH_List_NB_IoT_t;
typedef long RSRP_Range_t;
@@ -415,7 +421,7 @@ typedef struct {
/// nprach_CP_Length_r13, for the CP length(unit us) only 66.7 and 266.7 is implemented
uint16_t nprach_CP_Length;
/// The criterion for UEs to select a NPRACH resource. Up to 2 RSRP threshold values can be signalled. \vr{[1..2]}
rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList;
struct rsrp_ThresholdsNPrachInfoList *rsrp_ThresholdsPrachInfoList;
/// NPRACH Parameters List
NPRACH_List_NB_IoT_t nprach_ParametersList;
@@ -469,9 +475,11 @@ typedef struct {
/// Ref signals configuration
UL_REFERENCE_SIGNALS_NPUSCH_t ul_ReferenceSignalsNPUSCH;
} NPUSCH_CONFIG_COMMON;
typedef struct{
/// See TS 36.213 [23, 16.2.1.1], unit dBm.
uint8_t p0_NominalNPUSCH;
@@ -489,18 +497,32 @@ typedef struct {
uint16_t dl_GapDurationCoeff;
} DL_GapConfig_NB_IoT;
#define NBIOT_INBAND_LTEPCI 0
#define NBIOT_INBAND_IOTPCI 1
#define NBIOT_INGUARD 2
#define NBIOT_STANDALONE 3
typedef struct {
/// for inband, lte bandwidth
uint8_t LTE_N_RB_DL;
uint8_t LTE_N_RB_UL;
/// Frame type (0 FDD, 1 TDD)
NB_IoT_frame_type_t frame_type;
/// Number of resource blocks (RB) in DL of the LTE (for knowing the bandwidth)
uint8_t N_RB_DL;
/// Number of resource blocks (RB) in UL of the LTE ((for knowing the bandwidth)
uint8_t N_RB_UL;
/// TDD subframe assignment (0-7) (default = 3) (254=RX only, 255=TX only)
uint8_t tdd_config;
/// Cell ID
uint16_t Nid_cell;
/// Cyclic Prefix for DL (0=Normal CP, 1=Extended CP)
NB_IoT_prefix_type_t Ncp;
/// Cyclic Prefix for UL (0=Normal CP, 1=Extended CP)
NB_IoT_prefix_type_t Ncp_UL;
/// shift of pilot position in one RB
uint8_t nushift;
/// indicates if node is a UE (NODE=2) or eNB (PRIMARY_CH=0).
@@ -528,7 +550,9 @@ typedef struct {
/// flag to indicate SISO transmission
uint8_t mode1_flag;
/// Indicator that 20 MHz channel uses 3/4 sampling frequency
//uint8_t threequarter_fs;
uint8_t threequarter_fs;
/// Size of FFT
uint16_t ofdm_symbol_size;
/// Number of prefix samples in all but first symbol of slot
@@ -582,6 +606,7 @@ typedef struct {
* 3 =stand alone
*/
uint16_t operating_mode;
/*
* Only for In-band operating mode with same PCI
* its measured in number of OFDM symbols
@@ -604,23 +629,67 @@ typedef struct {
*/
uint8_t subcarrier_spacing;
uint8_t nb_antennas_tx_NB_IoT; // to replace with NB_IoT_frame_params
uint8_t flag_free_sf; // flag to indicate for NPDSCH and NPDCCH process if the current SF already used
} NB_IoT_DL_FRAME_PARMS;
typedef struct {
/// \brief Pointers (dynamic) to the received data in the time domain.
/// - first index: rx antenna [0..nb_antennas_rx]
/// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti]
int32_t **rxdata;
/// \brief Pointers (dynamic) to the received data in the frequency domain.
/// - first index: rx antenna [0..nb_antennas_rx[
/// - second index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti]
int32_t **rxdataF;
/// \brief Holds the transmit data in time domain.
/// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
/// - first index: eNB id [0..2] (hard coded)
/// - second index: tx antenna [0..nb_antennas_tx[
/// - third index:
int32_t **txdata[3];
/// \brief holds the transmit data in the frequency domain.
/// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
/// - first index: eNB id [0..2] (hard coded)
/// - second index: tx antenna [0..14[ where 14 is the total supported antenna ports.
/// - third index: sample [0..]
int32_t **txdataF;
int32_t **txdataF[3];
/// \brief holds the transmit data after beamforming in the frequency domain.
/// For IFFT_FPGA this points to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER. //?
/// - first index: eNB id [0..2] (hard coded)
/// - second index: tx antenna [0..nb_antennas_tx[
/// - third index: sample [0..]
int32_t **txdataF_BF[3];
/// \brief Holds the received data in time domain.
/// Should point to the same memory as PHY_vars->rx_vars[a].RX_DMA_BUFFER.
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: sample [0..]
int32_t **rxdata[3];
/// \brief Holds the last subframe of received data in time domain after removal of 7.5kHz frequency offset.
/// - first index: secotr id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: sample [0..samples_per_tti[
int32_t **rxdata_7_5kHz[3];
/// \brief Holds the received data in the frequency domain.
/// - first index: sector id [0..2] (hard coded)
/// - second index: rx antenna [0..nb_antennas_rx[
/// - third index: ? [0..2*ofdm_symbol_size*frame_parms->symbols_per_tti[
int32_t **rxdataF[3];
/// \brief Holds output of the sync correlator.
/// - first index: sector id [0..2] (hard coded)
/// - second index: sample [0..samples_per_tti*10[
uint32_t *sync_corr[3];
/// \brief Holds the beamforming weights
/// - first index: eNB id [0..2] (hard coded)
/// - second index: eNB antenna port index (hard coded)
/// - third index: tx antenna [0..nb_antennas_tx[
/// - fourth index: sample [0..]
int32_t **beam_weights[3][15];
/// \brief Holds the tdd reciprocity calibration coefficients
/// - first index: eNB id [0..2] (hard coded)
/// - second index: tx antenna [0..nb_antennas_tx[
/// - third index: frequency [0..]
int32_t **tdd_calib_coeffs[3];
} NB_IoT_eNB_COMMON;
typedef struct {
@@ -645,6 +714,7 @@ typedef struct {
uint32_t *sync_corr[3];
} NB_IoT_RU_COMMON;
typedef struct {
/// \brief Hold the channel estimates in frequency domain based on SRS.
/// - first index: sector id [0..2] (hard coded)

View File

@@ -109,7 +109,7 @@
#include "defs_eNB.h"
#include "types.h"
#include "LTE_UE_TRANSPORT/transport_ue.h"
/** @addtogroup _PHY_STRUCTURES_
@@ -270,6 +270,20 @@ typedef struct {
int *RX_DMA_BUFFER[2];
} TX_RX_VARS;
/// Top-level PHY Data Structure for RN
typedef struct {
/// Module ID indicator for this instance
uint8_t Mod_id;
uint32_t frame;
// phy_vars_eNB
// phy_vars ue
// cuurently only used to store and forward the PMCH
uint8_t mch_avtive[10];
uint8_t sync_area[10]; // num SF
LTE_UE_DLSCH_t *dlsch_rn_MCH[10];
} PHY_VARS_RN;
/// Measurement Variables
//#define NUMBER_OF_SUBBANDS_MAX 13

View File

@@ -3,7 +3,9 @@
* 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
*

View File

@@ -40,7 +40,7 @@ extern int number_of_cards;
#ifndef OCP_FRAMEWORK
//extern PHY_VARS_eNB ***PHY_vars_eNB_g;
extern PHY_VARS_eNB ***PHY_vars_eNB_g;
extern RAN_CONTEXT_t RC;
extern LTE_DL_FRAME_PARMS *lte_frame_parms_g;
#else

View File

@@ -47,8 +47,8 @@ PHY_VARS_UE ***PHY_vars_UE_g;
RAN_CONTEXT_t RC;
UL_RCC_IND_t UL_RCC_INFO;
//PHY_VARS_eNB ***PHY_vars_eNB_g;
//PHY_VARS_RN **PHY_vars_RN_g;
PHY_VARS_eNB ***PHY_vars_eNB_g;
PHY_VARS_RN **PHY_vars_RN_g;
LTE_DL_FRAME_PARMS *lte_frame_parms_g;
#else
PHY_VARS_UE * PHY_vars_UE_g[MAX_UE][MAX_NUM_CCs]={NULL};

158
openair1/PHY/vars.h Normal file
View File

@@ -0,0 +1,158 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file vars.h
* \brief mac vars
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \version 1.0
* \email navid.nikaein@eurecom.fr
* @ingroup _mac
*/
#ifndef __MAC_VARS_H__
#define __MAC_VARS_H__
#ifdef USER_MODE
//#include "stdio.h"
#endif //USER_MODE
#include "PHY/defs_L1_NB_IoT.h"
#include "defs.h"
#include "defs_NB_IoT.h"
#include "PHY_INTERFACE/defs.h"
#include "COMMON/mac_rrc_primitives.h"
const uint32_t BSR_TABLE[BSR_TABLE_SIZE]= {0,10,12,14,17,19,22,26,31,36,42,49,57,67,78,91,
105,125,146,171,200,234,274,321,376,440,515,603,706,826,967,1132,
1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099,
16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439, 128125,150000, 300000
};
// extended bsr table--currently not used
const uint32_t Extended_BSR_TABLE[BSR_TABLE_SIZE] = {0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,
181,223,274,337,414,509,625,769,945,1162,1429,
1757,2161,2657,3267,4017,4940,6074,7469,9185,
11294,13888,17077,20999,25822,31752,39045,48012,
59039,72598,89272,109774,134986,165989,204111,
250990,308634,379519,466683,573866,705666,867737,
1067031,1312097,1613447,1984009,2439678,3000000,
6000000};
//#define MAX_SIZE_OF_AGG3 576
//#define MAX_SIZE_OF_AGG2 288
//#define MAX_SIZE_OF_AGG1 144
//#define MAX_SIZE_OF_AGG0 72
/*
* If the CQI is low, then scheduler will use a higher aggregation level and lower aggregation level otherwise
* this is also dependent to transmission mode, where an offset could be defined
*/
// the follwoing three tables are calibrated for TXMODE 1 and 2
const uint8_t cqi2fmt0_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 37 bits
//{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 41
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 43
{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE = 44
};
const uint8_t cqi2fmt1x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size < 38 bits
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE < 43
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE < 47
{3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0} // 20_DCI0_CRC_SIZE < 55
};
const uint8_t cqi2fmt2x_agg[MAX_SUPPORTED_BW][CQI_VALUE_RANGE]= {
{3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, // 1.4_DCI0_CRC_Size= 47 bits
{3, 3, 3, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0}, // 5_DCI0_CRC_SIZE = 55
{3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0}, // 10_DCI0_CRC_SIZE = 59
{3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0} // 20_DCI0_CRC_SIZE = 64
};
//uint32_t EBSR_Level[63]={0,10,13,16,19,23,29,35,43,53,65,80,98,120,147,181};
MAC_xface *mac_xface;
uint32_t RRC_CONNECTION_FLAG;
UE_MAC_INST *UE_mac_inst; //[NB_MODULE_MAX];
eNB_MAC_INST *eNB_mac_inst; //[NB_MODULE_MAX];
MAC_RLC_XFACE *Mac_rlc_xface;
/// Primary component carrier index of eNB
int pCC_id[NUMBER_OF_eNB_MAX];
eNB_ULSCH_INFO eNB_ulsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
eNB_DLSCH_INFO eNB_dlsch_info[NUMBER_OF_eNB_MAX][MAX_NUM_CCs][NUMBER_OF_UE_MAX]; // eNBxUE = 8x8
/*
#ifndef USER_MODE
RRC_XFACE *Rrc_xface;
MAC_xface *mac_xface;
#else
#include "PHY_INTERFACE/extern.h"
#include "RRC/LITE/extern.h"
#endif
*/
uint8_t Is_rrc_registered;
#ifdef OPENAIR2
unsigned char NB_eNB_INST=0;
unsigned char NB_UE_INST=0;
unsigned char NB_RN_INST=0;
unsigned char NB_INST=0;
#endif
DCI0_5MHz_TDD_1_6_t UL_alloc_pdu;
DCI1A_5MHz_TDD_1_6_t DLSCH_alloc_pdu1A;
DCI1A_5MHz_TDD_1_6_t RA_alloc_pdu;
DCI1A_5MHz_TDD_1_6_t BCCH_alloc_pdu;
DCI1A_5MHz_TDD_1_6_t CCCH_alloc_pdu;
DCI1_5MHz_TDD_t DLSCH_alloc_pdu;
#if defined(Rel10) || defined(Rel14)
DCI1C_5MHz_t MCCH_alloc_pdu;
#endif
DCI0_5MHz_FDD_t UL_alloc_pdu_fdd;
DCI1A_5MHz_FDD_t DLSCH_alloc_pdu1A_fdd;
DCI1A_5MHz_FDD_t RA_alloc_pdu_fdd;
DCI1A_5MHz_FDD_t BCCH_alloc_pdu_fdd;
DCI1A_5MHz_FDD_t CCCH_alloc_pdu_fdd;
DCI1_5MHz_FDD_t DLSCH_alloc_pdu_fdd;
DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu1;
DCI2_5MHz_2A_TDD_t DLSCH_alloc_pdu2;
DCI1E_5MHz_2A_M10PRB_TDD_t DLSCH_alloc_pdu1E;
#endif

162
openair1/PHY/vars_NB_IoT.h Normal file
View File

@@ -0,0 +1,162 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef __PHY_VARS_NB_IOT_H__
#define __PHY_VARS_NB_IOT_H__
#include "PHY/types_NB_IoT.h"
#include "PHY/defs_L1_NB_IoT.h"
/*
#ifndef USER_MODE
unsigned int RX_DMA_BUFFER[4][NB_ANTENNAS_RX];
unsigned int TX_DMA_BUFFER[4][NB_ANTENNAS_TX];
unsigned int DAQ_MBOX;
#endif
char* namepointer_chMag ;
char fmageren_name2[512];
char* namepointer_log2;
//PHY_CONFIG *PHY_config;
*/
/*
#include "PHY/LTE_REFSIG/primary_synch.h"
int16_t *primary_synch0_time;
int16_t *primary_synch1_time;
int16_t *primary_synch2_time;
*/
//#include "PHY/CODING/vars.h"
//PHY_VARS *PHY_vars;
#ifndef OCP_FRAMEWORK
PHY_VARS_UE_NB_IoT ***PHY_vars_UE_NB_IoT_g;
PHY_VARS_eNB_NB_IoT ***PHY_vars_eNB_NB_IoT_g;
PHY_VARS_RN_NB_IoT **PHY_vars_RN_NB_IoT_g;
//NB_IoT_DL_FRAME_PARMS *lte_frame_parms_g;
#else
PHY_VARS_UE_NB_IoT * PHY_vars_UE_NB_IoT_g[MAX_UE][MAX_NUM_CCs]={NULL};
PHY_vars_eNB_NB_IoT * PHY_vars_eNB_NB_IoT_g[MAX_eNB_NB_IoT][MAX_NUM_CCs]={NULL};
#endif
///*
//unsigned short rev[2048],rev_times4[8192],rev_half[1024];
//unsigned short rev256[256],rev512[512],rev1024[1024],rev4096[4096],rev2048[2048],rev8192[8192];
//*/
/*
char mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"};
#include "PHY/LTE_TRANSPORT/vars.h"
#include "SIMULATION/ETH_TRANSPORT/vars.h"
#ifndef OPENAIR2
unsigned char NB_eNB_INST=0;
unsigned char NB_UE_INST=0;
unsigned char NB_RN_INST=0;
unsigned char NB_INST=0;
#endif
*/
/*
unsigned int ULSCH_max_consecutive_errors = 20;
int number_of_cards;
int flag_LA=0;
int flagMag;
//extern channel_desc_t *eNB2UE[NUMBER_OF_eNB_MAX][NUMBER_OF_UE_MAX];
//extern double ABS_SINR_eff_BLER_table[MCS_COUNT][9][9];
//extern double ABS_beta[MCS_COUNT];odi
double sinr_bler_map[MCS_COUNT][2][MCS_TABLE_LENGTH_MAX];
int table_length[MCS_COUNT];
//double sinr_bler_map_up[MCS_COUNT][2][16];
//for MU-MIMO abstraction using MIESM
//this 2D arrarays contains SINR, MI and RBIR in rows 1, 2, and 3 respectively
double MI_map_4qam[3][162];
double MI_map_16qam[3][197];
double MI_map_64qam[3][227];
// here the first index is for transmission mode 1, 2, 5 and 6 whereas the second index is for the 16 sinr vaues corresponding to 16 CQIs
double sinr_to_cqi[4][16]= { {-2.5051, -2.5051, -1.7451, -0.3655, 1.0812, 2.4012, 3.6849, 6.6754, 8.3885, 8.7970, 12.0437, 14.4709, 15.7281, 17.2424, 17.2424, 17.2424},
{-2.2360, -2.2360, -1.3919, -0.0218, 1.5319, 2.9574, 4.3234, 6.3387, 8.9879, 9.5096, 12.6609, 14.0116, 16.4984, 18.1572, 18.1572, 18.1572},
{-1, -1.0000, -0.4198, -0.0140, 1.0362, 2.3520, 3.5793, 6.1136, 8.4836, 9.0858, 12.4723, 13.9128, 16.2054, 17.7392, 17.7392, 17.7392},
{ -4.1057, -4.1057, -3.3768, -2.2916, -1.1392, 0.1236, 1.2849, 3.1933, 5.9298, 6.4052, 9.6245, 10.9414, 13.5166, 14.9545, 14.9545, 14.9545}
};
//int cqi_to_mcs[16]={0, 0, 1, 3, 5, 7, 9, 13, 15, 16, 20, 23, 25, 27, 27, 27};
int cqi_to_mcs[16]= {0, 0, 1, 2, 4, 6, 8, 11, 13, 16, 18, 20, 23, 25, 27, 28};
//for SNR to MI conversion 7 th order Polynomial coeff
double q_qam16[8]= {3.21151853033897e-10,5.55435952230651e-09,-2.30760065362117e-07,-6.25587743817859e-06,4.62251036452795e-06,0.00224150813158937,0.0393723140344367,0.245486379182639};
double q_qpsk[8]= {1.94491167814437e-09,8.40494123817774e-08,4.75527131198034e-07,-2.48946285301621e-05,-0.000347614016158364,0.00209252225437100,0.0742986115462510,0.488297879889425};
double q_qam64[8]= {2.25934026232206e-11,-1.45992206328306e-10,-3.70861183071900e-08,-1.22206071019319e-06,6.49115500399637e-06,0.00129828997837433,0.0259669554914859,0.166602901214898};
//for MI to SNR conversion 7 th order Polynomial coeff
double p_qpsk[8]= {5982.42405670359,-21568.1135917693,31293.9987036905,-23394.6795043871,9608.34750585489,-2158.15802349899,267.731968719036,-20.6145324295965};
double p_qam16[8]= {7862.12690694170,-28510.3207048338,41542.2150287122,-31088.3036957379,12690.1982361016,-2785.66604739984,326.595462489375,-18.9911849872089};
double p_qam64[8]= {8832.57933013696,-32119.1802555952,46914.2578990397,-35163.8150557183,14343.7419388853,-3126.61025510092,360.954930562237,-18.0358548533343};
// ideal CE MIESM
double beta1_dlsch_MI[6][MCS_COUNT] = { {1.1188, 0.3720, 0.3755, 0.9453, 0.5799, 0.5256, 0.5485, 0.5340, 0.5165, 0.5300, 0.6594, 0.5962, 0.4884, 0.4927, 0.3687, 0.4614, 0.4081, 0.2639,0.2935,0.2520,0.3709,0.2906,0.2612,0.2390}, {0.7138, 0.5533, 0.5533, 0.4828, 0.4998, 0.4843, 0.4942, 0.5323, 0.5142, 0.4756, 0.5792, 0.4167, 0.4445, 0.3942, 0.3789, 0.2756, 0.4456, 0.1650, 0.2254, 0.2353, 0.2097,0.2517,0.3242,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.7146, 0.4789, 0.5392, 0.5556, 0.4975, 0.4847, 0.4691, 0.5261, 0.5278, 0.4962, 0.4468, 0.4113, 0.4622, 0.4609, 0.3946, 0.3991, 0.3532, 0.2439, 0.1898, 0.2929, 0.2712, 0.3367, 0.3591, 0.2571}};
double beta2_dlsch_MI[6][MCS_COUNT] = { {1.1293, 0.3707, 0.3722, 0.9310, 0.5808, 0.5265, 0.5404, 0.5279, 0.5210, 0.5226, 0.6438, 0.5827, 0.4804, 0.4830, 0.3638, 0.4506, 0.4107, 0.2547, 0.2797, 0.2413, 0.3351, 0.2750, 0.2568, 0.2273}, {0.7028, 0.5503, 0.5503, 0.4815, 0.5006, 0.4764, 0.4810, 0.5124, 0.4964, 0.4485, 0.5497, 0.3971, 0.4239, 0.3701, 0.3494, 0.2630, 0.4053, 0.1505, 0.2001,0.2024,0.1788,0.2124,0.2668,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.6980, 0.4694, 0.5379, 0.5483, 0.4982, 0.4737, 0.4611, 0.5051, 0.5020, 0.4672, 0.4357, 0.3957, 0.4389, 0.4344, 0.3645, 0.3661, 0.3301, 0.2179, 0.1730, 0.2536, 0.2389,0.2884,0.2936,0.2226}};
//real CE MIESM
////////
double beta1_dlsch_MI[6][MCS_COUNT] = { {1.32955, 0.59522, 0.54024, 0.98698, 0.81305, 0.76976, 0.69258, 0.69713, 0.70546, 0.69111, 0.81904, 0.72664, 0.79491, 0.72562, 0.53980, 0.33134, 0.50550, 0.40602,0.40281,0.47012,0.50510,0.23540,0.32045,1}, {0.59632, 1.08475, 1.02431, 1.07020, 0.90170, 0.97719, 0.95464, 0.92764, 0.86721, 0.85986, 0.64558, 0.80631, 0.82673, 0.82888, 0.87122, 0.77245, 0.29771, 0.43477, 0.55321, 0.61027, 0.56111, 0.57292, 0.39737,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1},{1.808065416202085, 1.754544945430673,1.902272019362616, 1.790054645392961, 1.563204092967629, 1.585258289348813, 1.579349443720310, 1.570650121437345, 1.545055626608596, 1.362229442426877, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33, 1,1,1,1,1,1,1},{0.77532, 1.07544, 1.10571, 1.04099, 0.91638, 0.88644, 0.96405, 0.86709, 0.94066, 0.84430, 1.24478, 1.09665, 1.42604, 0.79541, 0.71847, 0.71604, 0.74561, 0.36431, 0.41536, 0.52175, 0.47096, 0.49977, 0.59728,1}};
double beta2_dlsch_MI[6][MCS_COUNT] = { {1.36875, 0.59304, 0.53870, 0.98239, 0.81637, 0.76847, 0.69842, 0.69885, 0.69967, 0.69826, 0.82660, 0.70559, 0.78404, 0.70670, 0.55393, 0.36893, 0.52225, 0.39752, 0.40494, 0.46239, 0.49247,0.26900,0.34504,1}, {0.43775, 0.78208, 0.72875, 0.77458, 0.64485, 0.69174, 0.66097, 0.63289, 0.59652, 0.61175, 0.44551, 0.56047, 0.57314, 0.57553, 0.58849, 0.52159, 0.21241, 0.30139, 0.37373, 0.32029, 0.37067, 0.36706, 0.27118,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1},{1.079518113138858, 1.105622953570353, 1.031337449900606, 1.073342032668810, 1.242636589110353, 1.255054927783647, 1.291463834317768, 1.317048698347491, 1.354485054187984, 0.338534029291017, 1.85, 1.79, 1.65, 1.54, 1.46, 1.39, 1.33,1, 1,1,1,1,1,1},{0.54448, 0.73731, 0.79165, 0.74407, 0.68042, 0.64906, 0.71349, 0.62109, 0.65815, 0.60940, 0.90549, 0.78708, 1.03176, 0.58431, 0.53379, 0.51224, 0.52767, 0.26848, 0.29642, 0.36879, 0.34148, 0.35279,0.40633,1}};
////////
//ideal channel estimation values
//double beta1_dlsch[6][MCS_COUNT] = { {2.3814, 0.4956, 0.5273, 1.1708, 0.8014, 0.7889, 0.8111, 0.8139, 0.8124, 0.8479, 1.9280, 1.9664, 2.3857, 2.5147, 2.4511, 3.0158, 2.8643, 5.3013, 5.8594, 6.5372, 7.8073, 7.8030, 7.5295, 7.1320}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
//double beta2_dlsch[6][MCS_COUNT] = { {2.3639, 0.4952, 0.5207, 1.1572, 0.8026, 0.7864, 0.7996, 0.8034, 0.8200, 0.8367, 1.8701, 1.9212, 2.2947, 2.4472, 2.4091, 2.9479, 2.8973, 5.0591, 5.5134, 6.1483, 7.2166, 7.5177, 7.5704, 7.2248}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
/////////double beta1_dlsch[6][MCS_COUNT] = { {1.199175, 1.085656, 0.983872, 0.843789, 0.816093, 0.853078, 0.899236, 0.919665, 0.888673, 0.924181, 0.814176, 0.794108, 0.770653, 0.826266, 0.982043, 0.979621, 0.985176, 0.901741, 0.870311, 0.911303, 0.898923, 1.003359, 0.988535, 1.030639, 1.151038, 1.116939, 1.214118, 1.219148}, {0.5146, 0.5549, 0.7405, 0.6913, 0.7349, 0.7000, 0.7539, 0.7955, 0.8074, 0.7760, 1.8150, 1.6561, 1.9280, 2.3563, 2.6699, 2.3086, 3.1601, 4.5316, 5.2870, 6.0983, 6.5635, 7.7024, 9.9592, 6.6173}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79358, 1.17908, 2.02600, 1.72040, 1.58618, 1.59039, 1.68111, 1.67062, 1.64911, 1.33274, 4.87800, 3.58797, 3.72338, 5.35700, 2.81752, 1.93472, 2.23259, 1,1,1,1,1,1,1}, {0.4445, 0.5918, 0.7118, 0.7115, 0.7284, 0.7202, 0.7117, 0.8111, 0.8239, 0.7907, 1.8456, 1.8144, 2.3830, 2.6634, 2.6129, 2.8127, 2.7372, 4.9424, 4.8763, 6.8413, 7.1493, 9.4180, 10.1230, 8.9613}};
/////////double beta2_dlsch[6][MCS_COUNT] = { {0.534622, 0.596561, 0.500838, 0.471721, 0.548218, 0.547974, 0.924245, 0.836484, 0.776917, 0.879691, 0.875722, 0.666933, 0.666393, 0.755377, 1.074985, 1.080290, 1.010914, 0.790892, 0.793435, 0.860249, 0.901508, 0.967060, 0.951372, 1.011493, 1.106151, 1.117076, 1.209397, 1.227790}, {0.5113, 0.5600, 0.7359, 0.6860, 0.7344, 0.6902, 0.7315, 0.7660, 0.7817, 0.7315, 1.7268, 1.5912, 1.8519, 2.2115, 2.4580, 2.1879, 2.9015, 4.1543, 4.6986, 5.3193, 5.6319, 6.5640, 8.2421, 5.6393}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.79479, 0.52872, 0.90005, 0.77170, 0.73220, 0.72060, 0.75433, 0.75451, 0.75989, 0.67655, 1.68525, 1.31100, 1.46573, 1.99843, 1.57293, 1.62852, 2.10636, 1,1,1,1,1,1,1}, {0.4398, 0.5823, 0.7094, 0.7043, 0.7282, 0.7041, 0.6979, 0.7762, 0.7871, 0.7469, 1.7752, 1.7443, 2.2266, 2.4767, 2.4146, 2.6040, 2.5708, 4.4488, 4.4944, 5.9630, 6.3740, 8.1097, 8.4210, 7.8027}};
//real channel estimation valus
///
double beta1_dlsch[6][MCS_COUNT] = { {2.50200, 0.84047, 0.78195, 1.37929, 1.16871, 1.11906, 1.06303, 1.07447, 1.11403, 1.09223, 2.82502, 2.87556, 3.51254, 3.62920, 3.53638, 2.35980, 3.74126, 8.66532, 7.31772, 9.86882, 10.64939, 6.75208, 9.50664, 13.63057}, {0.92257, 1, 1.80445, 1.43175, 1.42093, 1.37381, 1.45392, 1.47255, 1.47451, 1.41235, 3.9079, 3.38557, 4.13059, 4.93355, 4.97277, 6.04951, 5.88896, 8.68076, 10.23746, 12.37069, 5.50538, 17.29612, 17.95050, 13.27095}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {1.79255, 1.88213, 4.44226, 2.25150, 1.93710, 2.18504, 2.57389, 1.94322, 1.78515, 2.09265, 2.37459, 1.74442, 1.74346, 1.19705, 1.56149, 1.59604, 1.6, 1,1,1,1,1,1,1}, {0.93374, 1.40389, 1.36670, 1.38679, 1.35707, 1.26353, 1.32360, 1.40164, 1.51843, 1.34863, 3.45839, 3.13726, 3.94768, 4.21966, 4.60750, 4.97894, 5.40755, 8.12814, 10.59221, 12.96427, 13.37323, 14.27206, 16.61779, 17.19656}};
double beta2_dlsch[6][MCS_COUNT] = { {2.52163, 0.83231, 0.77472, 1.36536, 1.16829, 1.11186, 1.06287, 1.07292, 1.09946, 1.10650, 2.79174, 2.75655, 3.36651, 3.49011, 3.60903, 2.73517, 3.84009, 8.20312, 7.41739, 9.64081, 10.40911, 8.11765, 10.41923, 9.34300}, {0.67252, 0.8600, 1.28633, 1.01624, 1.03066, 0.97590, 1.02560, 1.01840, 1.00547, 0.97093, 2.72573, 2.33283, 2.86181, 3.40452, 3.47957, 4.08916, 3.97628, 6.14541, 7.11017, 8.42369, 4.04812, 11.42082, 11.57171, 9.28462}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1,1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1,1,1,1,1}, {0.85784, 0.90361, 2.09766, 1.08385, 0.96300, 1.04432, 1.22763, 0.99249, 0.95544, 1.12333, 1.37924, 1.12913, 1.30644, 1.19253, 1.75488, 2.13813, 2.10636, 1,1,1,1,1,1,1}, {0.66288, 0.96402, 0.98545, 0.99386, 0.99981, 0.92678, 0.98978, 0.99600, 1.05538, 0.97777, 2.52504, 2.29338, 2.89631, 3.10812, 3.41916, 3.58671, 3.84166, 6.05254, 7.45821, 9.15812, 9.66330, 10.17852, 11.50519, 11.16299}};
///
#ifdef OCP_FRAMEWORK
#include <enums.h>
#else
char eNB_functions[6][20]={"eNodeB_3GPP","eNodeB_3GPP_BBU","NGFI_RCC_IF4p5","NGFI_RAI_IF4p5","NGFI_RRU_IF5","NGFI_RRU_IF4p5",};
char eNB_timing[2][20]={"synch_to_ext_device","synch_to_other"};
#endif
*/
/// lookup table for unscrambling in RX
int16_t unscrambling_lut_NB_IoT[65536*16] __attribute__((aligned(32)));
/*
/// lookup table for scrambling in TX
uint8_t scrambling_lut[65536*16] __attribute__((aligned(32)));
*/
#endif /*__PHY_VARS_H__ */

View File

@@ -0,0 +1,576 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file IF_Module_L1_primitives_NB_IoT.c
* \brief handling nfapi
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
//#include "PHY/LTE_TRANSPORT/dlsch_tbs_full_NB_IoT.h"
#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
#include "IF_Module_L1_primitives_NB_IoT.h"
//#include "../SCHED/defs.h"
#include "defs_NB_IoT.h"
#include "assertions.h"
//#include "PHY/defs.h"
#include "PHY/defs_L1_NB_IoT.h"
//#include "PHY/extern.h"
#include "PHY/extern_NB_IoT.h"
#include "PHY/phy_extern.h"
#include "PHY/defs_eNB.h"
//#include "PHY/vars.h"
#include "PHY/INIT/defs_NB_IoT.h"
int Irep_to_Nrep_x[16] = {1,2,4,8,16,32,64,128,192,256,384,512,768,1024,1536,2048};
void handle_nfapi_dlsch_pdu_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t *sdu)
{
NB_IoT_eNB_NDLSCH_t *ndlsch;
NB_IoT_eNB_NDLSCH_t *ndlsch23;
NB_IoT_DL_eNB_HARQ_t *ndlsch_harq;
NB_IoT_DL_eNB_HARQ_t *ndlsch_harq23;
nfapi_dl_config_ndlsch_pdu_rel13_t *rel13 = &dl_config_pdu->ndlsch_pdu.ndlsch_pdu_rel13;
int UE_id= -1;
// int flag_malloc;
ndlsch= eNB->ndlsch_SIB1;
ndlsch23= eNB->ndlsch_SIB23;
// if(flag_malloc) free (ndlsch->harq_process);
// ndlsch->harq_process = (NB_IoT_DL_eNB_HARQ_t*) malloc (sizeof(NB_IoT_DL_eNB_HARQ_t));
// flag_malloc = 1 ;
//Check for SI PDU since in NB-IoT there is no DCI for that
//SIB1 (type 0), other DLSCH data (type 1) (include the SI messages) based on our ASSUMPTIONs
//is SIB1-NB
if(rel13->rnti_type == 0 && rel13->rnti == 65535)
{
/*
* the configuration of the NDLSCH PDU for the SIB1-NB shoudl be the following:
* -RNTI type = 0; (BCCH)
* -RNTI = OxFFFF (65535)
* -Repetition number = 0-15 and should be mapped to 4,8,16 as reported in Table 16.4.1.3-3 TS 36.213 (is the schedulingInoSIB1 of the MIB)
* -Number of subframe for resource assignment = may is not neded to know since the scheduling is fixed
* (Spec TS 36.331 "SIB1-NB transmission occur in subframe #4 of every other frame in 16 continuous frame"
* meaning that from the starting point we should transmit the SIB1-NB in 8 subframes among the 16 available (every other))
*
* From spec. TS 36.321 v14.2.o pag 31 --> there is an HARQ process for all the broadcast (so we consider it also for SIB1-NB)
*
*/
//LOG_I(PHY,"B NB-handle_nfapi_dlsch_pdu_NB_IoT SIB1\n");
ndlsch->active = 1;
ndlsch->rnti = 65535;
ndlsch_harq = ndlsch->harq_process;
ndlsch->ndlsch_type = SIB1;
ndlsch->npdsch_start_symbol = rel13->start_symbol; //start symbol for the ndlsch transmission
//ndlsch_harq->pdu = sdu;
//LOG_I(PHY,"B content_sib1:%d\n",sdu);
/////ndlsch->content_sib1.pdu = sdu;
ndlsch_harq->pdu = sdu;
//LOG_I(PHY,"A content_sib1:%d\n",ndlsch->content_sib1.pdu);
//should be from 1 to 8
ndlsch->resource_assignment_SIB1 = rel13->number_of_subframes_for_resource_assignment;//maybe we don't care about it since a fixed schedule
ndlsch->repetition_number_SIB1 = rel13->repetition_number; //is the schedulingInfoSIB1 (value 1-15) of MIB that is mapped into value 4-8-16 (see NDLSCH fapi specs Table 4-47)
ndlsch->modulation = rel13->modulation;
ndlsch->status = ACTIVE_NB_IoT;
//ndlsch->
//SI information in reality have no feedback (so there is no retransmission from the HARQ view point since no ack and nack)
// ndlsch_harq->frame = frame;
// ndlsch_harq->subframe = subframe;
ndlsch->nrs_antenna_ports = rel13->nrs_antenna_ports_assumed_by_the_ue;
ndlsch->scrambling_sequence_intialization = rel13->scrambling_sequence_initialization_cinit;
//LOG_I(PHY,"A NB-handle_nfapi_dlsch_pdu_NB_IoT SIB1\n");
ndlsch_harq->TBS = TBStable_NB_IoT_SIB1[rel13->repetition_number];
}
//is SI message (this is an NDLSCH that will be transmitted very frequently)
else if(rel13->rnti_type == 1 && rel13->rnti == 65535)
{
/*
*
* the configuration of the NDLSCH PDU for the SIB1-NB should be the following:
* RNTI type = 1;
* RNTI = OxFFFF (65535)
* Repetition number = 0 and should be mapped to 1 through Table 16.4.1.3-2 TS 36.213
* Number of subframe for resource assignment = will be evaluated by the MAC based on the value of the "si-TB" field inside the SIB1-NB (value 2 or 8)
*
* From spec. TS 36.321 v14.2.o pag 31 --> there is an HARQ process for all the broadcast
*
* XXX for the moment we are not able to prevent the problem of Error: first transmission but sdu = NULL.
* anyway, the PHY layer if have finished the transmission it will not transmit anything and will generate the error
*
*/
//LOG_I(PHY,"B NB-handle_nfapi_dlsch_pdu_NB_IoT SIB23\n");
ndlsch_harq23 = ndlsch23->harq_process;
//new SI starting transmission (should enter here only the first time for a new transmission)
if(sdu != NULL)
{
ndlsch23->active = 1;
ndlsch23->ndlsch_type = SI_Message;
ndlsch23->rnti = 65535;
ndlsch23->npdsch_start_symbol = rel13->start_symbol; //start OFDM symbol for the ndlsch transmission
//ndlsch_harq->pdu = sdu;
//LOG_I(PHY,"B content_sib23:%d\n",sdu);
ndlsch_harq23->pdu = sdu;
ndlsch_harq23->repetition_number = rel13->repetition_number;//should be always fix to 0 to be mapped in 1
ndlsch_harq23->modulation = rel13->modulation;
ndlsch_harq23->TBS = rel13->length;
//LOG_I(PHY,"A content_sib23:%d\n",sdu);
ndlsch23->resource_assignment = rel13->number_of_subframes_for_resource_assignment;//value 2 or 8
ndlsch23->counter_repetition_number = rel13->number_of_subframes_for_resource_assignment;
ndlsch23->counter_current_sf_repetition = 0;
ndlsch23->pointer_to_subframe = 0;
//SI information in reality have no feedback (so there is no retransmission from the HARQ view point since no sck and nack)
// ndlsch_harq->frame = frame;
// ndlsch_harq->subframe = subframe;
ndlsch23->nrs_antenna_ports = rel13->nrs_antenna_ports_assumed_by_the_ue;
ndlsch23->scrambling_sequence_intialization = rel13->scrambling_sequence_initialization_cinit;
}
else
{
//continue the remaining transmission of the previous SI at PHY if any (otherwise nothing)
//there is no need of repeating the configuration on the ndlsch
//ndlsch_harq->pdu = NULL;
//LOG_I(PHY,"sib23=NULL\n");
ndlsch_harq23->pdu = NULL;
}
//Independently if we have the PDU or not (first transmission or repetition) the process is activated for triggering the ndlsch_procedure
//LOG_I(PHY,"ACTIVE_NB_IoT\n");
ndlsch_harq23->status = ACTIVE_NB_IoT;
//LOG_D(PHY,"A NB-handle_nfapi_dlsch_pdu_NB_IoT SIB23\n");
}
//ue specific data or RAR (we already have received the DCI for this)
else if(rel13->rnti != 65535 && rel13->rnti_type == 1)
{
//printf("rel13->rnti: %d, eNB->ndlsch_RAR->rnti: %d\n",rel13->rnti,eNB->ndlsch_RAR->rnti);
//eNB->ndlsch_RAR->rnti = rel13->rnti;
//check if the PDU is for RAR
//if(eNB->ndlsch_RAR != NULL && eNB->ndlsch_RAR->ndlsch_type == RAR) //rnti for the RAR should have been set priviously by the DCI
if(eNB->ndlsch_RAR != NULL && rel13->rnti == eNB->ndlsch_RAR->rnti) //rnti for the RAR should have been set priviously by the DCI
{
eNB->ndlsch_RAR->active = 1;
eNB->ndlsch_RAR->active_msg2 = 1; /// activated only when NPDSCH is transmitting msg2
eNB->ndlsch_RAR->rnti = rel13->rnti;
eNB->ndlsch_RAR->npdsch_start_symbol = rel13->start_symbol;
eNB->ndlsch_RAR->rnti_type = rel13->rnti_type;
eNB->ndlsch_RAR->resource_assignment = rel13->resource_assignment; // for NDLSCH // this value point to --> number of subframes needed
eNB->ndlsch_RAR->repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
eNB->ndlsch_RAR->modulation = rel13->modulation;
eNB->ndlsch_RAR->number_of_subframes_for_resource_assignment = rel13->number_of_subframes_for_resource_assignment; // for NDLSCH //table 16.4.1.3-1 // TS 36.213
eNB->ndlsch_RAR->counter_repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
eNB->ndlsch_RAR->counter_current_sf_repetition = 0;
eNB->ndlsch_RAR->pointer_to_subframe = 0;
//printf("number of subframe : %d, Rep of subframe : %d\n",eNB->ndlsch_RAR->number_of_subframes_for_resource_assignment,eNB->ndlsch_RAR->counter_repetition_number);
eNB->ndlsch_RAR->harq_process->TBS = rel13->length;
eNB->ndlsch_RAR->harq_process->pdu = sdu;
}
else
{ //this for ue data
//TODO
LOG_I(PHY,"handling MSG4 or ue-spec data\n");
//program addition DLSCH parameters not from DCI (for the moment we only pass the pdu)
//int UE_id = find_dlsch(rel13->rnti,eNB,SEARCH_EXIST);
UE_id = 0;
//UE_id = find_ue_NB_IoT(rel13->rnti,eNB);
//AssertFatal(UE_id==-1,"no existing ue specific dlsch_context\n");
ndlsch = eNB->ndlsch[(uint8_t)UE_id];
ndlsch_harq = eNB->ndlsch[(uint8_t)UE_id]->harq_process;
AssertFatal(ndlsch_harq!=NULL,"dlsch_harq for ue specific is null\n");
ndlsch->active = 1;
ndlsch->rnti = rel13->rnti; // how this value is tested in line 177 ???? i am missing something ????
ndlsch->npdsch_start_symbol = rel13->start_symbol;
ndlsch->rnti_type = rel13->rnti_type;
ndlsch->resource_assignment = rel13->resource_assignment ; // for NDLSCH // this value point to --> number of subframes needed
ndlsch->repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
ndlsch->modulation = rel13->modulation;
ndlsch->number_of_subframes_for_resource_assignment = rel13->number_of_subframes_for_resource_assignment; // for NDLSCH //table 16.4.1.3-1 // TS 36.213
ndlsch->counter_repetition_number = Irep_to_Nrep_x[rel13->repetition_number];
ndlsch->counter_current_sf_repetition = 0;
ndlsch->pointer_to_subframe = 0;
ndlsch_harq->TBS = rel13->length;
ndlsch_harq->pdu = sdu;
}
}
//I don't know which kind of data is
else
{
LOG_E(PHY, "handle_nfapi_dlsch_pdu_NB_IoT: Unknown type of data (rnti type %d, rnti %d)\n", rel13->rnti_type, rel13->rnti);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//Memo for initialization TODO: target/SIMU/USER/init_lte.c/init_lte_eNB --> new_eNB_dlsch(..) //
//this is where the allocation of PHy_vars_eNB_NB_IoT and all the ndlsch structures happen //
/////////////////////////////////////////////////////////////////////////////////////////////////
// do the schedule response and trigger the TX
void schedule_response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO)
{
//LOG_I(PHY,"schedule_response_NB_IoT\n");
//XXX check if correct to take eNB like this
PHY_VARS_eNB_NB_IoT *eNB = PHY_vars_eNB_NB_IoT_g[0][Sched_INFO->CC_id];
eNB_rxtx_proc_NB_IoT_t *proc = &eNB->proc.proc_rxtx[0];
NB_IoT_eNB_NPBCH_t *npbch;
///
int i;
//module_id_t Mod_id = Sched_INFO->module_id;
//uint8_t CC_id = Sched_INFO->CC_id;
nfapi_dl_config_request_t *DL_req = Sched_INFO->DL_req;
nfapi_ul_config_request_t *UL_req = Sched_INFO->UL_req;
nfapi_hi_dci0_request_t *HI_DCI0_req = Sched_INFO->HI_DCI0_req;
nfapi_tx_request_t *TX_req = Sched_INFO->TX_req;
//uint32_t hypersfn = Sched_INFO->hypersfn;
//frame_t frame = Sched_INFO->frame; // unused for instance
sub_frame_t subframe = Sched_INFO->subframe;
// implicite declaration of AssertFatal
//AsserFatal(proc->subframe_tx != subframe, "Current subframe %d != NFAPI subframe %d\n",proc->subframe_tx,subframe);
//AsserFatal(proc->frame_tx != frame, "Current sframe %d != NFAPI frame %d\n", proc->frame_tx,frame );
uint8_t number_dl_pdu = DL_req->dl_config_request_body.number_pdu;
uint8_t number_ul_pdu = UL_req->ul_config_request_body.number_of_pdus;
uint8_t number_ul_dci = HI_DCI0_req->hi_dci0_request_body.number_of_dci;
/*
if(number_dl_pdu>=5) number_dl_pdu=0;
if(number_ul_dci>=5) number_ul_dci=0;
*/
//uint8_t number_pdsch_rnti = DL_req->number_pdsch_rnti; // for the moment not used
// at most 2 pdus (DCI) in the case of NPDCCH
nfapi_dl_config_request_pdu_t *dl_config_pdu;
nfapi_ul_config_request_pdu_t *ul_config_pdu;
nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu;
//clear previous possible allocation (maybe something else should be added)
for(int i = 0; i < NUMBER_OF_UE_MAX_NB_IoT; i++)
{
if(eNB->ndlsch[i])
{
eNB->ndlsch[i]->harq_process->round=0; // may not needed
/*clear previous allocation information for all UEs*/
eNB->ndlsch[i]->subframe_tx[subframe] = 0;
}
/*clear the DCI allocation maps for new subframe*/
if(eNB->ulsch_NB_IoT[i])
{
eNB->ulsch_NB_IoT[i]->harq_process->dci_alloc = 0; //flag for indicating that a DCI has been allocated for UL
eNB->ulsch_NB_IoT[i]->harq_process->rar_alloc = 0; //Flag indicating that this ULSCH has been allocated by a RAR (for Msg3)
//no phich for NB-IoT so no DMRS should be utilized
}
}
for (i=0;i<number_dl_pdu;i++) //in principle this should be at most 2 (in case of DCI)
{
dl_config_pdu = &DL_req->dl_config_request_body.dl_config_pdu_list[i];
//LOG_I(PHY, "number_dl_pdu: %d ,dl_config_pdu type: %d\n",number_dl_pdu,dl_config_pdu->pdu_type);
switch (dl_config_pdu->pdu_type)
{
case NFAPI_DL_CONFIG_NPDCCH_PDU_TYPE:
//Remember: there is no DCI for SI information
//LOG_D(PHY,"Generate DL DCI PDU information from scheduler\n");
//TODO: separate the ndlsch structure configuration from the DCI (here we will encode only the DCI)
generate_eNB_dlsch_params_NB_IoT(eNB,proc,dl_config_pdu);
break;
case NFAPI_DL_CONFIG_NBCH_PDU_TYPE:
// for the moment we don't care about the n-bch pdu content since we need only the sdu if tx.request
npbch = eNB->npbch; //in the main of the lte-softmodem they should allocate this memory of PHY_vars
npbch->h_sfn_lsb = dl_config_pdu->nbch_pdu.nbch_pdu_rel13.hyper_sfn_2_lsbs;
//LOG_I(PHY,"npbch->pdu\n");
dl_config_pdu->nbch_pdu.nbch_pdu_rel13.pdu_index = 1;
if(TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->nbch_pdu.nbch_pdu_rel13.pdu_index].segments[0].segment_data != NULL)
npbch->pdu = TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->nbch_pdu.nbch_pdu_rel13.pdu_index].segments[0].segment_data;
else
LOG_E(PHY, "Received a schedule_response with N-BCH but no SDU!!\n");
break;
case NFAPI_DL_CONFIG_NDLSCH_PDU_TYPE:
//we can have three types of NDLSCH based on our assumptions: SIB1, SI, Data, RAR
//remember that SI messages have no DCI in NB-IoT therefore this is the only way to configure the ndlsch_SI/ndlsch_SIB1 structures ndlsch->active = 1;
/*
* OBSERVATION:
* Although 2 DCI may be received over a schedule_response the transmission of the NDLSCH data foresees only 1 NDLSCH PDU at time.
* Therefore is the MAC scheduler that knowing the different timing delay will send the corresponding schedule_response containing the NDLSCH PDU and the MAC PDU
* at the proper DL subframe
* -for this reason the activation of the ndslch structure is done only when we receive the NDLSCH pdu (here) such the in the TX procedure only 1 ue-specific pdu
* result active from the loop before calling the ndlsch_procedure
*/
dl_config_pdu->ndlsch_pdu.ndlsch_pdu_rel13.pdu_index = 1;
handle_nfapi_dlsch_pdu_NB_IoT(eNB, proc,dl_config_pdu,TX_req->tx_request_body.tx_pdu_list[dl_config_pdu->ndlsch_pdu.ndlsch_pdu_rel13.pdu_index].segments[0].segment_data);
break;
default:
LOG_D(PHY, "dl_config_pdu type not for NB_IoT\n");
break;
}
}
for (i=0;i<number_ul_dci;i++)
{
hi_dci0_pdu = &HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list[i];
LOG_D(PHY, "number_ul_dci:%d ,hi_dci0_pdu->pdu_type: %d\n",number_ul_dci,hi_dci0_pdu->pdu_type);
switch (hi_dci0_pdu->pdu_type)
{
case NFAPI_HI_DCI0_NPDCCH_DCI_PDU_TYPE:
LOG_I(PHY, "hi_dci0_pdu type for NB_IoT\n");
generate_eNB_ulsch_params_NB_IoT(eNB,proc,hi_dci0_pdu);
break;
default:
LOG_E(PHY, "hi_dci0_pdu type not for NB_IoT\n");
break;
}
}
for(i = 0; i< number_ul_pdu; i++)
{
ul_config_pdu = &UL_req->ul_config_request_body.ul_config_pdu_list[i];
NB_IoT_eNB_NULSCH_t *nulsch;
NB_IoT_UL_eNB_HARQ_t *nulsch_harq;
nfapi_ul_config_nulsch_pdu_rel13_t *nfapi_parameters_rel13 = &ul_config_pdu->nulsch_pdu.nulsch_pdu_rel13;
switch(ul_config_pdu->pdu_type)
{
case NFAPI_UL_CONFIG_NULSCH_PDU_TYPE:
if(nfapi_parameters_rel13->nulsch_format==0)
{
// new condition should be added to identify if this is msg3 3 since the TBS_table is not the same.
// the type of subcarrier spacing should be specified before the call of rx_ulsch since the parameter does not exist in nfapi parameters.
//TODO should distinguish between data and between data (npusch format)
/*NB: for reception of Msg3 generally not exist a DCI (because scheduling information are implicitly given by the RAR)
* but in case of FAPI specs we should receive an UL_config (containing the NULSCH pdu) for configuring the PHY for Msg3 reception from the MAC
* (this UL_config most probably will be created by the MAC when fill the RAR)
* (most probably we don't have the DL_config (for the RAR transmission) and the UL_CONFIG (for the Msg3 reception) at the same time (same subrame)
* since we are working in HD-FDD mode so for sure the UE will transmit the Msg3 in another subframe so make sense to have a UL_CONFIG in subframe
* diferent from the DL_CONFIG one)
*
*/
///////////////////////////////////////////////////////////////////////////////////////////
//maybe this condition should be replaced by another test ?!
if(nfapi_parameters_rel13->size < 80) // msg3 data
{
nulsch = eNB->ulsch_NB_IoT[0];
nulsch_harq = nulsch->harq_process;
nulsch->Msg3_active = 1;
nulsch->Msg3_flag = 1;
nulsch->flag_vars = 1;
nulsch->rnti = nfapi_parameters_rel13->rnti;
nulsch->npusch_format = nfapi_parameters_rel13->nulsch_format;
nulsch->N_srs = nfapi_parameters_rel13->n_srs;
nulsch->C_init = nfapi_parameters_rel13->scrambling_sequence_initialization_cinit;
nulsch->SF_idx = nfapi_parameters_rel13->sf_idx;
nulsch->HARQ_ACK_resource = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource;
//nulsch_harq->subcarrier_spacing = nfapi_parameters_rel13->handle; // get from the UL_grant of MSG3
nulsch_harq->subcarrier_indication = nfapi_parameters_rel13->subcarrier_indication; // Isc =0->18 , or 0->47 // format 2, 0->3 or 0->7
nulsch_harq->resource_assignment = nfapi_parameters_rel13->resource_assignment; // valid for format 1 // this should be set by DCI N0 // not used for msg3 // I_RU --> helps to get N_RU
nulsch_harq->mcs = nfapi_parameters_rel13->mcs; // I_mcs = 0->10 (single tone) and 0->12 (multi-tone)
nulsch_harq->rvidx = nfapi_parameters_rel13->redudancy_version; // values = 0 or 1
nulsch_harq->repetition_number = nfapi_parameters_rel13->repetition_number; // // N_rep values = 0->7 // new funciton to be created to compute the nb_slots = f(N_rep)
nulsch_harq->new_data_indication = nfapi_parameters_rel13->new_data_indication; // valid only for DCI N0
nulsch_harq->TBS = nfapi_parameters_rel13->size; /// check if needed *8 or /8 or nothing to do
} else{ // other npusch data
nulsch = eNB->ulsch_NB_IoT[0];
nulsch_harq = nulsch->harq_process;
nulsch->Msg3_active = 1;
nulsch->Msg3_flag = 0;
nulsch->flag_vars = 1;
nulsch->rnti = nfapi_parameters_rel13->rnti;
nulsch->npusch_format = nfapi_parameters_rel13->nulsch_format;
nulsch->N_srs = nfapi_parameters_rel13->n_srs;
nulsch->C_init = nfapi_parameters_rel13->scrambling_sequence_initialization_cinit;
nulsch->SF_idx = nfapi_parameters_rel13->sf_idx;
nulsch->HARQ_ACK_resource = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource;
//nulsch_harq->subcarrier_spacing = nfapi_parameters_rel13->handle; // get from the UL_grant of MSG3
nulsch_harq->subcarrier_indication = nfapi_parameters_rel13->subcarrier_indication; // Isc =0->18 , or 0->47 // format 2, 0->3 or 0->7
nulsch_harq->resource_assignment = nfapi_parameters_rel13->resource_assignment; // valid for format 1 // this should be set by DCI N0 // not used for msg3 // I_RU --> helps to get N_RU
nulsch_harq->mcs = nfapi_parameters_rel13->mcs; // I_mcs = 0->10 (single tone) and 0->12 (multi-tone)
nulsch_harq->rvidx = nfapi_parameters_rel13->redudancy_version; // values = 0 or 1
nulsch_harq->repetition_number = nfapi_parameters_rel13->repetition_number; // // N_rep values = 0->7 // new funciton to be created to compute the nb_slots = f(N_rep)
nulsch_harq->new_data_indication = nfapi_parameters_rel13->new_data_indication; // valid only for DCI N0
nulsch_harq->TBS = nfapi_parameters_rel13->size; /// check if needed *8 or /8 or nothing to do
}
//nulsch_harq->rep_tmp = ;
////////////////////////////////////////////////////////////////////////////////////////
LOG_I(PHY,"subframe = %d (TX timing), IF module proceed UL config NULSCH data pdu, will trigger npusch in next subframe\n",subframe);
}else
{
nulsch = eNB->ulsch_NB_IoT[0];
nulsch_harq = nulsch->harq_process;
nulsch->Msg3_active = 1;
nulsch->Msg3_flag = 0;
nulsch->flag_vars = 1;
nulsch->rnti = nfapi_parameters_rel13->rnti;
nulsch->npusch_format = nfapi_parameters_rel13->nulsch_format;
nulsch->N_srs = nfapi_parameters_rel13->n_srs;
nulsch->C_init = nfapi_parameters_rel13->scrambling_sequence_initialization_cinit;
nulsch->SF_idx = nfapi_parameters_rel13->sf_idx;
nulsch->HARQ_ACK_resource = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource;
//nulsch_harq->subcarrier_spacing = nfapi_parameters_rel13->handle; // get from the UL_grant of MSG3
nulsch_harq->subcarrier_indication = nfapi_parameters_rel13->nb_harq_information.nb_harq_information_rel13_fdd.harq_ack_resource; // Isc =0->18 , or 0->47 // format 2, 0->3 or 0->7
nulsch_harq->resource_assignment = nfapi_parameters_rel13->resource_assignment; // valid for format 1 // this should be set by DCI N0 // not used for msg3 // I_RU --> helps to get N_RU
nulsch_harq->mcs = nfapi_parameters_rel13->mcs; // I_mcs = 0->10 (single tone) and 0->12 (multi-tone)
nulsch_harq->rvidx = nfapi_parameters_rel13->redudancy_version; // values = 0 or 1
nulsch_harq->repetition_number = nfapi_parameters_rel13->ue_information.ue_information_rel13.total_number_of_repetitions; // // N_rep values = 0->7 // new funciton to be created to compute the nb_slots = f(N_rep)
nulsch_harq->new_data_indication = nfapi_parameters_rel13->new_data_indication; // valid only for DCI N0
nulsch_harq->TBS = nfapi_parameters_rel13->size; /// check if needed *8 or /8 or nothing to do
LOG_I(PHY,"subframe = %d (TX timing), IF module proceed UL config NULSCH ack pdu, will trigger npusch in next subframe\n",subframe);
}
break;
case NFAPI_UL_CONFIG_NRACH_PDU_TYPE:
//TODO just for update the nprach configuration (given at the beginning through phy_config_sib2)
break;
}
}
//XXX problem: although we may have nothing to transmit this function should be always triggered in order to allow the PHY layer to complete the repetitions
//of previous Transport Blocks
//phy_procedures_eNB_TX_NB_IoT(eNB,proc,NULL);
//phy_procedures_eNB_TX_NB_IoT(eNB,proc,0); // check if 0 or NULL ?!
LOG_D(PHY,"Schedule response has been done\n");
}
void PHY_config_req_NB_IoT(PHY_Config_NB_IoT_t* config_INFO){
LOG_D(PHY,"[NB-IoT] PHY CONFIG REQ NB-IoT In\n");
if(config_INFO->get_MIB != 0){
//MIB-NB configuration
phy_config_mib_eNB_NB_IoT(config_INFO->mod_id,
config_INFO->cfg->nfapi_config.rf_bands.rf_band[0],//eutraband
config_INFO->cfg->sch_config.physical_cell_id.value,
config_INFO->cfg->subframe_config.dl_cyclic_prefix_type.value,
config_INFO->cfg->subframe_config.ul_cyclic_prefix_type.value,
config_INFO->cfg->rf_config.tx_antenna_ports.value,
config_INFO->cfg->nfapi_config.earfcn.value,
config_INFO->cfg->nb_iot_config.prb_index.value,
config_INFO->cfg->nb_iot_config.operating_mode.value,
config_INFO->cfg->nb_iot_config.control_region_size.value,
config_INFO->cfg->nb_iot_config.assumed_crs_aps.value); //defined only in in-band different PCI
}
if(config_INFO->get_COMMON != 0)
{
//Common Configuration included in SIB2-NB
phy_config_sib2_eNB_NB_IoT(config_INFO->mod_id,
&config_INFO->cfg->nb_iot_config, // FIXME to be evaluated is should be passed a pointer
&config_INFO->cfg->rf_config,
&config_INFO->cfg->uplink_reference_signal_config,
&config_INFO->extra_phy_parms);
}
///FOR FAPI is not specified
if(config_INFO->get_DEDICATED!= 0)
{
//Dedicated Configuration
/*phy_config_dedicated_eNB_NB_IoT(config_INFO->mod_id,
config_INFO->CC_id,
config_INFO->rnti,
&config_INFO->extra_phy_parms);*/
}
LOG_D(PHY,"IF Module for PHY Configuration has been done\n");
}

View File

@@ -0,0 +1,20 @@
#ifndef __IF_MODULE_L1_PRIMITIVES_NB_IOT_H__
#define __IF_MODULE_L1_PRIMITIVES_NB_IOT_H__
#include "openair1/PHY/defs_L1_NB_IoT.h"
//#include "LAYER2/MAC/extern.h"
//#include "LAYER2/MAC/proto_NB_IoT.h"
//#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
void handle_nfapi_dlsch_pdu_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,
eNB_rxtx_proc_NB_IoT_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t *sdu);
#endif

View File

@@ -0,0 +1,62 @@
#ifndef __openair_SCHED_NB_IOT_H__
#define __openair_SCHED_NB_IOT_H__
#include "PHY/defs_eNB.h"
#include "PHY/defs_UE.h"
#include "PHY/defs_L1_NB_IoT.h"
//#include "openair2/PHY_INTERFACE/IF_Module_nb_iot.h"
#include "nfapi_interface.h"
extern uint16_t hundred_times_log10_NPRB_NB_IoT[100];
enum openair_HARQ_TYPE_NB_IoT {
openair_harq_DL_NB_IoT = 0,
openair_harq_UL_NB_IoT,
openair_harq_RA_NB_IoT
};
void process_schedule_rsp_NB_IoT(Sched_Rsp_NB_IoT_t *sched_rsp,
PHY_VARS_eNB_NB_IoT *eNB,
eNB_rxtx_proc_NB_IoT_t *proc);
/* For NB-IoT, we put NPBCH in later part, since it would be scheduled by MAC scheduler,this generates NRS/NPSS/NSSS*/
void common_signal_procedures_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_NB_IoT_t *proc);
/*Generate the ulsch params and do the mapping for the FAPI style parameters to OAI, and then do the packing*/
void generate_eNB_ulsch_params_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_NB_IoT_t *proc,nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu);
/*Generate the dlsch params and do the mapping for the FAPI style parameters to OAI, and then do the packing*/
void generate_eNB_dlsch_params_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_NB_IoT_t * proc,nfapi_dl_config_request_pdu_t *dl_config_pdu);
/*Process all the scheduling result from MAC and also common signals.*/
void phy_procedures_eNB_TX_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_NB_IoT_t *proc,int do_meas);
int8_t find_ue_NB_IoT(uint16_t rnti, PHY_VARS_eNB_NB_IoT *eNB);
NB_IoT_DL_FRAME_PARMS *get_NB_IoT_frame_parms(module_id_t Mod_id, uint8_t CC_id);
int16_t get_hundred_times_delta_IF_eNB_NB_IoT(PHY_VARS_eNB_NB_IoT *phy_vars_eNB,uint8_t UE_id,uint8_t harq_pid, uint8_t bw_factor);
uint32_t is_SIB1_NB_IoT(const frame_t frameP,
long schedulingInfoSIB1, //from the mib
int physCellId, //by configuration
NB_IoT_eNB_NDLSCH_t *ndlsch_SIB1
);
uint32_t rx_nprach_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,int frame, uint8_t subframe, uint16_t *rnti, uint16_t *preamble_index, uint16_t *timing_advance);
void npusch_procedures(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_NB_IoT_t *proc);
////////////////// NB-IoT testing ////////////////////
void fill_rx_indication_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,eNB_rxtx_proc_NB_IoT_t *proc,uint8_t data_or_control, uint8_t decode_flag);
void fill_crc_indication_NB_IoT(PHY_VARS_eNB_NB_IoT *eNB,int UE_id,int frame,int subframe,uint8_t decode_flag);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*!\brief SCHED external variables */
#ifndef __SCHED_EXTERN_NB_IOT_H__
#define __SCHED_EXTERN_NB_IOT_H__
#include "defs_NB_IoT.h"
extern uint16_t hundred_times_log10_NPRB_NB_IoT[100];
#endif /*__SCHED_EXTERN_H__ */

View File

@@ -32,7 +32,7 @@
# define __BYPASS_SESSION_LAYER_EXTERN_H__
#include <pthread.h>
#include "defs.h"
extern unsigned char Emulation_status;
extern unsigned char emu_tx_status;
extern unsigned char emu_rx_status;

View File

@@ -30,6 +30,8 @@
#include "COMMON/platform_types.h"
#include "COMMON/platform_constants.h"
#include "openair2/RRC/LTE/rrc_defs.h"
#include "LTE_RadioResourceConfigCommonSIB.h"
#include "LTE_RadioResourceConfigDedicated.h"
#include "LTE_MeasGapConfig.h"

View File

@@ -0,0 +1,322 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*
platform_types_NB_IoT.h
-------------------
AUTHOR : Lionel GAUTHIER
COMPANY : EURECOM
EMAIL : Lionel.Gauthier@eurecom.fr
***************************************************************************/
#ifndef __PLATFORM_TYPES_NB_IoT_H__
# define __PLATFORM_TYPES_NB_IoT_H__
#ifdef USER_MODE
#include <stdint.h>
#endif
/*
#if defined(ENABLE_ITTI)
#include "itti_types.h"
#endif
*/
//-----------------------------------------------------------------------------
// GENERIC TYPES
//-----------------------------------------------------------------------------
typedef uint16_t rnti_NB_IoT_t;
/* boolean_t is also defined in openair2/COMMON/commonDef.h,
* let's protect potential redefinition
*/
#ifndef _BOOLEAN_T_DEFINED_NB_IoT_
#define _BOOLEAN_T_DEFINED_NB_IoT_
typedef signed char boolean_t;
#if !defined(TRUE)
#define TRUE (boolean_t)0x01
#endif
#if !defined(FALSE)
#define FALSE (boolean_t)0x00
#endif
#define BOOL_NOT(b) (b^TRUE)
#endif
///NB-IoT
typedef boolean_t srb1bis_flag_t;
#define SRB1BIS_FLAG_NO FALSE
#define SRB1BIS_FLAG_YES TRUE
typedef boolean_t mib_flag_t;
#define MIB_FLAG_YES TRUE
#define MIB_FLAG_NO FALSE
/* _BOOLEAN_T_DEFINED_ */
/*
//-----------------------------------------------------------------------------
// GENERIC ACCESS STRATUM TYPES
//-----------------------------------------------------------------------------
typedef int32_t sdu_size_t;
typedef uint32_t frame_t;
typedef int32_t sframe_t;
typedef uint32_t sub_frame_t;
typedef uint8_t module_id_t;
typedef uint8_t eNB_index_t;
typedef uint16_t ue_id_t;
typedef int16_t smodule_id_t;
typedef uint16_t rb_id_t;
typedef uint16_t srb_id_t;
typedef boolean_t MBMS_flag_t;
#define MBMS_FLAG_NO FALSE
#define MBMS_FLAG_YES TRUE
typedef boolean_t eNB_flag_t;
#define ENB_FLAG_NO FALSE
#define ENB_FLAG_YES TRUE
typedef boolean_t srb_flag_t;
#define SRB_FLAG_NO FALSE
#define SRB_FLAG_YES TRUE
///NB-IoT
typedef boolean_t srb1bis_flag_t;
#define SRB1BIS_FLAG_NO FALSE
#define SRB1BIS_FLAG_YES TRUE
typedef boolean_t mib_flag_t;
#define MIB_FLAG_YES TRUE
#define MIB_FLAG_NO FALSE
typedef enum link_direction_e {
UNKNOWN_DIR = 0,
DIR_UPLINK = 1,
DIR_DOWNLINK = 2
} link_direction_t;
typedef enum rb_type_e {
UNKNOWN_RADIO_BEARER = 0,
SIGNALLING_RADIO_BEARER = 1,
RADIO_ACCESS_BEARER = 2
} rb_type_t;
//-----------------------------------------------------------------------------
// PHY TYPES
//-----------------------------------------------------------------------------
typedef uint8_t crc8_t;
typedef uint16_t crc16_t;
typedef uint32_t crc32_t;
typedef unsigned int crc_t;
//-----------------------------------------------------------------------------
// MAC TYPES
//-----------------------------------------------------------------------------
typedef sdu_size_t tbs_size_t;
typedef sdu_size_t tb_size_t;
typedef unsigned int logical_chan_id_t;
typedef unsigned int num_tb_t;
typedef uint8_t mac_enb_index_t;
//-----------------------------------------------------------------------------
// RLC TYPES
//-----------------------------------------------------------------------------
typedef unsigned int mui_t;
typedef unsigned int confirm_t;
typedef unsigned int rlc_tx_status_t;
typedef int16_t rlc_sn_t;
typedef uint16_t rlc_usn_t;
typedef int32_t rlc_buffer_occupancy_t;
typedef signed int rlc_op_status_t;
#define SDU_CONFIRM_NO FALSE
#define SDU_CONFIRM_YES TRUE
//-----------------------------------------------------------------------------
// PDCP TYPES
//-----------------------------------------------------------------------------
typedef uint16_t pdcp_sn_t;
typedef uint32_t pdcp_hfn_t;
typedef int16_t pdcp_hfn_offset_t;
typedef enum pdcp_transmission_mode_e {
PDCP_TRANSMISSION_MODE_UNKNOWN = 0,
PDCP_TRANSMISSION_MODE_CONTROL = 1,
PDCP_TRANSMISSION_MODE_DATA = 2,
PDCP_TRANSMISSION_MODE_TRANSPARENT = 3
} pdcp_transmission_mode_t;
//-----------------------------------------------------------------------------
// IP DRIVER / PDCP TYPES
//-----------------------------------------------------------------------------
typedef uint16_t tcp_udp_port_t;
typedef enum ip_traffic_type_e {
TRAFFIC_IPVX_TYPE_UNKNOWN = 0,
TRAFFIC_IPV6_TYPE_UNICAST = 1,
TRAFFIC_IPV6_TYPE_MULTICAST = 2,
TRAFFIC_IPV6_TYPE_UNKNOWN = 3,
TRAFFIC_IPV4_TYPE_UNICAST = 5,
TRAFFIC_IPV4_TYPE_MULTICAST = 6,
TRAFFIC_IPV4_TYPE_BROADCAST = 7,
TRAFFIC_IPV4_TYPE_UNKNOWN = 8
} ip_traffic_type_t;
*/
//-----------------------------------------------------------------------------
// RRC TYPES
//-----------------------------------------------------------------------------
//typedef uint32_t mbms_session_id_t;
//typedef uint16_t mbms_service_id_t;
//typedef uint8_t rrc_enb_index_t;
//typedef uint8_t mme_code_t;
//typedef uint32_t m_tmsi_t;
/*
//Random UE identity length = 40 bits
#if ! defined(NOT_A_RANDOM_UE_IDENTITY)
#define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF
#endif
#if ! defined(NOT_A_RNTI)
#define NOT_A_RNTI (rnti_t)0
#endif
#if ! defined(M_RNTI)
#define M_RNTI (rnti_t)0xFFFD
#endif
#if ! defined(P_RNTI)
#define P_RNTI (rnti_t)0xFFFE
#endif
#if ! defined(SI_RNTI)
#define SI_RNTI (rnti_t)0xFFFF
#endif
typedef enum config_action_e {
CONFIG_ACTION_NULL = 0,
CONFIG_ACTION_ADD = 1,
CONFIG_ACTION_REMOVE = 2,
CONFIG_ACTION_MODIFY = 3,
CONFIG_ACTION_SET_SECURITY_MODE = 4,
CONFIG_ACTION_MBMS_ADD = 10,
CONFIG_ACTION_MBMS_MODIFY = 11
} config_action_t;
//-----------------------------------------------------------------------------
// GTPV1U TYPES
//-----------------------------------------------------------------------------
typedef uint32_t teid_t; // tunnel endpoint identifier
typedef uint8_t ebi_t; // eps bearer id
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// may be ITTI not enabled, but type instance is useful also for OTG,
#if !defined(instance_t)
typedef uint16_t instance_t;
#endif
typedef struct protocol_ctxt_s {
module_id_t module_id; /!< \brief Virtualized module identifier /
eNB_flag_t enb_flag; /!< \brief Flag to indicate eNB (1) or UE (0) /
instance_t instance; /!< \brief ITTI or OTG module identifier /
rnti_t rnti;
frame_t frame; /!< \brief LTE frame number./
sub_frame_t subframe; /!< \brief LTE sub frame number./
eNB_index_t eNB_index; /!< \brief valid for UE indicating the index of connected eNB(s) /
boolean_t configured; /!< \brief flag indicating whether the instance is configured or not /
} protocol_ctxt_t;
// warning time hardcoded
#define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame*10+(CtXt_h)->subframe)
#define UE_MODULE_ID_TO_INSTANCE( mODULE_iD ) mODULE_iD + NB_eNB_INST
#define ENB_MODULE_ID_TO_INSTANCE( mODULE_iD ) mODULE_iD
#define UE_INSTANCE_TO_MODULE_ID( iNSTANCE ) iNSTANCE - NB_eNB_INST
#define ENB_INSTANCE_TO_MODULE_ID( iNSTANCE )iNSTANCE
#define MODULE_ID_TO_INSTANCE(mODULE_iD, iNSTANCE, eNB_fLAG) \
if(eNB_fLAG == ENB_FLAG_YES) \
iNSTANCE = ENB_MODULE_ID_TO_INSTANCE(mODULE_iD); \
else \
iNSTANCE = UE_MODULE_ID_TO_INSTANCE(mODULE_iD)
#define INSTANCE_TO_MODULE_ID(iNSTANCE, mODULE_iD, eNB_fLAG) \
if(eNB_fLAG == ENB_FLAG_YES) \
mODULE_iD = ENB_INSTANCE_TO_MODULE_ID(iNSTANCE); \
else \
mODULE_iD = UE_INSTANCE_TO_MODULE_ID(iNSTANCE)
#define PROTOCOL_CTXT_COMPUTE_MODULE_ID(CtXt_h) \
INSTANCE_TO_MODULE_ID( (CtXt_h)->instance , (CtXt_h)->module_id , (CtXt_h)->enb_flag )
#define PROTOCOL_CTXT_COMPUTE_INSTANCE(CtXt_h) \
MODULE_ID_TO_INSTANCE( (CtXt_h)->module_id , (CtXt_h)->instance , (CtXt_h)->enb_flag )
#define PROTOCOL_CTXT_SET_BY_MODULE_ID(Ctxt_Pp, mODULE_iD, eNB_fLAG, rNTI, fRAME, sUBfRAME, eNB_iNDEX) \
(Ctxt_Pp)->module_id = mODULE_iD; \
(Ctxt_Pp)->enb_flag = eNB_fLAG; \
(Ctxt_Pp)->rnti = rNTI; \
(Ctxt_Pp)->frame = fRAME; \
(Ctxt_Pp)->subframe = sUBfRAME; \
(Ctxt_Pp)->eNB_index = eNB_iNDEX; \
PROTOCOL_CTXT_COMPUTE_INSTANCE(Ctxt_Pp)
#define PROTOCOL_CTXT_SET_BY_INSTANCE(Ctxt_Pp, iNSTANCE, eNB_fLAG, rNTI, fRAME, sUBfRAME) \
(Ctxt_Pp)->instance = iNSTANCE; \
(Ctxt_Pp)->enb_flag = eNB_fLAG; \
(Ctxt_Pp)->rnti = rNTI; \
(Ctxt_Pp)->frame = fRAME; \
(Ctxt_Pp)->subframe = sUBfRAME; \
PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp)
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02u][RNTI %" PRIx16 "]"
#define PROTOCOL_CTXT_ARGS(CTXT_Pp) \
(CTXT_Pp)->frame, \
((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB":" UE", \
(CTXT_Pp)->module_id, \
(CTXT_Pp)->rnti
#ifdef OAI_EMU
#define CHECK_CTXT_ARGS(CTXT_Pp) \
if ((CTXT_Pp)->enb_flag) {\
AssertFatal (((CTXT_Pp)->module_id >= oai_emulation.info.first_enb_local) && (oai_emulation.info.nb_enb_local > 0),\
"eNB module id is too low (%u/%d/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_enb_local,\
oai_emulation.info.nb_enb_local);\
AssertFatal (((CTXT_Pp)->module_id < (oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local)) && (oai_emulation.info.nb_enb_local > 0),\
"eNB module id is too high (%u/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_enb_local + oai_emulation.info.nb_enb_local);\
} else {\
AssertFatal ((CTXT_Pp)->module_id < (oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local),\
"UE module id is too high (%u/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_ue_local + oai_emulation.info.nb_ue_local);\
AssertFatal ((CTXT_Pp)->module_id >= oai_emulation.info.first_ue_local,\
"UE module id is too low (%u/%d)!\n",\
(CTXT_Pp)->module_id,\
oai_emulation.info.first_ue_local);\
}
#else
#define CHECK_CTXT_ARGS(CTXT_Pp)
#endif
*/
#endif

View File

@@ -30,13 +30,13 @@
#include <string.h>
#include <inttypes.h>
#include "log.h"
#include "log_extern.h"
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/log_extern.h"
#include "assertions.h"
#include "intertask_interface.h"
#include "s1ap_eNB.h"
#include "sctp_eNB_task.h"
#include "SystemInformationBlockType2.h"
//#include "SystemInformationBlockType2.h"
#include "PHY/phy_extern.h"
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
@@ -47,6 +47,7 @@
#include "L1_paramdef.h"
#include "MACRLC_paramdef.h"
#include "LAYER2/MAC/proto_NB_IoT.h"
#include "PHY/INIT/defs_NB_IoT.h"
void RCconfig_NbIoTL1(void) {
@@ -90,7 +91,7 @@ void RCconfig_NbIoTL1(void) {
LOG_I(PHY,"No " NBIOT_L1LIST_CONFIG_STRING " configuration found");
}
}
#if 0 //Ann
void RCconfig_NbIoTmacrlc(void) {
paramdef_t NbIoT_MacRLC_Params[] = MACRLCPARAMS_DESC;
paramlist_def_t NbIoT_MacRLC_ParamList = {NBIOT_MACRLCLIST_CONFIG_STRING,NULL,0};
@@ -250,3 +251,4 @@ void RCConfig_NbIoT(RAN_CONTEXT_t *RC) {
config_getlist( &NbIoT_L1ParamList,NULL,0, NULL);
RC->nb_nb_iot_L1_inst = NbIoT_L1ParamList.numelt;
}
#endif //Ann

View File

@@ -31,14 +31,15 @@
*/
#include "common/config/config_paramdesc.h"
#include "SystemInformationBlockType2.h"
#include "DL-GapConfig-NB-r13.h"
#include "NPRACH-Parameters-NB-r13.h"
#include "PowerRampingParameters.h"
#include "BCCH-Config-NB-r13.h"
#include "PCCH-Config-NB-r13.h"
#include "ACK-NACK-NumRepetitions-NB-r13.h"
#include "TDD-Config.h"
#if 0 //Ann
#include "LTE_SystemInformationBlockType2.h"
#include "LTE_DL-GapConfig-NB-r13.h"
#include "LTE_NPRACH-Parameters-NB-r13.h"
#include "LTE_PowerRampingParameters.h"
#include "LTE_BCCH-Config-NB-r13.h"
#include "LTE_PCCH-Config-NB-r13.h"
#include "LTE_ACK-NACK-NumRepetitions-NB-r13.h"
#include "LTE_TDD-Config.h"
@@ -393,8 +394,7 @@
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* NB IoT MACRLC configuration list section name */
#define NBIOT_MACRLCLIST_CONFIG_STRING "NB-IoT_MACRLCs"
#endif //Ann
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* NB IoT L1 configuration list section name */
#define NBIOT_L1LIST_CONFIG_STRING "NB-IoT_L1s"

View File

@@ -48,13 +48,14 @@
#include "targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.h"
#include "nfapi_vnf.h"
#include "nfapi_pnf.h"
#include "../../openair1/PHY/defs_L1_NB_IoT.h"
#include "L1_paramdef.h"
#include "MACRLC_paramdef.h"
#include "common/config/config_userapi.h"
#include "RRC_config_tools.h"
#include "enb_paramdef.h"
#include "proto_agent.h"
#include "NB_IoT_config.h"
extern uint16_t sf_ahead;
extern void set_parallel_conf(char *parallel_conf);
@@ -120,6 +121,7 @@ void RCconfig_L1(void) {
config_getlist( &L1_ParamList,L1_Params,sizeof(L1_Params)/sizeof(paramdef_t), NULL);
if (L1_ParamList.numelt > 0) {
for (j = 0; j < RC.nb_L1_inst; j++) {
RC.nb_L1_CC[j] = *(L1_ParamList.paramarray[j][L1_CC_IDX].uptr);
@@ -2940,6 +2942,7 @@ void read_config_and_init(void) {
RC.nb_macrlc_inst, RC.nb_inst);
RCconfig_L1();
RCconfig_NbIoTL1();
LOG_I(PHY, "%s() RC.nb_L1_inst: %d\n", __FUNCTION__, RC.nb_L1_inst);
RCconfig_macrlc(macrlc_has_f1);
LOG_I(MAC, "%s() RC.nb_macrlc_inst: %d\n", __FUNCTION__, RC.nb_macrlc_inst);

View File

@@ -0,0 +1,488 @@
/*! \file config_NB_IoT.c
* \brief configuration primitives between RRC and MAC
* \author NTUST BMW Lab./
* \date 2019
* \email:
* \version 2.0
*
*/
#include "LAYER2/MAC/defs_NB_IoT.h"
#include "LAYER2/MAC/proto_NB_IoT.h"
#include "LAYER2/MAC/extern_NB_IoT.h"
#include "LTE_BCCH-DL-SCH-Message-NB.h"
#include "LTE_RRCConnectionSetup-NB.h"
#include "LTE_BCCH-BCH-Message-NB.h"
//#include "SIB-Type-NB-r13.h"
typedef struct eutra_bandentry_NB_s {
//this should be the colum order of the table below (eutra_bandtable)
int16_t band;
uint32_t ul_min;
uint32_t ul_max;
uint32_t dl_min;
uint32_t dl_max;
uint32_t N_OFFs_DL;
} eutra_bandentry_NB_IoT_t;
typedef struct band_info_s {
int nbands;
eutra_bandentry_NB_IoT_t band_info[100];
} band_info_t;
//[BAND] [FUL_low] [FUL_hi] [FDL_low] [FDL_hig] [NOFF_DL]
static const eutra_bandentry_NB_IoT_t eutra_bandtable[] = {
{ 1, 19200, 19800, 21100, 21700, 0},
{ 2, 18500, 19100, 19300, 19900, 6000},
{ 3, 17100, 17850, 18050, 18800, 12000},
{ 5, 8240, 8490, 8690, 8940, 24000},
{ 8, 8800, 9150, 9250, 9600, 34500},
{11, 14279, 14529, 14759, 15009, 47500},
{12, 6980, 7160, 7280, 7460, 50100},
{13, 7770, 7870, 7460, 7560, 51800},
{17, 7040, 7160, 7340, 7460, 57300},
{18, 8150, 9650, 8600, 10100, 58500},
{19, 8300, 8450, 8750, 8900, 60000},
{20, 8320, 8620, 7910, 8210, 61500},
{25, 18500, 19150, 19300, 19950, 80400},
{26, 8140, 8490, 8590, 8940, 86900},
{28, 7030, 7580, 7580, 8130, 92100},
{31, 45250, 34900, 46250, 35900, 98700},
{66, 17100, 18000, 21100, 22000, 664360},
{70, 16950 , 17100, 19950, 20200, 683360}}; //may not used for Rel.13 equipment
//used for getting the DL Carrier Frequency from the EARFCN
uint32_t from_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_earfcn, float m_dl) {
int i;
// float m_dl = 0; //for the moment we fix but maybe should be dynamic (anyway the 0 works for any case)
AssertFatal(eutra_bandP <= 70,"eutra_band %d > 70\n",eutra_bandP);
for (i=0;i<= 70 && eutra_bandtable[i].band!=eutra_bandP;i++);
// this function is given by TS 36.104 Release 13.2 CH 5.7.3
return(eutra_bandtable[i].dl_min + 0.0025*(2*m_dl+1)+(dl_earfcn-(eutra_bandtable[i].N_OFFs_DL/10)))*100000;
}
int32_t get_uldl_offset_NB_IoT(int eutra_band) {
return(-eutra_bandtable[eutra_band].dl_min + eutra_bandtable[eutra_band].ul_min);
}
uint32_t to_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_CarrierFreq, float m_dl) {
uint32_t dl_CarrierFreq_by_100k = dl_CarrierFreq/100000;
int i;
AssertFatal(eutra_bandP < 70,"eutra_band %d > 70\n",eutra_bandP);
for (i=0;i<69 && eutra_bandtable[i].band!=eutra_bandP;i++);
AssertFatal(dl_CarrierFreq_by_100k>=eutra_bandtable[i].dl_min,
"Band %d : DL carrier frequency %u Hz < %u\n",
eutra_bandP,dl_CarrierFreq,eutra_bandtable[i].dl_min);
//based on formula TS 36.101 5.7.3F
return(dl_CarrierFreq_by_100k - eutra_bandtable[i].dl_min - 0.0025*(2*m_dl+ 1)+ (eutra_bandtable[i].N_OFFs_DL/10));
}
void config_mib_fapi_NB_IoT(int physCellId,
uint8_t eutra_band,
int Ncp,
int Ncp_UL,
int p_eNB,
int p_rx_eNB,
int dl_CarrierFreq,
int ul_CarrierFreq,
long *eutraControlRegionSize,
LTE_BCCH_BCH_Message_NB_t *mib_NB_IoT
)
{
nfapi_config_request_t *cfg = &mac_inst->config;
cfg->sch_config.physical_cell_id.value = physCellId;
cfg->nfapi_config.rf_bands.rf_band[0] = eutra_band;
cfg->subframe_config.dl_cyclic_prefix_type.value = Ncp;
cfg->subframe_config.ul_cyclic_prefix_type.value = Ncp_UL;
cfg->rf_config.tx_antenna_ports.value = p_eNB;
cfg->nfapi_config.earfcn.value = 9370; // value from taiwan commercial base station, just setting for now, will use formula to calculate it layer
//cfg->nb_iot_config.prb_index.value = // need to set in thread part
switch (mib_NB_IoT->message.operationModeInfo_r13.present)
{
//FAPI specs pag 135
case LTE_MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_SamePCI_r13:
cfg->nb_iot_config.operating_mode.value = 0;
cfg->nb_iot_config.prb_index.value = mib_NB_IoT->message.operationModeInfo_r13.choice.inband_SamePCI_r13.eutra_CRS_SequenceInfo_r13; //see TS 36.213 ch 16.0
cfg->nb_iot_config.assumed_crs_aps.value = -1; //is not defined so we put a negative value
if(eutraControlRegionSize == NULL)
LOG_E(RRC, "rrc_mac_config_req_eNB_NB_IoT: operation mode is in-band but eutraControlRegionSize is not defined\n");
else
cfg->nb_iot_config.control_region_size.value = *eutraControlRegionSize;
break;
case LTE_MasterInformationBlock_NB__operationModeInfo_r13_PR_inband_DifferentPCI_r13:
cfg->nb_iot_config.operating_mode.value = 1;
//fapi think to define also eutra_CRS_sequenceInfo also for in band with different PCI but the problem is that we don-t have i
cfg->nb_iot_config.assumed_crs_aps.value = mib_NB_IoT->message.operationModeInfo_r13.choice.inband_DifferentPCI_r13.eutra_NumCRS_Ports_r13;
if(eutraControlRegionSize == NULL)
LOG_E(RRC, "rrc_mac_config_req_eNB_NB_IoT: operation mode is in-band but eutraControlRegionSize is not defined\n");
else
cfg->nb_iot_config.control_region_size.value = *eutraControlRegionSize;
break;
case LTE_MasterInformationBlock_NB__operationModeInfo_r13_PR_guardband_r13:
cfg->nb_iot_config.operating_mode.value = 2;
cfg->nb_iot_config.control_region_size.value = -1; //should not being defined so we put a negative value
cfg->nb_iot_config.assumed_crs_aps.value = -1; //is not defined so we put a negative value
break;
case LTE_MasterInformationBlock_NB__operationModeInfo_r13_PR_standalone_r13:
cfg->nb_iot_config.operating_mode.value = 3;
cfg->nb_iot_config.prb_index.value = -1; // is not defined for this case (put a negative random value--> will be not considered for encoding, scrambling procedures)
cfg->nb_iot_config.control_region_size.value = -1; //is not defined so we put a negative value
cfg->nb_iot_config.assumed_crs_aps.value = -1; //is not defined so we put a negative value
break;
default:
LOG_E(RRC, "rrc_mac_config_req_eNB_NB_IoT: NB-IoT operating Mode (MIB-NB) not set\n");
break;
}
}
void config_sib2_fapi_NB_IoT(
int physCellId,
LTE_RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon
)
{
nfapi_config_request_t *cfg = &mac_inst->config;
/*
* Following the FAPI like approach:
* 1) fill the PHY_Config_t structure (PHY_INTERFACE/IF_Module_NB_IoT.h)
* 1.1) check for how many NPRACH resources has been set and enable the corresponding parameter
* 1.2) fill the structure PHY_Config_t (shared structure of the IF_Module
* 2) Call the PHY_config_req for trigger the NB_phy_config_sib2_eNB()
*/
/*NPRACH section*/
LTE_NPRACH_Parameters_NB_r13_t* nprach_parameter;
cfg->nb_iot_config.nprach_config_0_enabled.value = 0;
cfg->nb_iot_config.nprach_config_1_enabled.value = 0;
cfg->nb_iot_config.nprach_config_2_enabled.value = 0;
if(radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[0]!=NULL&&radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[1]!=NULL&&radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[2]!=NULL)
{
nprach_parameter = radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[0];
cfg->nb_iot_config.nprach_config_0_enabled.value = 1;
cfg->nb_iot_config.nprach_config_0_cp_length.value = radioResourceConfigCommon->nprach_Config_r13.nprach_CP_Length_r13;
cfg->nb_iot_config.nprach_config_0_sf_periodicity.value = nprach_parameter->nprach_Periodicity_r13;
cfg->nb_iot_config.nprach_config_0_start_time.value = nprach_parameter->nprach_StartTime_r13;
cfg->nb_iot_config.nprach_config_0_subcarrier_offset.value = nprach_parameter->nprach_SubcarrierOffset_r13;
cfg->nb_iot_config.nprach_config_0_number_of_subcarriers.value = nprach_parameter->nprach_NumSubcarriers_r13;
cfg->nb_iot_config.nprach_config_0_number_of_repetitions_per_attempt.value = nprach_parameter->numRepetitionsPerPreambleAttempt_r13;
//rsrp_ThresholdsPrachInfoList_r13 -> optional
nprach_parameter = radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[1];
cfg->nb_iot_config.nprach_config_1_enabled.value = 1;
cfg->nb_iot_config.nprach_config_1_cp_length.value = radioResourceConfigCommon->nprach_Config_r13.nprach_CP_Length_r13;
cfg->nb_iot_config.nprach_config_1_sf_periodicity.value = nprach_parameter->nprach_Periodicity_r13;
cfg->nb_iot_config.nprach_config_1_start_time.value = nprach_parameter->nprach_StartTime_r13;
cfg->nb_iot_config.nprach_config_1_subcarrier_offset.value = nprach_parameter->nprach_SubcarrierOffset_r13;
cfg->nb_iot_config.nprach_config_1_number_of_subcarriers.value = nprach_parameter->nprach_NumSubcarriers_r13;
cfg->nb_iot_config.nprach_config_1_number_of_repetitions_per_attempt.value = nprach_parameter->numRepetitionsPerPreambleAttempt_r13;
//rsrp_ThresholdsPrachInfoList_r13 -> optional
nprach_parameter = radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[2];
cfg->nb_iot_config.nprach_config_2_enabled.value = 1;
cfg->nb_iot_config.nprach_config_2_cp_length.value = radioResourceConfigCommon->nprach_Config_r13.nprach_CP_Length_r13;
cfg->nb_iot_config.nprach_config_2_sf_periodicity.value = nprach_parameter->nprach_Periodicity_r13;
cfg->nb_iot_config.nprach_config_2_start_time.value = nprach_parameter->nprach_StartTime_r13;
cfg->nb_iot_config.nprach_config_2_subcarrier_offset.value = nprach_parameter->nprach_SubcarrierOffset_r13;
cfg->nb_iot_config.nprach_config_2_number_of_subcarriers.value = nprach_parameter->nprach_NumSubcarriers_r13;
cfg->nb_iot_config.nprach_config_2_number_of_repetitions_per_attempt.value = nprach_parameter->numRepetitionsPerPreambleAttempt_r13;
//rsrp_ThresholdsPrachInfoList_r13 -> optional
}else
{
LOG_E(MAC,"NPRACH Configuration isn't set properly\n");
}
LOG_I(MAC,"Fill parameters of FAPI NPRACH done\n");
/*NPDSCH ConfigCommon*/
//FAPI specs define a range of value [0-255]==[0db - 63.75db] with 0.25db step -- corrispondence in Ts 36.213 CH 16.2.2
cfg->rf_config.reference_signal_power.value = radioResourceConfigCommon->npdsch_ConfigCommon_r13.nrs_Power_r13;
/*NPUSCH ConfigCommon*/
if(radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13 != NULL)/* OPTIONAL */
{
/* OPTIONAL */
if(radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->threeTone_BaseSequence_r13!= NULL)
cfg->nb_iot_config.three_tone_base_sequence.value = *(radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->threeTone_BaseSequence_r13);
else
cfg->nb_iot_config.three_tone_base_sequence.value = physCellId%12; //see spec TS 36.331 NPUSCH-Config-NB
/* OPTIONAL */
if(radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->sixTone_BaseSequence_r13!= NULL)
cfg->nb_iot_config.six_tone_base_sequence.value = *(radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->sixTone_BaseSequence_r13);
else
cfg->nb_iot_config.six_tone_base_sequence.value = physCellId%14; //see spec TS 36.331 NPUSCH-Config-NB
/* OPTIONAL */
if(radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->twelveTone_BaseSequence_r13!= NULL)
cfg->nb_iot_config.twelve_tone_base_sequence.value = *(radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->twelveTone_BaseSequence_r13);
else
cfg->nb_iot_config.twelve_tone_base_sequence.value = physCellId%30; //see spec TS 36.331 NPUSCH-Config-NB
cfg->nb_iot_config.three_tone_cyclic_shift.value = radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->threeTone_CyclicShift_r13;
cfg->nb_iot_config.six_tone_cyclic_shift.value = radioResourceConfigCommon->npusch_ConfigCommon_r13.dmrs_Config_r13->sixTone_CyclicShift_r13;
}
//NOTE: MP: FAPI specs for UL RS Configurations seems to be targeted for LTE and not for NB-IoT
if(radioResourceConfigCommon->npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupHoppingEnabled_r13 == TRUE)
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 1; //RS_GROUP_HOPPING (FAPI specs pag 127)
else
cfg->uplink_reference_signal_config.uplink_rs_hopping.value = 0;//RS_NO_HOPPING
cfg->uplink_reference_signal_config.group_assignment.value = radioResourceConfigCommon->npusch_ConfigCommon_r13.ul_ReferenceSignalsNPUSCH_r13.groupAssignmentNPUSCH_r13;
//srs_SubframeConfig_r13 /* OPTIONAL */
/*DL GAP config */
if(radioResourceConfigCommon->dl_Gap_r13 !=NULL)/* OPTIONAL */
{
cfg->nb_iot_config.dl_gap_config_enable.value = 1;
cfg->nb_iot_config.dl_gap_threshold.value = radioResourceConfigCommon->dl_Gap_r13->dl_GapThreshold_r13;
cfg->nb_iot_config.dl_gap_duration_coefficient.value = radioResourceConfigCommon->dl_Gap_r13->dl_GapDurationCoeff_r13;
cfg->nb_iot_config.dl_gap_periodicity.value = radioResourceConfigCommon->dl_Gap_r13->dl_GapPeriodicity_r13;
}
else
cfg->nb_iot_config.dl_gap_config_enable.value = 0;
/*UL Power Control ConfigCommon*/
//nothing defined in FAPI specs
/*RACH Config Common*/
//nothing defined in FAPI specs
}
// Called by init_testing_NB_IoT, configure and initiate NB-IoT MAC and PHY here
void rrc_mac_config_req_NB_IoT(
module_id_t Mod_idP,
int CC_idP,
int rntiP,
rrc_eNB_carrier_data_NB_IoT_t *carrier,
LTE_SystemInformationBlockType1_NB_t *sib1_NB_IoT,
LTE_RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon,
LTE_PhysicalConfigDedicated_NB_r13_t *physicalConfigDedicated,
LTE_LogicalChannelConfig_NB_r13_t *logicalChannelConfig,
uint8_t ded_flag,
uint8_t ue_list_ded_num)
{
int UE_id = -1;
rrc_config_NB_IoT_t *mac_config=NULL;
mac_top_init_eNB_NB_IoT();
mac_config = &mac_inst->rrc_config;
long schedulingInfoSIB1 = carrier->mib_NB_IoT.message.schedulingInfoSIB1_r13;
if(ded_flag==0)
{
LOG_D(MAC,"Initiate config by system information\n");
}else
{
// now we only have 3 UE list USS for three CE levels
// fix value for RMAX to 8 / 16 / 32
mac_config->npdcch_ConfigDedicated[ue_list_ded_num].R_max = 8 + 8*ue_list_ded_num;
// fix value for G to 8 / 4 / 2
mac_config->npdcch_ConfigDedicated[ue_list_ded_num].G = 2 + (2-ue_list_ded_num)*(3-ue_list_ded_num);
// fix a_offest to 0 / 0 / 0
mac_config->npdcch_ConfigDedicated[ue_list_ded_num].a_offset = 0;
return;
}
if (&carrier->mib_NB_IoT != NULL)
{
/*
* Following the FAPI like approach:
* 1) fill the PHY_Config_t structure (PHY_INTERFACE/IF_Module_NB_IoT.h)
* 2) Call the PHY_config_req for trigger the NB_phy_config_mib_eNB() at the end
*/
//Mapping OAI params into FAPI params
config_mib_fapi_NB_IoT(carrier->physCellId,
sib1_NB_IoT->freqBandIndicator_r13,
carrier->Ncp,
carrier->Ncp_UL,
carrier->p_eNB,
carrier->p_rx_eNB,
carrier->dl_CarrierFreq,
carrier->ul_CarrierFreq,
sib1_NB_IoT->eutraControlRegionSize_r13,
&carrier->mib_NB_IoT
);
}else
{
LOG_E(MAC,"carrier->mib_NB_IoT is NULL\n");
return;
}
if(sib1_NB_IoT != NULL)
{
if(schedulingInfoSIB1 <=11)
{
// the value come from table 16.4.1.3-3 from TS 36.213
switch(schedulingInfoSIB1%3)
{
case 0:
mac_config->sib1_NB_IoT_sched_config.repetitions = 4;
// the value come from table 16.4.1.3-4 from TS 36.213
mac_config->sib1_NB_IoT_sched_config.starting_rf = (carrier->physCellId % 4) * 16;
break;
case 1:
mac_config->sib1_NB_IoT_sched_config.repetitions = 8;
mac_config->sib1_NB_IoT_sched_config.starting_rf = (carrier->physCellId % 2) * 16;
break;
case 2:
mac_config->sib1_NB_IoT_sched_config.repetitions = 16;
mac_config->sib1_NB_IoT_sched_config.starting_rf = carrier->physCellId % 2;
break;
}
}else
LOG_E(MAC,"SchedulinginfoSIB1 value not available!\n");
mac_config->si_window_length = ms160;
///OAI only supports SIB2/3-NB for the system information
mac_config->sibs_NB_IoT_sched[0].si_periodicity = si_Periodicity_rf64 ;
mac_config->sibs_NB_IoT_sched[0].si_repetition_pattern = si_RepetitionPattern_every4thRF;
mac_config->sibs_NB_IoT_sched[0].sib_mapping_info = sib3_v;
mac_config->sibs_NB_IoT_sched[0].si_tb = si_TB_680;
LOG_D(MAC,"si_periodicity:%d, siw: %d, start rf: %d\n",mac_config->sibs_NB_IoT_sched[0].si_periodicity, mac_config->si_window_length,mac_config->sib1_NB_IoT_sched_config.starting_rf);
}else
{
LOG_E(MAC,"sib1_NB_IoT is NULL\n");
}
if (radioResourceConfigCommon!=NULL)
{
//LOG_I(MAC,"[CONFIG]SIB2/3-NB radioResourceConfigCommon Contents (partial)\n");
LTE_NPRACH_Parameters_NB_r13_t* nprach_parameter;
//CE level 0
if ( radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[0] != NULL)
{
nprach_parameter = radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[0];
LOG_I(MAC,"NPRACH CE 0 setting: NumRepetition: %ld Period: %ld size of list %d\n",nprach_parameter->numRepetitionsPerPreambleAttempt_r13,nprach_parameter->nprach_Periodicity_r13,radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.size);
mac_config->mac_NPRACH_ConfigSIB[0].mac_numRepetitionsPerPreambleAttempt_NB_IoT = rachrepeat[nprach_parameter->numRepetitionsPerPreambleAttempt_r13];
mac_config->mac_NPRACH_ConfigSIB[0].mac_npdcch_NumRepetitions_RA_NB_IoT = rmax[nprach_parameter->npdcch_NumRepetitions_RA_r13];
mac_config->mac_NPRACH_ConfigSIB[0].mac_npdcch_StartSF_CSS_RA_NB_IoT = gvalue[nprach_parameter->npdcch_StartSF_CSS_RA_r13];
mac_config->mac_NPRACH_ConfigSIB[0].mac_npdcch_Offset_RA_NB_IoT = pdcchoffset[nprach_parameter->npdcch_Offset_RA_r13];
mac_inst->npdcch_config_common[0].R_max = rmax[nprach_parameter->npdcch_NumRepetitions_RA_r13];
mac_inst->npdcch_config_common[0].G = gvalue[nprach_parameter->npdcch_StartSF_CSS_RA_r13];
mac_inst->npdcch_config_common[0].a_offset = pdcchoffset[nprach_parameter->npdcch_Offset_RA_r13];
LOG_I(MAC,"NPRACH CE 0 setting: Rmax: %u G: %lf a: %lf\n",mac_inst->npdcch_config_common[0].R_max,mac_inst->npdcch_config_common[0].G,mac_inst->npdcch_config_common[0].a_offset);
}
//CE level 1
if ( radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[1] != NULL)
{
nprach_parameter = radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[1];
LOG_I(MAC,"NPRACH CE 1 setting: NumRepetiion: %ld size of list %d\n",nprach_parameter->numRepetitionsPerPreambleAttempt_r13,radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.size);
mac_config->mac_NPRACH_ConfigSIB[1].mac_numRepetitionsPerPreambleAttempt_NB_IoT = rachrepeat[nprach_parameter->numRepetitionsPerPreambleAttempt_r13];
mac_config->mac_NPRACH_ConfigSIB[1].mac_npdcch_NumRepetitions_RA_NB_IoT = rmax[nprach_parameter->npdcch_NumRepetitions_RA_r13];
mac_config->mac_NPRACH_ConfigSIB[1].mac_npdcch_StartSF_CSS_RA_NB_IoT = gvalue[nprach_parameter->npdcch_StartSF_CSS_RA_r13];
mac_config->mac_NPRACH_ConfigSIB[1].mac_npdcch_Offset_RA_NB_IoT = pdcchoffset[nprach_parameter->npdcch_Offset_RA_r13];
mac_inst->npdcch_config_common[1].R_max = rmax[nprach_parameter->npdcch_NumRepetitions_RA_r13];
mac_inst->npdcch_config_common[1].G = gvalue[nprach_parameter->npdcch_StartSF_CSS_RA_r13];
mac_inst->npdcch_config_common[1].a_offset = pdcchoffset[nprach_parameter->npdcch_Offset_RA_r13];
LOG_I(MAC,"NPRACH CE 1 setting: Rmax: %u G: %lf a: %lf\n",mac_inst->npdcch_config_common[1].R_max,mac_inst->npdcch_config_common[1].G,mac_inst->npdcch_config_common[1].a_offset);
}
//CE level 2
if ( radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[2] != NULL)
{
nprach_parameter = radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.array[2];
LOG_I(MAC,"NPRACH CE 2 setting: NumRepetiion: %ld size of list %d\n",nprach_parameter->numRepetitionsPerPreambleAttempt_r13,radioResourceConfigCommon->nprach_Config_r13.nprach_ParametersList_r13.list.size);
mac_config->mac_NPRACH_ConfigSIB[2].mac_numRepetitionsPerPreambleAttempt_NB_IoT = rachrepeat[nprach_parameter->numRepetitionsPerPreambleAttempt_r13];
mac_config->mac_NPRACH_ConfigSIB[2].mac_npdcch_NumRepetitions_RA_NB_IoT = rmax[nprach_parameter->npdcch_NumRepetitions_RA_r13];
mac_config->mac_NPRACH_ConfigSIB[2].mac_npdcch_StartSF_CSS_RA_NB_IoT = gvalue[nprach_parameter->npdcch_StartSF_CSS_RA_r13];
mac_config->mac_NPRACH_ConfigSIB[2].mac_npdcch_Offset_RA_NB_IoT = pdcchoffset[nprach_parameter->npdcch_Offset_RA_r13];
mac_inst->npdcch_config_common[2].R_max = rmax[nprach_parameter->npdcch_NumRepetitions_RA_r13];
mac_inst->npdcch_config_common[2].G = gvalue[nprach_parameter->npdcch_StartSF_CSS_RA_r13];
mac_inst->npdcch_config_common[2].a_offset = pdcchoffset[nprach_parameter->npdcch_Offset_RA_r13];
LOG_I(MAC,"NPRACH CE 2 setting: Rmax: %u G: %lf a: %lf\n",mac_inst->npdcch_config_common[2].R_max,mac_inst->npdcch_config_common[2].G,mac_inst->npdcch_config_common[2].a_offset);
}
config_sib2_fapi_NB_IoT(carrier->physCellId,radioResourceConfigCommon);
}else
{
LOG_E(MAC,"radioResourceConfigCommon is NULL\n");
}
if (logicalChannelConfig!= NULL) {
if (UE_id == -1)
{
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
}
else
{
//logical channel group not defined for nb-iot --> no UL specific Parameter
// or at least LCGID should be set to 0 for NB-IoT (See TS 36.321 ch 6.1.3.1) so no make sense to store this
}
}
if (physicalConfigDedicated != NULL) {
if (UE_id == -1)
LOG_E(MAC,"%s:%d:%s: ERROR, UE_id == -1\n", __FILE__, __LINE__, __FUNCTION__);
else
{
LOG_D(MAC,"UE id = %d\n",UE_id);
}
}
if(mac_inst->if_inst_NB_IoT!=NULL)
{
if (radioResourceConfigCommon!=NULL)
{
AssertFatal( mac_inst->if_inst_NB_IoT->PHY_config_req != NULL, "rrc_mac_config_req_eNB_NB_IoT: PHY_config_req pointer function is NULL\n");
PHY_Config_NB_IoT_t phycfg;
phycfg.mod_id = Mod_idP;
phycfg.cfg = &mac_inst->config;
if (mac_inst->if_inst_NB_IoT->PHY_config_req)
mac_inst->if_inst_NB_IoT->PHY_config_req(&phycfg);
}
}else
{
LOG_E(MAC,"NB-IoT IF INST is NULL, need to fix\n");
}
init_mac_NB_IoT(mac_inst);
LOG_I(MAC,"[NB-IoT] Init_MAC done\n");
}

36
openair2/LAYER2/MAC/config_NB_IoT.h Normal file → Executable file
View File

@@ -2,17 +2,16 @@
/*! \file config_NB_IoT.h
* \brief configured structures used by scheduler
* \author NTUST BMW Lab./
* \date 2017
* \date 2019
* \email:
* \version 1.0
* \version 2.0
*
*/
#ifndef _CONFIG_H_
#define _CONFIG_H_
//#include "NB_IoT_Message_definitions.h"
#define NUMBER_OF_SIBS_MAX_NB_IoT 6
///MIB
@@ -23,6 +22,7 @@ typedef enum operationModeInf{
standalone_r13 = 4
} operationModeInf_t;
///SIB1_SchedulingInfo_NB_IoT_r13
typedef enum si_Periodicity{
si_Periodicity_rf64=640,
@@ -51,14 +51,14 @@ typedef enum sib_MappingInfo{
} sib_MappingInfo_NB_IoT;
typedef enum si_TB{
si_TB_56=2,
si_TB_120=2,
si_TB_208=8,
si_TB_256=8,
si_TB_328=8,
si_TB_440=8,
si_TB_552=8,
si_TB_680=8
si_TB_56=0,
si_TB_120,
si_TB_208,
si_TB_256,
si_TB_328,
si_TB_440,
si_TB_552,
si_TB_680
} si_TB_NB_IoT;
///RACH_ConfigCommon configuration
@@ -92,7 +92,7 @@ typedef enum nprach_Periodicity{
nprach_Periodicity_ms80=80,
nprach_Periodicity_ms160=160,
nprach_Periodicity_ms240=240,
nprach_Periodicity_ms320=320,
nprach_Periodicity_ms320=320,
nprach_Periodicity_ms640=640,
nprach_Periodicity_ms1280=1280,
nprach_Periodicity_ms2560=2560
@@ -202,7 +202,7 @@ typedef enum si_periodicity_e{
rf128=1280,
rf256=2560,
rf512=5120,
rf1024=10240,
rf1024=10240,
rf2048=20480,
rf4096=40960
} si_periodicity_t;
@@ -210,7 +210,7 @@ typedef enum si_periodicity_e{
typedef enum si_repetition_pattern_e{
every2ndRF=20,
every4thRF=40,
every8thRF=80,
every8thRF=80,
every16thRF=160
} si_repetition_pattern_t;
@@ -225,13 +225,11 @@ typedef enum si_tb_e{
b680=8
} si_tb_t;
typedef struct sibs_NB_IoT_sched_s{
si_periodicity_t si_periodicity;
si_periodicity_t si_periodicity;
si_repetition_pattern_t si_repetition_pattern;
sib_MappingInfo_NB_IoT sib_mapping_info; //bit vector
si_tb_t si_tb;
si_TB_NB_IoT si_tb;
} sibs_NB_IoT_sched_t;

View File

@@ -261,7 +261,14 @@ typedef struct {
uint8_t PH:6;
uint8_t R:2;
} __attribute__((__packed__))POWER_HEADROOM_CMD;
/*!\brief DCI PDU filled by MAC for the PHY */
typedef struct {
uint8_t Num_ue_spec_dci ;
uint8_t Num_common_dci ;
// uint32_t nCCE;
uint32_t num_pdcch_symbols;
DCI_ALLOC_t dci_alloc[NUM_DCI_MAX] ;
} DCI_PDU;
/*! \brief MIB payload */
typedef struct {
uint8_t payload[3] ;
@@ -305,7 +312,6 @@ typedef struct {
uint8_t lcid:5; // octet 2 MSB
uint8_t stop_sf_LSB:8;
} __attribute__((__packed__))MSI_ELEMENT;
#endif
/*! \brief Values of CCCH LCID for DLSCH */
#define CCCH_LCHANID 0
/*!\brief Values of BCCH logical channel (fake)*/
@@ -1343,3 +1349,4 @@ typedef struct {
#include "proto.h"
/*@}*/
#endif /*__LAYER2_MAC_DEFS_H__ */
#endif

View File

@@ -1,4 +1,3 @@
/*! \file defs_NB_IoT.c
* \brief MAC layer structures
* \author NTUST BMW Lab./
@@ -16,16 +15,18 @@
#endif
//#include "COMMON/openair_defs.h"
#include "COMMON/platform_constants.h"
#include "COMMON/mac_rrc_primitives.h"
#include "PHY/LTE_TRANSPORT/defs_NB_IoT.h"
//#include "COMMON/mac_rrc_primitives.h"
#include "PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
//#include "PHY/defs.h"
#include "PHY/defs_L1_NB_IoT.h"
#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
#include "config_NB_IoT.h"
// MAC definition
#define MAX_FRAME 0xfffff
#define NUM_FRAME 0x100000
#define MAX_SUBFRAME 10485760
//#define MAX_FRAME 0xfffff
//#define NUM_FRAME 0x100000
//#define MAX_SUBFRAME 10485760
#define MAX_FRAME 0xfff
#define MAX_SUBFRAME 40960
#define MAX(a, b) (((a)>(b))?(a):(b))
@@ -64,7 +65,7 @@
#define DTCH 3 // LCID
/*!\brief MCCH logical channel */
//#define MCCH 4
#define MCCH 62
//#define MCCH 62
/*!\brief MTCH logical channel */
#define MTCH 1
// DLSCH LCHAN ID
@@ -77,6 +78,13 @@
/*!\brief LCID of padding LCID for DLSCH */
#define SHORT_PADDING 31
typedef enum rach_state_e
{
initial_access = 0,
rach_for_auth_rsp,
rach_for_TAU,
rach_for_next
}rach_state_t;
typedef enum tone_type_e
{
@@ -99,10 +107,10 @@ typedef enum{
DL
}message_direction_t;
#define MAX_MAX_MOBILES_PER_ENB_NB_IoT 20
#define MAX_NUMBER_OF_UE_MAX_NB_IoT 20
#define SCH_PAYLOAD_SIZE_MAX_NB_IoT 320
#define MAX_NUMBER_OF_SIBs_NB_IoT 16
#define MAX_NUMBER_OF_UE_MAX_NB_IoT 20
/*!\brief Values of BCCH0 logical channel for MIB*/
#define BCCH0_NB_IoT 11 // MIB-NB_IoT
/*!\brief Values of BCCH1 logical channel for SIBs */
@@ -129,33 +137,6 @@ typedef enum{
/*Index of PADDING logical channel*/
#define PADDING 31
/// NPRACH-ParametersList-NB_IoT-r13 from 36.331 RRC spec defined in PHY
/*typedef struct NPRACH_Parameters_NB_IoT{
/// the period time for nprach
int nprach_Periodicity;
/// for the start time for the NPRACH resource from 40ms-2560ms
int nprach_StartTime;
/// for the subcarrier of set to the NPRACH preamble from n0 - n34
int nprach_SubcarrierOffset;
///number of subcarriers in a NPRACH resource allowed values (n12,n24,n36,n48)
int nprach_NumSubcarriers;
/// where is the region that in NPRACH resource to indicate if this UE support MSG3 for multi-tone or not. from 0 - 1
int nprach_SubcarrierMSG3_RangeStart;
/// The max preamble transmission attempt for the CE level from 1 - 128
int maxNumPreambleAttemptCE;
/// Number of NPRACH repetitions per attempt for each NPRACH resource
int numRepetitionsPerPreambleAttempt;
/// The number of the repetition for DCI use in RAR/MSG3/MSG4 from 1 - 2048 (Rmax)
int npdcch_NumRepetitions_RA;
/// Starting subframe for NPDCCH Common searching space for (RAR/MSG3/MSG4)
int npdcch_StartSF_CSS_RA;
/// Fractional period offset of starting subframe for NPDCCH common search space
int npdcch_Offset_RA;
} nprach_parameters_NB_IoT_t;*/
/*! \brief Downlink SCH PDU Structure */
typedef struct {
uint8_t payload[SCH_PAYLOAD_SIZE_MAX_NB_IoT];
@@ -210,11 +191,105 @@ typedef struct {
int prev;
// MSG4 complete
int RRC_connected;
uint8_t flag_schedule_success;
// UE active flag
int active;
boolean_t active;
uint8_t allocated_data_size_ul;
} UE_TEMPLATE_NB_IoT;
// link list of uplink resource node
typedef struct available_resource_UL_s{
///Resource start subframe
uint32_t start_subframe;
///Resource end subframe
uint32_t end_subframe;
//pointer to next and previous node
struct available_resource_UL_s *next, *prev;
}available_resource_UL_t;
// link list of downlink resource node
typedef struct available_resource_DL_s{
///Resource start subframe
uint32_t start_subframe;
///Resource end subframe
uint32_t end_subframe;
//pointer to next and previous node
struct available_resource_DL_s *next, *prev;
}available_resource_DL_t;
/*Structure used for scheduling*/
typedef struct{
//resource position info.
uint32_t sf_end,sf_start;
//resource position info. separate by HyperSF, Frame, Subframe
uint32_t start_h, end_h;
uint32_t start_f, end_f;
uint32_t start_sf, end_sf;
//whcih available resource node is used
available_resource_DL_t *node;
}sched_temp_DL_NB_IoT_t;
/*Structure used for UL scheduling*/
typedef struct{
//resource position info, used subframe as unit
uint32_t sf_end, sf_start;
// information for allocating the resource (to fill DCIN)
int tone;
int scheduling_delay;
int subcarrier_indication;
int ACK_NACK_resource_field;
available_resource_UL_t *node;
}sched_temp_UL_NB_IoT_t;
/*** the value of variable in this structure is able to be changed in Preprocessor**/
typedef struct{
uint16_t TBS;
uint8_t index_tbs;
uint32_t total_sdu_size;
//Repetition
uint16_t R_dci;
uint16_t R_dl_data;
uint16_t R_dl_harq;
uint16_t R_ul_data;
//DL relative
uint8_t dci_n1_index_R_dci;
uint8_t dci_n1_index_R_data;
uint8_t dci_n1_index_mcs;
uint8_t dci_n1_index_sf;
uint8_t dci_n1_index_delay;
uint8_t dci_n1_index_ack_nack;
uint32_t dci_n1_n_sf;
//UL relative
uint8_t dci_n0_index_R_dci;
uint8_t dci_n0_index_R_data;
uint8_t dci_n0_index_mcs;
uint8_t dci_n0_index_ru;
uint8_t dci_n0_index_delay;
uint8_t dci_n0_index_subcarrier;
uint32_t dci_n0_n_ru;
uint8_t dci_n0_index_rv;
uint8_t dci_n0_index_ndi;
// byte
uint16_t total_data_size_dl;
// byte
uint16_t total_data_size_ul;
//0:UL 1:DL 2:both
uint16_t transmit_direction;
/*resource allocation*/
// scheduling result for NPDCCH
uint32_t NPDCCH_sf_end, NPDCCH_sf_start;
// scheduling result for USS DL
uint32_t NPDSCH_sf_end, NPDSCH_sf_start;
uint32_t HARQ_sf_end, HARQ_sf_start;
// scheduling result for USS UL
uint32_t NPUSCH_sf_end, NPUSCH_sf_start;
// schedule success 1 failure 0
uint8_t flag_schedule_success;
}UE_SCHED_CTRL_NB_IoT_t;
/*36331 NPDCCH-ConfigDedicated-NB_IoT*/
typedef struct{
//npdcch-NumRepetitions-r13
@@ -234,23 +309,24 @@ typedef struct{
typedef struct {
/// DCI template and MAC connection parameters for UEs
UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_MAX_MOBILES_PER_ENB_NB_IoT];
UE_TEMPLATE_NB_IoT UE_template_NB_IoT[MAX_NUMBER_OF_UE_MAX_NB_IoT];
UE_SCHED_CTRL_NB_IoT_t UE_sched_ctrl_NB_IoT[MAX_NUMBER_OF_UE_MAX_NB_IoT];
/// NPDCCH Period and searching space info
NPDCCH_config_dedicated_NB_IoT_t NPDCCH_config_dedicated;
//int next[MAX_MAX_MOBILES_PER_ENB_NB_IoT];
//int next[MAX_NUMBER_OF_UE_MAX_NB_IoT];
// -1:No UE in list
int head;
// -1:No UE in list
int tail;
int num_UEs;
//boolean_t active[MAX_MAX_MOBILES_PER_ENB_NB_IoT];
//boolean_t active[MAX_NUMBER_OF_UE_MAX_NB_IoT];
} UE_list_NB_IoT_t;
// scheduling flag calculated by computing flag function
typedef struct{
// flag to indicate scheduing MIB-NB_IoT
uint8_t flag_MIB;
// flag to indicate scheduling SIB1-NB_IoT
@@ -262,7 +338,7 @@ typedef struct{
// flag to indicate scheduling type1 NPDCCH CSS with different CE level
uint8_t flag_type1_css[3];
// flag to indicate scheduling NPDCCH USS with UE list
uint8_t flag_uss[MAX_MAX_MOBILES_PER_ENB_NB_IoT];
uint8_t flag_uss[MAX_NUMBER_OF_UE_MAX_NB_IoT];
// flag to indicate scheduling sib1/MIB
uint8_t flag_fix_scheduling;
// number of the type2 css to schedule in this period
@@ -271,39 +347,8 @@ typedef struct{
uint8_t num_type1_css_run;
// number of the uss to schedule in this period
uint8_t num_uss_run;
}scheduling_flag_t;
typedef struct available_resource_UL_s{
///Resource start subframe
uint32_t start_subframe;
///Resource end subframe
uint32_t end_subframe;
// pointer to next node
struct available_resource_UL_s *next, *prev;
}available_resource_UL_t;
typedef struct available_resource_DL_s{
uint32_t start_subframe;
uint32_t end_subframe;
struct available_resource_DL_s *next, *prev;
}available_resource_DL_t;
/*Structure used for scheduling*/
typedef struct{
//resource position info.
uint32_t sf_end,sf_start;
//resource position info. separate by HyperSF, Frame, Subframe
uint32_t start_h, end_h;
uint32_t start_f, end_f;
uint32_t start_sf, end_sf;
//whcih available resource node is used
available_resource_DL_t *node;
}sched_temp_DL_NB_IoT_t;
/*!\brief MAC subheader short with 7bit Length field */
typedef struct {
uint8_t LCID:5; // octet 1 LSB
@@ -313,6 +358,7 @@ typedef struct {
uint8_t L:7; // octet 2 LSB
uint8_t F:1; // octet 2 MSB
} __attribute__((__packed__))SCH_SUBHEADER_SHORT_NB_IoT;
typedef struct {
uint8_t LCID:5; // octet 1 LSB
uint8_t E:1;
@@ -322,6 +368,7 @@ typedef struct {
uint8_t F:1; // octet 2 MSB
uint8_t L_LSB:8;
} __attribute__((__packed__))SCH_SUBHEADER_LONG_NB_IoT;
typedef struct {
uint8_t LCID:5; // octet 1 LSB
uint8_t E:1;
@@ -330,12 +377,12 @@ typedef struct {
uint8_t L_MSB:8; // octet 2 MSB
uint8_t L_LSB:8;
} __attribute__((__packed__))SCH_SUBHEADER_LONG_EXTEND_NB_IoT;
/*!\brief MAC subheader short without length field */
typedef struct {
uint8_t LCID:5;
uint8_t F2:1;
uint8_t E:1;
uint8_t R:1;
uint8_t R:2;
} __attribute__((__packed__))SCH_SUBHEADER_FIXED_NB_IoT;
@@ -356,38 +403,23 @@ typedef struct {
uint8_t E:1;
} __attribute__((__packed__))RA_HEADER_RAPID_NB_IoT;
/*Structure used for UL scheduling*/
typedef struct{
//resource position info.
uint32_t sf_end, sf_start;
//resource position info. separate by HyperSF, Frame, Subframe
//uint32_t start_h, end_h;
//uint32_t start_f, end_f;
//uint32_t start_sf, end_sf;
// information for allocating the resource
int tone;
int scheduling_delay;
int subcarrier_indication;
int ACK_NACK_resource_field;
available_resource_UL_t *node;
}sched_temp_UL_NB_IoT_t;
typedef struct Available_available_resource_DL{
typedef struct Available_resource_tones_UL_s{
///Available Resoruce for sixtone
available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame;
///Available Resoruce for sixtone
available_resource_UL_t *sixtone_Head;//, *sixtone_npusch_frame;
uint32_t sixtone_end_subframe;
///Available Resoruce for threetone
available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame;
///Available Resoruce for threetone
available_resource_UL_t *threetone_Head;//, *threetone_npusch_frame;
uint32_t threetone_end_subframe;
///Available Resoruce for singletone1
available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame;
///Available Resoruce for singletone1
available_resource_UL_t *singletone1_Head;//, *singletone1_npusch_frame;
uint32_t singletone1_end_subframe;
///Available Resoruce for singletone2
available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame;
uint32_t singletone2_end_subframe;
///Available Resoruce for singletone2
available_resource_UL_t *singletone2_Head;//, *singletone2_npusch_frame;
uint32_t singletone2_end_subframe;
///Available Resoruce for singletone3
available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame;
available_resource_UL_t *singletone3_Head;//, *singletone3_npusch_frame;
uint32_t singletone3_end_subframe;
}available_resource_tones_UL_t;
@@ -422,6 +454,14 @@ typedef struct schedule_result{
uint8_t *rar_buffer;
int16_t dl_sdly;
int16_t ul_sdly;
int16_t num_sf;
int16_t harq_round;
// determine this uplink data is msg3 or not (different TBS table here)
uint8_t msg3_flag;
}schedule_result_t;
/*Flag structure used for trigger each scheduler*/
@@ -465,7 +505,9 @@ typedef struct RA_TEMPLATE_NB_IoT_s{
boolean_t wait_msg4_ack;
boolean_t wait_msg3_ack;
uint8_t rar_buffer[7];
uint8_t *ccch_buffer;
uint8_t msg4_buffer[16];
uint8_t *msg4_rrc_buffer;
} RA_TEMPLATE_NB_IoT;
typedef struct RA_template_list_s{
@@ -473,29 +515,46 @@ typedef struct RA_template_list_s{
RA_TEMPLATE_NB_IoT *tail;
}RA_template_list_t;
/*36331 NPDCCH-ConfigDedicated-NB_IoT*/
typedef struct{
//npdcch-NumRepetitions-r13
uint32_t R_max;
//npdcch-StartSF-CSS-r13
double G;
//npdcch-Offset-USS-r13
double a_offset;
//NPDCCH period
uint32_t T;
//Starting subfrane of Search Space which is mod T
uint32_t ss_start_css;
}NPDCCH_config_common_NB_IoT_t;
/*! \brief top level eNB MAC structure */
typedef struct eNB_MAC_INST_NB_IoT_s {
typedef struct eNB_MAC_INST_NB_IoT_s{
/// Ethernet parameters for northbound midhaul interface
eth_params_t eth_params_n;
/// Ethernet parameters for fronthaul interface
eth_params_t eth_params_s;
uint8_t Mod_id;
uint8_t Mod_id;
// System
uint32_t hyper_system_frame;
uint32_t system_frame;
uint32_t sub_frame;
uint32_t current_subframe;
/// Pointer to IF module instance for PHY
IF_Module_t *if_inst;
// RA
RA_template_list_t RA_msg2_list;
RA_template_list_t RA_msg3_list;
RA_template_list_t RA_msg4_list;
RA_TEMPLATE_NB_IoT RA_template[MAX_MAX_MOBILES_PER_ENB_NB_IoT];
RA_TEMPLATE_NB_IoT RA_template[MAX_NUMBER_OF_UE_MAX_NB_IoT];
//int32_t last_tx_subframe;
@@ -516,13 +575,18 @@ typedef struct eNB_MAC_INST_NB_IoT_s {
scheduling_flag_t scheduling_flag;
uint32_t schedule_subframe_DL;
uint32_t schedule_subframe_UL;
//uint32_t schedule_subframe_UL;
NPDCCH_config_common_NB_IoT_t npdcch_config_common[3];
rrc_config_NB_IoT_t rrc_config;
nfapi_config_request_t config;
IF_Module_NB_IoT_t *if_inst_NB_IoT;
IF_Module_NB_IoT_t *if_inst_NB_IoT;
Sched_Rsp_NB_IoT_t Sched_INFO;
} eNB_MAC_INST_NB_IoT;
// actually not here, but for now put it here

View File

@@ -0,0 +1,419 @@
/*! \file eNB_scheduler_NB_IoT.c
* \brief top level of the scheduler, it scheduled in pdcch period based.
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
#include "defs_NB_IoT.h"
#include "proto_NB_IoT.h"
#include "extern_NB_IoT.h"
// scheduler
#define flag_css_type1 0x1
#define flag_css_type2 0x2
#define flag_uss_v 0x4
// common
#define flag_mib 0x1
#define flag_sib1 0x2
#define flag_npss 0x4
#define flag_nsss 0x8
unsigned char str22[] = "UL_Data";
unsigned char str23[] = "DCI_N0";
//extern BCCH_DL_SCH_Message_NB_IoT_t SIB;
void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe){
uint32_t subframe = abs_subframe % 10;
uint32_t frame = abs_subframe / 10;
int i;
uint32_t max = 0;
//NPRACH_Parameters_NB_IoT_r13_t **type2_css_info = SIB.message.choice.c1.choice.systemInformation_r13.criticalExtensions.choice.systemInformation_r13.sib_TypeAndInfo_r13.choice.sib2_r13.radioResourceConfigCommon_r13.nprach_Config_r13.nprach_ParametersList_r13.list.array;
// fixed scheduling part (e.g. MIB, NPSS, NSSS, SIB1)
if(subframe == 0){
*common_flags |= flag_mib;
}else if(subframe == 5){
*common_flags |= flag_npss;
}else if(subframe == 9 && (frame&0x1)==0){
*common_flags |= flag_nsss;
}else if(subframe == 4 && mac_inst->sib1_flag[frame%mac_inst->sib1_period]){
*common_flags |= flag_sib1;
}
uint32_t type2_css_pp[3] = { mac_inst->npdcch_config_common[0].R_max*mac_inst->npdcch_config_common[0].G,
mac_inst->npdcch_config_common[1].R_max*mac_inst->npdcch_config_common[1].G,
mac_inst->npdcch_config_common[2].R_max*mac_inst->npdcch_config_common[2].G };
uint32_t start_subframe;
for(i=0; i<1; ++i){ // only CE0
if(mac_inst->npdcch_config_common[i].a_offset==0)
{
start_subframe = 0;
}
else if(mac_inst->npdcch_config_common[i].a_offset==1/8)
{
start_subframe = type2_css_pp[i]>>3;
}
else if(mac_inst->npdcch_config_common[i].a_offset==1/4)
{
start_subframe = type2_css_pp[i]>>2;
}
else if(mac_inst->npdcch_config_common[i].a_offset==3/8)
{
start_subframe = (type2_css_pp[i]>>3)+(type2_css_pp[i]>>2);
}
if(((abs_subframe+1)%type2_css_pp[i])==start_subframe){
*scheduler_flags |= flag_css_type2;
max = MAX(max, extend_space[i]);
LOG_D(MAC,"[%d][computing flags] common searching space: %d, num subframe: %d\n", mac_inst->current_subframe, i, extend_space[i]);
}
}
//USS trigger flag
for(i=0;i<mac_inst->num_uss_list;++i)
{
if(((abs_subframe+1)%mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T)==mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.ss_start_uss)
{
*scheduler_flags |= (flag_uss_v<<i);
max = MAX(max, mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T);
LOG_D(MAC,"[%d][computing flags] UE-spec searching space: %d, num subframe: %d\n", mac_inst->current_subframe, i, mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T);
}
}
*max_subframe = max; // the maximum subframe to be extend
}
/*function description:
* top level of the scheduler, this will trigger in every subframe,
* and determined if do the schedule by checking this current subframe is the start of the NPDCCH period or not
*/
void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe){
int i;
uint8_t MIB_flag = 0, SIB1_flag = 0;
uint32_t scheduler_flags, max_subframe, common_flags;
/*Check this subframe should schedule something, set the flag*/
scheduler_flags = 0;
common_flags = 0;
uint32_t h,f,sf,a;
mac_inst->current_subframe = abs_subframe;
eNB_scheduler_computing_flag_NB_IoT(mac_inst, abs_subframe, &scheduler_flags, &common_flags, &max_subframe);
if(scheduler_flags > 0){
extend_available_resource_DL(mac_inst, mac_inst->current_subframe +1 + max_subframe);
}
maintain_available_resource(mac_inst);
if((abs_subframe % nprach_list->nprach_Periodicity) == rachstart[0]){ //TODO, configuration should be pass by configuration module
add_UL_Resource();
}
//Check if type2 searching space scheduling
if((scheduler_flags&flag_css_type2)>0){
schedule_RA_NB_IoT(mac_inst);
scheduler_flags &= ~(flag_css_type2);
}
//Check if type1 searching space scheduling
if((scheduler_flags&flag_css_type1)>0){
// paging, direct indication
scheduler_flags &= ~(flag_css_type1);
}
//The scheduling time is current subframe + 1
convert_system_number(abs_subframe+1, &h, &f, &sf);
// loop all USS period
for(i=0;i<mac_inst->num_uss_list;++i)
{
if((scheduler_flags&(flag_uss_v<<i))>0){
LOG_D(MAC,"--------------[%04d][SchedulerUSS] Schedule USS list %d------------\n", mac_inst->current_subframe, (scheduler_flags&(flag_uss_v<<i))>>3);
schedule_uss_NB_IoT(0, mac_inst,sf, f, h, i);
LOG_D(MAC,"--------------[%04d][SchedulerUSS] Schedule USS list %d end------------\n", mac_inst->current_subframe, (scheduler_flags&(flag_uss_v<<i))>>3);
scheduler_flags &= ~(flag_uss_v<<i);
}
}
if(common_flags == flag_mib)
MIB_flag = 1;
if(common_flags == flag_sib1)
SIB1_flag = 1;
convert_system_number(abs_subframe, &h, &f, &sf);
a = output_handler(mac_inst, 0,0,h,f,sf,MIB_flag,SIB1_flag, abs_subframe);
if(a==-1)
LOG_I(MAC,"[%04d][SchedulerUSS] schedule result is empty------------\n", mac_inst->current_subframe);
}
void USS_scheduling_module(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint8_t total_num_UE_list)
{
int i, max_subframe,MIB_flag,SIB1_flag;
/*Check this subframe should schedule something, set the flag*/
MIB_flag = 0;
SIB1_flag = 0;
max_subframe=0;
uint32_t h,f,sf;
int a;
int UE_list_index;
// how many scheduling is triggered this sunframe
uint8_t num_sched_UE_list=0;
uint8_t *UE_list_flag=(uint8_t*)malloc(total_num_UE_list*sizeof(uint8_t));
//DEBUG("[%04d][USS_scheduling_module] check scheduling trigger\n", mac_inst->current_subframe);
//eNB_scheduler_computing_flag_NB_IoT(mac_inst, abs_subframe, &scheduler_flags, &common_flags, &max_subframe);
// Check which scheduling period of UE_list is triggered
for(i=0;i<total_num_UE_list;++i)
{
if(((abs_subframe+1)%mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T)==mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.ss_start_uss)
//if((abs_subframe+1)%16==0)
{
if(mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T>max_subframe)
{
max_subframe=mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T;
}
UE_list_flag[i]=1;
num_sched_UE_list++;
//*scheduler_flags |= (flag_uss_v<<i);
//max = MAX(max, mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T);
LOG_D(MAC,"[%d][USS_scheduling_module] UE_list num: %d, num subframe: %d\n", mac_inst->current_subframe, i, mac_inst->UE_list_spec[i].NPDCCH_config_dedicated.T);
}
else
{
UE_list_flag[i]=0;
}
}
// Update available resource
if(num_sched_UE_list > 0)
{
LOG_D(MAC,"[%d][USS_scheduling_module] extend resource\n", mac_inst->current_subframe);
//DEBUG("[%04d][USS_scheduling_module] In extend_available_resource_DL\n", mac_inst->current_subframe);
extend_available_resource_DL(mac_inst, mac_inst->current_subframe +1 + max_subframe);
}
maintain_available_resource(mac_inst);
// reserve resource for NPRACH
if((abs_subframe % nprach_list->nprach_Periodicity) == rachstart[0])
{
//DEBUG("[%04d][USS_scheduling_module] In add_UL_Resource\n", mac_inst->current_subframe);
add_UL_Resource();
}
//The scheduling time is current subframe + 1
convert_system_number(abs_subframe+1, &h, &f, &sf);
// loop all USS period
for(UE_list_index=0;UE_list_index<total_num_UE_list;++UE_list_index)
{
//if((scheduler_flags&(flag_uss_v<<i))>0){
if(UE_list_flag[UE_list_index]==1)
{
LOG_D(MAC,"--------------[%04d][USS_scheduling_module] Schedule USS list %d------------\n", mac_inst->current_subframe, UE_list_index);
//USS Scheduling for corresponding index
schedule_uss_NB_IoT(0, mac_inst,sf, f, h, UE_list_index);
LOG_D(MAC,"--------------[%04d][USS_scheduling_module] Schedule USS list %d end------------\n", mac_inst->current_subframe, UE_list_index);
//scheduler_flags &= ~(flag_uss_v<<i);
}
}
// flag for generating SIB1 and MIB message
if(abs_subframe%10 == 0)
MIB_flag = 1;
if(abs_subframe%10 == 4 && mac_inst->sib1_flag[abs_subframe/10%mac_inst->sib1_period])
SIB1_flag = 1;
// handling output to L1
a = output_handler(mac_inst, 0,0,h,f,sf,MIB_flag,SIB1_flag, abs_subframe);
if(a==-1)
LOG_D(MAC,"[%04d][USS_scheduling_module] schedule result is empty------------\n", mac_inst->current_subframe);
}
void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int UE_list_index)
{
UE_SCHED_CTRL_NB_IoT_t *UE_sched_ctrl_info;
UE_TEMPLATE_NB_IoT *UE_template_temp;
DCIFormatN1_t *DCI_N1;
DCIFormatN0_t *DCI_N0;
//SCHEDULE_NB_IoT_t *scheduler = &eNB->scheduler;
mac_inst->scheduling_flag.flag_uss[0]=1;
mac_inst->scheduling_flag.flag_uss[1]=0;
mac_inst->scheduling_flag.flag_uss[2]=0;
mac_inst->scheduling_flag.num_uss_run = 0;
int UE_ID;
//search space index
//int index_ss=0;
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT] Start processing preprocessor\n", mac_inst->current_subframe);
/***algorithm for USS scheduling***/
preprocessor_uss_NB_IoT(module_id, mac_inst, subframe, frame, hypersfn, UE_list_index);
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT] Finish processing preprocessor\n", mac_inst->current_subframe);
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT] Do USS Final Scheduling\n", mac_inst->current_subframe);
UE_ID = mac_inst->UE_list_spec[UE_list_index].head;
while(UE_ID>-1)
{
UE_template_temp = &(mac_inst->UE_list_spec[UE_list_index].UE_template_NB_IoT[UE_ID]);
UE_sched_ctrl_info = &(mac_inst->UE_list_spec[UE_list_index].UE_sched_ctrl_NB_IoT[UE_ID]);
LOG_D(MAC,"------Start Scheduling USS UE RNTI %d------\n", UE_template_temp->rnti);
if((UE_template_temp->RRC_connected==1)&&(UE_sched_ctrl_info->flag_schedule_success==1))
{
switch(UE_template_temp->direction)
{
case 1: // Downlink Scheduling
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT][UE%d] USS DL Final scheduling\n", mac_inst->current_subframe, UE_template_temp->rnti);
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT][UE%d] UE_sched_ctrl NPDCCH information:sf_start %d sf end %d\n", mac_inst->current_subframe, UE_template_temp->rnti, UE_sched_ctrl_info->NPDCCH_sf_start, UE_sched_ctrl_info->NPDCCH_sf_end);
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT][UE%d] UE_sched_ctrl NPDSCH information:sf_start %d sf end %d\n", mac_inst->current_subframe, UE_template_temp->rnti, UE_sched_ctrl_info->NPDSCH_sf_start, UE_sched_ctrl_info->NPDSCH_sf_end);
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT][UE%d] UE_sched_ctrl HARQ information:sf_start %d sf end %d\n", mac_inst->current_subframe, UE_template_temp->rnti, UE_sched_ctrl_info->HARQ_sf_start, UE_sched_ctrl_info->HARQ_sf_end);
DCI_N1 = (DCIFormatN1_t*)malloc(sizeof(DCIFormatN1_t));
fill_DCI_N1(DCI_N1, UE_template_temp, UE_sched_ctrl_info);
generate_scheduling_result_DL(UE_sched_ctrl_info->NPDCCH_sf_end, UE_sched_ctrl_info->NPDCCH_sf_start, UE_sched_ctrl_info->NPDSCH_sf_end, UE_sched_ctrl_info->NPDSCH_sf_start, UE_sched_ctrl_info->HARQ_sf_end, UE_sched_ctrl_info->HARQ_sf_start, DCI_N1, UE_template_temp->rnti, UE_sched_ctrl_info->TBS, UE_template_temp->DLSCH_pdu.payload);
UE_template_temp->R_dci=UE_sched_ctrl_info->R_dci;
UE_template_temp->R_dl=UE_sched_ctrl_info->R_dl_data;
UE_template_temp->I_mcs_dl=UE_sched_ctrl_info->dci_n1_index_mcs;
UE_template_temp->DLSCH_pdu_size=UE_sched_ctrl_info->TBS;
if(UE_template_temp->HARQ_round==0)
UE_template_temp->oldNDI_DL=(UE_template_temp->oldNDI_DL+1)%2;
break;
case 0: // Uplink
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT][UE%d] USS UL Final scheduling\n", mac_inst->current_subframe, UE_template_temp->rnti);
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT][UE%d] UE_sched_ctrl NPDCCH information:sf_start %d sf end %d\n", mac_inst->current_subframe, UE_template_temp->rnti, UE_sched_ctrl_info->NPDCCH_sf_start, UE_sched_ctrl_info->NPDCCH_sf_end);
LOG_D(MAC,"[%04d][schedule_uss_NB_IoT][UE%d] UE_sched_ctrl NPUSCH information:sf_start %d sf end %d\n", mac_inst->current_subframe, UE_template_temp->rnti, UE_sched_ctrl_info->NPUSCH_sf_start, UE_sched_ctrl_info->NPUSCH_sf_end);
DCI_N0 = (DCIFormatN0_t*)malloc(sizeof(DCIFormatN0_t));
//generate DCI-N0 content
fill_DCI_N0(DCI_N0, UE_template_temp, UE_sched_ctrl_info);
generate_scheduling_result_UL(UE_sched_ctrl_info->NPDCCH_sf_start, UE_sched_ctrl_info->NPDCCH_sf_end,UE_sched_ctrl_info->NPUSCH_sf_start+3, UE_sched_ctrl_info->NPUSCH_sf_end+3,DCI_N0, UE_template_temp->rnti, str22, str23, 0);
//sotre UE_template
UE_template_temp->R_dci=UE_sched_ctrl_info->R_dci;
UE_template_temp->R_ul=UE_sched_ctrl_info->R_ul_data;
if(UE_template_temp->HARQ_round == 0)
{
UE_template_temp->oldNDI_UL=1-UE_template_temp->oldNDI_UL;
}
UE_template_temp->direction = -1;
break;
case -1: // Idle
//DEBUG("current idle.. \n");
break;
default:
break;
}
}
UE_sched_ctrl_info -> flag_schedule_success = 0;
UE_ID = UE_template_temp->next;
}
}
void preprocessor_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int UE_list_index)
{
int ue_id;
UE_TEMPLATE_NB_IoT *UE_template_temp;
UE_SCHED_CTRL_NB_IoT_t *UE_sched_ctrl_info;
ue_id = mac_inst->UE_list_spec[UE_list_index].head;
while(ue_id>-1)
{
UE_template_temp = &(mac_inst->UE_list_spec[UE_list_index].UE_template_NB_IoT[ue_id]);
UE_sched_ctrl_info = &(mac_inst->UE_list_spec[UE_list_index].UE_sched_ctrl_NB_IoT[ue_id]);
//determine index of MCS, TBS, R, R_max, R_dci, R_harq
UE_sched_ctrl_info->R_dci=UE_template_temp->R_dci;
//Set repetition number of downlink transmission
if(UE_template_temp->direction==1)
{
UE_sched_ctrl_info->R_dl_data=UE_template_temp->R_dl;
UE_sched_ctrl_info->R_dl_harq=UE_template_temp->R_harq;
UE_sched_ctrl_info->dci_n1_index_mcs=UE_template_temp->I_mcs_dl;
LOG_D(MAC,"[%04d][preprocessor_uss_NB_IoT][UE%d] Initialze R_dci %d R_data_dl %d R_harq %d \n", mac_inst->current_subframe, UE_template_temp->rnti, UE_sched_ctrl_info->R_dci=UE_template_temp->R_dci, UE_sched_ctrl_info->R_dl_data, UE_sched_ctrl_info->R_dl_harq=UE_template_temp->R_harq);
//determine how many SF for data transmission
//store_rlc_logical_channel_info_dl();
}
//Set repetition number of UL transmission
else
{
UE_sched_ctrl_info->R_ul_data=UE_template_temp->R_ul;
}
ue_id = UE_template_temp->next;
}
//sort all UE regardless DL or UL UEs
sort_UEs_uss();
ue_id = mac_inst->UE_list_spec[UE_list_index].head;
//Resource scheduling algorithm
while(ue_id>-1)
{
UE_template_temp = &(mac_inst->UE_list_spec[UE_list_index].UE_template_NB_IoT[ue_id]);
UE_sched_ctrl_info = &(mac_inst->UE_list_spec[UE_list_index].UE_sched_ctrl_NB_IoT[ue_id]);
// UE not finish RA or finish transmission
if(UE_template_temp->RRC_connected!=1)
{
LOG_D(MAC,"[%04d][preprocessor_uss_NB_IoT][UE%d] rrc not connected\n", mac_inst->current_subframe, UE_template_temp->rnti);
}
// Finish RA
else
{
//DEBUG("[%04d][preprocessor_uss_NB_IoT][UE%d] ", mac_inst->current_subframe, UE_template_temp->rnti);
//DEBUG("[%04d][preprocessor_uss_NB_IoT][UE%d] Start scheduling\n", mac_inst->current_subframe, UE_template_temp->rnti);
switch(UE_template_temp->direction)
{
case 1: // Downlink resource allocation algorithm
LOG_D(MAC,"uss downlink scheduling.. \n");
//schedule_DL_NB_IoT(0, mac_inst, UE_template_temp, hypersfn, frame, subframe);
if(0==schedule_DL_NB_IoT(0, mac_inst, UE_template_temp, hypersfn, frame, subframe, UE_sched_ctrl_info))
{
LOG_D(MAC,"[%04d][preprocessor_uss_NB_IoT][UE%d] DL scheduling USS is successful\n", mac_inst->current_subframe, UE_template_temp->rnti);
UE_sched_ctrl_info->flag_schedule_success=1;
}
else
{
LOG_D(MAC,"[%04d][preprocessor_uss_NB_IoT][UE%d] DL scheduling USS is failed\n", mac_inst->current_subframe, UE_template_temp->rnti);
}
break;
case 0: // Uplink resource allocation algorithm
LOG_D(MAC,"uss uplink scheduling.. \n");
if(0==schedule_UL_NB_IoT(mac_inst, UE_template_temp, subframe, frame, hypersfn, UE_sched_ctrl_info))
{
LOG_D(MAC,"[%04d][preprocessor_uss_NB_IoT][UE%d] UL scheduling USS is successful\n", mac_inst->current_subframe, UE_template_temp->rnti);
UE_sched_ctrl_info->flag_schedule_success=1;
}
else
{
LOG_D(MAC,"[%04d][preprocessor_uss_NB_IoT][UE%d] UL scheduling USS is failed\n", mac_inst->current_subframe, UE_template_temp->rnti);
}
break;
//schedule_UL_NB_IoT(mac_inst, UE_template_temp, subframe, frame, hypersfn);
break;
case -1: // Idle state, no data wait to send
//sDEBUG("current idle.. \n");
default:
break;
}
}
ue_id = UE_template_temp->next;
}
}
void sort_UEs_uss()
{
//loop all UE
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,154 @@
/*! \file eNB_scheduler_bch_NB_IoT.c
* \brief schedule functions for SIBs transmission in NB-IoT
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
#include "defs_NB_IoT.h"
#include "proto_NB_IoT.h"
#include "extern_NB_IoT.h"
#include "openair2/RRC/NBIOT/proto_NB_IoT.h"
char str[6][7] = { "SIBs_1", "SIBs_2", "SIBs_3", "SIBs_4", "SIBs_5", "SIBs_6" };
#define num_flags 2
extern int extend_space[num_flags];
extern int extend_alpha_offset[num_flags];
uint32_t get_SIB23_size(void)
{
rrc_config_NB_IoT_t *mac_config = &mac_inst->rrc_config;
uint32_t size_SIB23_in_MAC = 0;
switch(mac_config->sibs_NB_IoT_sched[0].si_tb)
{
case si_TB_56:
size_SIB23_in_MAC = 56;
break;
case si_TB_120:
size_SIB23_in_MAC = 120;
break;
case si_TB_208:
size_SIB23_in_MAC = 208;
break;
case si_TB_256:
size_SIB23_in_MAC = 256;
break;
case si_TB_328:
size_SIB23_in_MAC = 328;
break;
case si_TB_440:
size_SIB23_in_MAC = 440;
break;
case si_TB_552:
size_SIB23_in_MAC = 552;
break;
case si_TB_680:
size_SIB23_in_MAC = 680;
break;
default:
LOG_E(MAC,"No index for SIB23 size from SIB1!\n");
break;
}
return size_SIB23_in_MAC;
}
void schedule_sibs(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t sibs_order, int start_subframe1){
available_resource_DL_t *pt[8] = { (available_resource_DL_t *)0 };
int first_subframe[8] = { -1 };
//uint32_t end_subframe[8] = { -1 };
schedule_result_t *new_node;
DCIFormatN1_t *sibs_dci;
uint32_t j, i, k;
uint32_t SIB23_size = 0;
uint8_t *SIB23_pdu = get_NB_IoT_SIB23();
int residual_subframe, num_subframe, last_subframe;
uint8_t num_subframe_per_SIB = 0;
SIB23_size = get_SIB23_size();
if(SIB23_size > 0 && SIB23_size <= 120)
num_subframe_per_SIB = 2;
else if(SIB23_size > 120 && SIB23_size <= 680)
num_subframe_per_SIB = 8;
else
LOG_E(MAC,"Invalid SIB size\n");
num_subframe = num_subframe_per_SIB *4;
int rmax = mac_inst->rrc_config.mac_NPRACH_ConfigSIB[0].mac_npdcch_NumRepetitions_RA_NB_IoT;
rmax = (rmax * 10) >> 3; // x1.25
for(k=0, i=start_subframe1; i<(start_subframe1+mac_inst->rrc_config.si_window_length); i+=si_repetition_pattern[mac_inst->rrc_config.sibs_NB_IoT_sched[sibs_order].si_repetition_pattern], ++k){
LOG_D(MAC,"[debug][sibs%d] subframe: %d, check %d", sibs_order, i, num_subframe);
LOG_D(MAC,"[%d][%d][%d] [%d][%d]\n", i, start_subframe1, mac_inst->rrc_config.si_window_length, sibs_order, si_repetition_pattern[mac_inst->rrc_config.sibs_NB_IoT_sched[sibs_order].si_repetition_pattern]);
//system("pause");
#if 0 //disable new feature
// avoid to occupied others searching space. TODO: css, uss connect with configuration module
// start start+rmax
// i i+9
int continue_flag=0;
for(l=0; l<num_flags; ++l){
if((extend_space[l]>>extend_alpha_offset[l] <= i%extend_space[l] && ((extend_space[l]>>extend_alpha_offset[l])+rmax) >= i%extend_space[l]) ||
(extend_space[l]>>extend_alpha_offset[l] <= (i+9)%extend_space[l] && ((extend_space[l]>>extend_alpha_offset[l])+rmax) >= (i+9)%extend_space[l])){
continue_flag = 1;
}
}
if(continue_flag == 1)
continue;
#endif
pt[k] = (available_resource_DL_t *)check_sibs_resource(mac_inst, i, i+9, num_subframe, &residual_subframe, &last_subframe, &first_subframe[k]);
num_subframe = residual_subframe;
LOG_D(MAC,"-- rest: %d, last: %d start: %d\n", num_subframe, last_subframe, start_subframe1);
if(0==residual_subframe){LOG_D(MAC,"output\n\n");
sibs_dci = (DCIFormatN1_t *)malloc(sizeof(DCIFormatN1_t));
sibs_dci->type = 1;
sibs_dci->orderIndicator = 0;
sibs_dci->Scheddly = 0;
sibs_dci->ResAssign = 8;
sibs_dci->mcs = 2;
sibs_dci->RepNum = 0;
sibs_dci->ndi = 0;
sibs_dci->HARQackRes = 0;
sibs_dci->DCIRep = 0;
for(k=0, j=start_subframe1;j<=i;++k, j+=si_repetition_pattern[mac_inst->rrc_config.sibs_NB_IoT_sched[sibs_order].si_repetition_pattern]){
LOG_D(MAC,"for1 k=%d j=%d i=%d rep=%d\n", k, j, i, si_repetition_pattern[mac_inst->rrc_config.sibs_NB_IoT_sched[sibs_order].si_repetition_pattern]);
if((available_resource_DL_t *)0 != pt[k]){
new_node = (schedule_result_t *)malloc(sizeof(schedule_result_t));
// fill new node
new_node->output_subframe = first_subframe[k];
new_node->end_subframe = (j==i)?last_subframe:j+9;
new_node->sdu_length = SIB23_size;
new_node->DLSCH_pdu = SIB23_pdu;
new_node->direction = DL;
new_node->DCI_release = (j==i);
new_node->channel = NPDSCH;
new_node->rnti = 65535;
new_node->rnti_type = 1;
new_node->npusch_format = 0; // useless
new_node->R_harq = 0; // useless
new_node->next = (schedule_result_t *)0;
new_node->DCI_pdu = (void *)sibs_dci;
//new_node->debug_str = str[sibs_order];
LOG_D(MAC,"debug: pt[k]->start_subframe:%d output_subframe:%d end_subframe:%d rep:%d\n", pt[k]->start_subframe, first_subframe[k], (j==i)?last_subframe:j+9,si_repetition_pattern[mac_inst->rrc_config.sibs_NB_IoT_sched[sibs_order].si_repetition_pattern]);
fill_resource_DL(mac_inst, pt[k], first_subframe[k], (j==i)?last_subframe:j+9, new_node);
LOG_D(MAC,"for*2\n");
}
LOG_D(MAC,"for2\n");
}
return ;
}
}
return ;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,383 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file eNB_scheduler_ulsch_NB_IoT.c
* \brief handle UL UE-specific scheduling
* \author NTUST BMW Lab./Nick HO
* \date 2017 - 2018
* \email: nick133371@gmail.com
* \version 1.0
*
*/
#include "defs_NB_IoT.h"
#include "proto_NB_IoT.h"
#include "extern_NB_IoT.h"
#include "RRC/NBIOT/proto_NB_IoT.h"
//#include "RRC/NBIOT/extern.h"
//#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
unsigned char str20[] = "DCI_uss";
unsigned char str21[] = "DATA_uss";
// scheduling UL
int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info,uint32_t subframe, uint32_t frame, uint32_t H_SFN, UE_SCHED_CTRL_NB_IoT_t *UE_sched_ctrl_info){
int i,ndi = 0,check_DCI_result = 0,check_UL_result = 0,candidate;
uint32_t DL_end;
//Scheduling resource temp buffer
sched_temp_DL_NB_IoT_t *NPDCCH_info = (sched_temp_DL_NB_IoT_t*)malloc(sizeof(sched_temp_DL_NB_IoT_t));
candidate = UE_info->R_max/UE_sched_ctrl_info->R_dci;
uint32_t mcs = max_mcs[UE_info->multi_tone];
uint32_t mappedMcsIndex=UE_info->PHR+(4 * UE_info->multi_tone);
int TBS = 0;
int Iru = 0, Nru, I_rep,N_rep,total_ru;
int dly = 0,uplink_time = 0;
if(UE_info->ul_total_buffer<=0)
{
LOG_D(MAC,"[%04d][ULSchedulerUSS][UE:%05d] No UL data in buffer\n", mac_inst->current_subframe, UE_info->rnti);
return -1;
}
TBS=get_TBS_UL_NB_IoT(mcs,UE_info->multi_tone,Iru);
LOG_D(MAC,"Initial TBS : %d UL_buffer: %d\n", TBS, UE_info->ul_total_buffer);
sched_temp_UL_NB_IoT_t *NPUSCH_info = (sched_temp_UL_NB_IoT_t*)malloc(sizeof(sched_temp_UL_NB_IoT_t));
//DCIFormatN0_t *DCI_N0 = (DCIFormatN0_t*)malloc(sizeof(DCIFormatN0_t));
//available_resource_DL_t *node;
// setting of the NDI
/*
if(UE_info->HARQ_round == 0)
{
ndi = 1-UE_info->oldNDI_UL;
UE_info->oldNDI_UL=ndi;
}
*/
ndi = 1;
for (i = 0; i < candidate; i++)
{
/*step 1 : Check DL resource is available for DCI N0 or not*/
check_DCI_result = check_resource_NPDCCH_NB_IoT(mac_inst,H_SFN, frame, subframe, NPDCCH_info, i, UE_sched_ctrl_info->R_dci);
//node = check_resource_DL(mac_inst,);
//just use to check when there is no DL function
//NPDCCH_info->sf_start = H_SFN*10240+frame*10 +subframe + i * UE_sched_ctrl_info->R_dci;
//NPDCCH_info->sf_end = NPDCCH_info->sf_start + (i+1) * UE_sched_ctrl_info->R_dci;
//LOG_D(MAC,"UE : %5d, NPDCCH result: %d ,NPDCCH start: %d,NPDCCH end : %d\n",UE_info->rnti,check_DCI_result,NPDCCH_info->sf_start,NPDCCH_info->sf_end);
if( check_DCI_result != -1)
{
/*step 2 : Determine MCS / TBS / REP / RU number*/
/*while((mapped_mcs[UE_info->CE_level][mappedMcsIndex]< mcs)||((TBS>UE_info->ul_total_buffer)&&(mcs>=0)))
{
--mcs;
TBS=get_TBS_UL_NB_IoT(mcs,UE_info->multi_tone,Iru);
}*/
mcs = mapped_mcs[UE_info->CE_level][mappedMcsIndex];
//mcs = 2;
while((TBS<UE_info->ul_total_buffer)&&(Iru<=7))
{
Iru++;
TBS=get_TBS_UL_NB_IoT(mcs,UE_info->multi_tone,Iru);
}
//LOG_D(MAC,"TBS : %d MCS %d I_RU %d\n", TBS, UE_info->ul_total_buffer, mcs, Iru);
Nru = RU_table[Iru];
DL_end = NPDCCH_info->sf_end;
N_rep = get_N_REP(UE_info->CE_level);
I_rep = get_I_REP(N_rep);
total_ru = Nru * N_rep;
LOG_D(MAC,"[%04d][ULSchedulerUSS][UE:%05d] Multi-tone:%d,MCS:%d,TBS:%d,UL_buffer:%d,DL_start:%d,DL_end:%d,N_rep:%d,N_ru:%d,Total_ru:%d,Iru:%d\n", mac_inst->current_subframe,UE_info->rnti,UE_info->multi_tone,mcs,TBS,UE_info->ul_total_buffer,NPDCCH_info->sf_start,DL_end,N_rep,Nru,total_ru,Iru);
/*step 3 Check UL resource for Uplink data*/
// we will loop the scheduling delay here
for(dly=0;dly<4;dly++)
{
uplink_time = DL_end +scheduling_delay[dly]+1;
check_UL_result = Check_UL_resource(uplink_time,total_ru, NPUSCH_info, UE_info->multi_tone, 0);
if (check_UL_result != -1)
{
//LOG_D(MAC,"[%04d][UL scheduler][UE:%05d] DCI content = scind : %d ResAssign : %d mcs : %d ndi : %d scheddly : %d RepNum : %d rv : %d DCIRep : %d\n", mac_inst->current_subframe,UE_info->rnti,DCI_N0->scind,DCI_N0->ResAssign,DCI_N0->mcs,DCI_N0->ndi,DCI_N0->Scheddly,DCI_N0->RepNum,DCI_N0->rv,DCI_N0->DCIRep);
LOG_D(MAC,"[%04d][ULSchedulerUSS][%d][Success] complete scheduling with data size %d\n", mac_inst->current_subframe, UE_info->rnti, UE_info->ul_total_buffer);
LOG_I(MAC,"[%04d][ULSchedulerUSS][%d] Multi-tone:%d,MCS:%d,TBS:%d,UL_buffer:%d,DL_start:%d,DL_end:%d,N_rep:%d,N_ru:%d,Total_ru:%d\n", mac_inst->current_subframe,UE_info->rnti,UE_info->multi_tone,mcs,TBS,UE_info->ul_total_buffer,NPDCCH_info->sf_start,DL_end,N_rep,Nru,total_ru);
//LOG_D(MAC,"[%04d][ULSchedulerUSS][%d][Success] DCI content = scind : %d ResAssign : %d mcs : %d ndi : %d scheddly : %d RepNum : %d rv : %d DCIRep : %d\n", mac_inst->current_subframe, UE_info->rnti, DCI_N0->scind,DCI_N0->ResAssign,DCI_N0->mcs,DCI_N0->ndi,DCI_N0->Scheddly,DCI_N0->RepNum,DCI_N0->rv,DCI_N0->DCIRep);
// step 5 resource allocation and generate scheduling result
LOG_D(MAC,"[%04d][ULSchedulerUSS][UE:%05d] Generate result\n", mac_inst->current_subframe, UE_info->rnti);
//generate_scheduling_result_UL(NPDCCH_info->sf_start, NPDCCH_info->sf_end,NPUSCH_info->sf_start, NPUSCH_info->sf_end,DCI_N0,UE_info->rnti, str20, str21);
LOG_D(MAC,"[%04d][ULSchedulerUSS][UE:%05d] Maintain resource\n", mac_inst->current_subframe, UE_info->rnti);
//fill_resource_DL();
maintain_resource_DL(mac_inst,NPDCCH_info,NULL);
adjust_UL_resource_list(NPUSCH_info);
/*
//Change the UE state to idle
UE_info->direction = -1;
return 0;
*/
//Fill result to Output structure
UE_sched_ctrl_info->NPDCCH_sf_end=NPDCCH_info->sf_end;
UE_sched_ctrl_info->NPDCCH_sf_start=NPDCCH_info->sf_start;
UE_sched_ctrl_info->NPUSCH_sf_end=NPUSCH_info->sf_end;
UE_sched_ctrl_info->NPUSCH_sf_start=NPUSCH_info->sf_start;
UE_sched_ctrl_info->TBS=TBS;
UE_sched_ctrl_info->dci_n0_index_mcs=mcs;
UE_sched_ctrl_info->index_tbs=mcs;
UE_sched_ctrl_info->dci_n0_index_ru=Iru;
UE_sched_ctrl_info->dci_n0_n_ru=Nru;
UE_sched_ctrl_info->dci_n0_index_delay=dly;
UE_sched_ctrl_info->dci_n0_index_subcarrier=NPUSCH_info->subcarrier_indication;
UE_sched_ctrl_info->dci_n0_index_ndi=ndi;
//UE_sched_ctrl_info->dci_n0_index_R_dci=get_DCI_REP(UE_sched_ctrl_info->R_dci->R_dci,UE_info->R_max);
UE_sched_ctrl_info->dci_n0_index_R_data=I_rep;
LOG_D(MAC,"[%04d][ULSchedulerUSS][%d][Success] Finish UL USS scheduling \n", mac_inst->current_subframe, UE_info->rnti);
return 0;
}
}
}
/*break now, we only loop one candidiate*/
//break;
}
//----Daniel
UE_sched_ctrl_info->flag_schedule_success=0;
//----Daniel
LOG_D(MAC,"[%04d][ULSchedulerUSS][%d][Fail] UL scheduling USS fail\n", mac_inst->current_subframe, UE_info->rnti);
LOG_D(MAC,"[%04d][UL scheduler][UE:%05d] there is no available UL resource\n", mac_inst->current_subframe, UE_info->rnti);
return -1;
}
void rx_sdu_NB_IoT(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t subframe, uint16_t rnti, uint8_t *sdu, uint16_t length)
{
unsigned char rx_ces[5], num_ce = 0, num_sdu = 0, *payload_ptr, i; // MAX Control element
unsigned char rx_lcids[5];//for NB_IoT-IoT, NB_IoT_RB_MAX should be fixed to 5 (2 DRB+ 3SRB)
unsigned short rx_lengths[5];
int UE_id = 0;
int BSR_index=0;
int DVI_index = 0;
int PHR = 0;
int ul_total_buffer = 0;
//mac_NB_IoT_t *mac_inst;
UE_TEMPLATE_NB_IoT *UE_info;
uint8_t* msg4_rrc_pdu = NULL;
LOG_D(MAC,"RX_SDU_IN\n");
uint8_t* first_6 = (uint8_t*) malloc(6*sizeof(uint8_t));
for(int a = 0; a<6;a++)
first_6[a]=sdu[a+2];
// note: if lcid < 25 this is sdu, otherwise this is CE
payload_ptr = parse_ulsch_header_NB_IoT(sdu, &num_ce, &num_sdu,rx_ces, rx_lcids, rx_lengths, length);
LOG_I(MAC,"num_CE= %d, num_sdu= %d, rx_ces[0] = %d, rx_lcids = %d, rx_lengths[0] = %d, length = %d\n",num_ce,num_sdu,rx_ces[0],rx_lcids[0],rx_lengths[0],length);
for (i = 0; i < num_ce; i++)
{
switch(rx_ces[i])
{
case CRNTI:
// find UE id again, confirm the UE, intial some ue specific parameters
payload_ptr+=2;
break;
case SHORT_BSR:
// update BSR here
LOG_I(MAC,"Update BSR, rnti : %d\n",rnti);
UE_info = get_ue_from_rnti(mac_inst, rnti);
BSR_index = payload_ptr[0] & 0x3f;
if(UE_info != NULL)
{
LOG_I(MAC,"Find UE in CE 2 list, update ul_total_buffer to %d bytes\n",BSR_table[BSR_index]);
UE_info->ul_total_buffer = BSR_table[BSR_index];
}
else
LOG_E(MAC,"UE info empty\n");
payload_ptr+=1;
break;
default:
LOG_D(MAC,"Received unknown MAC header (0x%02x)\n", rx_ces[i]);
break;
}
}
for (i = 0; i < num_sdu; i++)
{
switch(rx_lcids[i])
{
case CCCH_NB_IoT:
// MSG3 content: |R|R|PHR|PHR|DVI|DVI|DVI|DVI|CCCH payload
PHR = ((payload_ptr[0] >> 5) & 0x01)*2+((payload_ptr[0]>>4) & 0x01);
DVI_index = (payload_ptr[0] >>3 & 0x01)*8+ (payload_ptr[0] >>2 & 0x01)*4 + (payload_ptr[0] >>1 & 0x01)*2 +(payload_ptr[0] >>0 & 0x01);
ul_total_buffer = DV_table[DVI_index];
LOG_D(MAC,"PHR = %d, ul_total_buffer = %d\n",PHR,ul_total_buffer);
// go to payload
payload_ptr+=1;
// Note that the first 6 byte (48 bits) of this CCCH SDU should be encoded in the MSG4 for contention resolution
/*printf("CCCH SDU content: ");
for(int a = 0; a<9;a++)
printf("%02x ",payload_ptr[a]);
printf("\n");*/
rx_lengths[i]-=1;
mac_rrc_data_ind(
module_id,
CC_id,
frame,subframe,
UE_id,
rnti,
CCCH,
(uint8_t*)payload_ptr,
rx_lengths[i],
0,
0);
LOG_D(MAC,"rx_lengths : %d\n", rx_lengths[i]);
msg4_rrc_pdu = mac_rrc_msg3_ind_NB_IoT(payload_ptr,rnti,rx_lengths[i]);
receive_msg3_NB_IoT(mac_inst,rnti,PHR,ul_total_buffer,first_6,msg4_rrc_pdu);
LOG_I(MAC,"Contention resolution ID = %02x %02x %02x %02x %02x %02x\n",first_6[0],first_6[1],first_6[2],first_6[3],first_6[4],first_6[5]);
//NB_IoT_mac_rrc_data_ind(payload_ptr,mac_inst,rnti);
//NB_IoT_receive_msg3(mac_inst,rnti,PHR,ul_total_buffer);
break;
case DCCH0_NB_IoT:
case DCCH1_NB_IoT:
LOG_I(MAC,"DCCH PDU Here\n");
mac_rlc_data_ind(
module_id,
rnti,
module_id,
frame,
1,
0,
rx_lcids[i],
//1,/* change channel_id equals 1 (SRB) */
(char *)payload_ptr,
rx_lengths[i],
1,
NULL);//(unsigned int*)crc_status);
// UE specific here
//NB_IoT_mac_rlc_data_ind(payload_ptr,mac_inst,rnti);
break;
// all the DRBS
case DTCH0_NB_IoT:
default:
//NB_IoT_mac_rlc_data_ind(payload_ptr,mac_inst,rnti);
break;
}
payload_ptr+=rx_lengths[i];
}
}
uint8_t *parse_ulsch_header_NB_IoT( uint8_t *mac_header,
uint8_t *num_ce,
uint8_t *num_sdu,
uint8_t *rx_ces,
uint8_t *rx_lcids,
uint16_t *rx_lengths,
uint16_t tb_length ){
uint8_t not_done=1, num_ces=0, num_sdus=0, lcid,num_sdu_cnt;
uint8_t *mac_header_ptr = mac_header;
uint16_t length, ce_len=0;
while(not_done==1){
if(((SCH_SUBHEADER_FIXED_NB_IoT*)mac_header_ptr)->E == 0){
not_done = 0;
}
lcid = ((SCH_SUBHEADER_FIXED_NB_IoT*)mac_header_ptr)->LCID;
if(lcid < EXTENDED_POWER_HEADROOM){
if (not_done==0) { // last MAC SDU, length is implicit
mac_header_ptr++;
length = tb_length-(mac_header_ptr-mac_header)-ce_len;
for(num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++){
length -= rx_lengths[num_sdu_cnt];
}
}else{
if(((SCH_SUBHEADER_SHORT_NB_IoT *)mac_header_ptr)->F == 0){
length = ((SCH_SUBHEADER_SHORT_NB_IoT *)mac_header_ptr)->L;
mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT);
}else{ // F = 1
length = ((((SCH_SUBHEADER_LONG_NB_IoT *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG_NB_IoT *)mac_header_ptr)->L_LSB & 0xff);
mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG);
}
}
rx_lcids[num_sdus] = lcid;
rx_lengths[num_sdus] = length;
num_sdus++;
}else{ // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
if(lcid == SHORT_PADDING){
mac_header_ptr++;
}else{
rx_ces[num_ces] = lcid;
num_ces++;
mac_header_ptr++;
if(lcid==LONG_BSR){
ce_len+=3;
}else if(lcid==CRNTI){
ce_len+=2;
}else if((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
ce_len++;
}else{
// wrong lcid
}
}
}
}
*num_ce = num_ces;
*num_sdu = num_sdus;
return(mac_header_ptr);
}
void fill_DCI_N0(DCIFormatN0_t *DCI_N0, UE_TEMPLATE_NB_IoT *UE_info, UE_SCHED_CTRL_NB_IoT_t *UE_sched_ctrl_info)
{
DCI_N0->type = 0;
DCI_N0->scind = UE_sched_ctrl_info->dci_n0_index_subcarrier;
DCI_N0->ResAssign = UE_sched_ctrl_info->dci_n0_index_ru;
DCI_N0->mcs = UE_sched_ctrl_info->dci_n0_index_mcs;
DCI_N0->ndi = UE_sched_ctrl_info->dci_n0_index_ndi;
DCI_N0->Scheddly = UE_sched_ctrl_info->dci_n0_index_delay;
DCI_N0->RepNum = UE_sched_ctrl_info->dci_n0_index_R_data;
DCI_N0->rv = (UE_info->HARQ_round%2==0)?0:1; // rv will loop 0 & 2
DCI_N0->DCIRep = get_DCI_REP(UE_sched_ctrl_info->R_dci,UE_info->R_max);
//DCI_N0->DCIRep = UE_sched_ctrl_info->dci_n0_index_R_dci;
LOG_I(MAC,"[fill_DCI_N0] Type %d scind %d I_ru %d I_mcs %d ndi %d I_delay %d I_rep %d RV %d I_dci %d\n", DCI_N0->type, DCI_N0->scind, DCI_N0->ResAssign, DCI_N0->mcs, DCI_N0->ndi, DCI_N0->Scheddly, DCI_N0->RepNum, DCI_N0->rv, DCI_N0->DCIRep);
}

View File

@@ -0,0 +1,121 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file extern_NB_IoT.h
* \brief MAC extern
* \author NTUST BMW Lab./Nick HO, Xavier LIU, Calvin HSU
* \date 2017 - 2018
* \email: nick133371@gmail.com, sephiroth7277@gmail.com , kai-hsiang.hsu@eurecom.fr
* \version 1.0
*
*/
#ifndef __MAC_EXTERN_NB_IOT_H__
#define __MAC_EXTERN_NB_IOT_H__
//#include "openair2/PHY_INTERFACE/defs_NB_IoT.h"
#include "defs_NB_IoT.h"
extern uint8_t Is_rrc_registered;
#ifndef PHY_EMUL
#ifndef PHYSIM
#define NB_INST 1
#else
extern unsigned char NB_INST;
#endif
extern unsigned char NB_eNB_INST;
extern uint16_t NB_UE_INST;
extern unsigned char NB_RN_INST;
extern unsigned short NODE_ID[1];
extern void* bigphys_malloc(int);
#else
extern EMULATION_VARS *Emul_vars;
#endif //PHY_EMUL
//NB-IoT---------------------------------
extern eNB_MAC_INST_NB_IoT *mac_inst;
extern uint8_t Is_rrc_registered_NB_IoT;
extern available_resource_DL_t *available_resource_DL;
extern available_resource_tones_UL_t *available_resource_UL;
extern available_resource_DL_t *available_resource_DL_last;
extern schedule_result_t *schedule_result_list_UL;
extern schedule_result_t *schedule_result_list_DL;
// array will be active when they are used
// 10 -> single-tone / 12 -> multi-tone
extern const uint32_t max_mcs[2];
// [CE level] [0 - 3] -> single-tone / [CE level] [4-7] -> multi-tone
extern const uint32_t mapped_mcs[3][8];
//TBS table for NPUSCH transmission TS 36.213 v14.2 table Table 16.5.1.2-2:
extern const int UL_TBS_Table[14][8];
const int UL_TBS_Table_msg3[8];
extern const int ULrep[8];
extern const int rachperiod[8];
extern const int rachstart[8];
extern const int rachrepeat[8];
extern const int rachscofst[7];
extern const int rachnumsc[4];
extern const int rmax[12];
extern const double gvalue[8];
extern const double pdcchoffset[4];
extern const uint32_t RU_table[8];
extern const uint32_t RU_table_msg3[8];
extern const uint32_t scheduling_delay[4];
extern const uint32_t msg3_scheduling_delay_table[4];
extern const uint32_t ack_nack_delay[4];
extern const uint32_t R_dl_table[16];
// TBS table for the case not containing SIB1-NB_IoT, Table 16.4.1.5.1-1 in TS 36.213 v14.2
extern const uint32_t MAC_TBStable_NB_IoT[14][8];
//TBS table for the case containing S1B1-NB_IoT, Table 16.4.1.5.2-1 in TS 36.213 v14.2 (Itbs = 12 ~ 15 is reserved field
//mapping ITBS to SIB1-NB_IoT
extern const unsigned int MAC_TBStable_NB_IoT_SIB1[16];
extern const int DV_table[16];
extern const int BSR_table[64];
extern const int dl_rep[3];
extern const uint32_t dci_rep[3];
extern const uint32_t harq_rep[3];
//SIBs
extern int extend_space[2];
extern int extend_alpha_offset[2];
extern const int si_repetition_pattern[4];
#endif //DEF_H

View File

@@ -0,0 +1,232 @@
/*! \file main_NB_IoT.c
* \brief top init of Layer 2
* \author NTUST BMW LAB./
* \date 2017
* \version 1.0
* \email:
*/
//#include "asn1_constants.h"
#include "LAYER2/MAC/defs_NB_IoT.h"
#include "LAYER2/MAC/proto_NB_IoT.h"
#include "LAYER2/MAC/extern_NB_IoT.h"
#include "vars_NB_IoT.h"
#include "RRC/NBIOT/proto_NB_IoT.h"
#define NUM_USS_PP 3
#define USER_NUM_USS 10
int mac_init_global_param_NB_IoT(void)
{
///// removed since already called by mac_init_global_param //////////////
/*
if (rlc_module_init()!=0) {
return(-1);
}
*/
/////////////////////////////////////////////////////////////////////////////
// LOG_I(MAC,"[MAIN] RRC NB-IoT initialization of global params\n");
// rrc_init_global_param_NB_IoT();
///// removed since already called by mac_init_global_param //////////////
/*
LOG_I(MAC,"[MAIN] PDCP layer init\n");
#ifdef USER_MODE
pdcp_layer_init ();
#else
pdcp_module_init ();
#endif
*/
////////////////////////////////////////////////////////////////////////
return 0;
}
// Initial function of the intialization for NB-IoT MAC
void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst)
{
int32_t i, j, k;
LOG_I(MAC,"[NB-IoT] MAC start initialization\n");
mac_inst->current_subframe = 0;
for(i=0;i<64;++i)
{
mac_inst->sib1_flag[i] = 0;
mac_inst->sib1_count[i] = 0;
}
init_tool_sib1(mac_inst);
// output handler
// RA
mac_inst->RA_msg2_list.head = (RA_TEMPLATE_NB_IoT *)0;
mac_inst->RA_msg3_list.head = (RA_TEMPLATE_NB_IoT *)0;
mac_inst->RA_msg4_list.head = (RA_TEMPLATE_NB_IoT *)0;
mac_inst->RA_msg2_list.tail = (RA_TEMPLATE_NB_IoT *)0;
mac_inst->RA_msg3_list.tail = (RA_TEMPLATE_NB_IoT *)0;
mac_inst->RA_msg4_list.tail = (RA_TEMPLATE_NB_IoT *)0;
sib1_NB_IoT_sched_t *config = &mac_inst->rrc_config.sib1_NB_IoT_sched_config;
// DLSF Table
init_dlsf_info(mac_inst, &DLSF_information);
// init sib1 tool
//int repetition_pattern = 1;// 1:every2frame, 2:every4frame, 3:every8frame, 4:every16frame
for(i=0;i<8;++i){
mac_inst->sib1_flag[(i<<1)+config->starting_rf] = 1;
}
for(i=0, j=0;i<64;++i){
if(mac_inst->sib1_flag[i]==1){
++j;
}
mac_inst->sib1_count[i]=j;
}
//printf("%d", mac_inst->sib1_period);
for(i=0, j=0;i<640;++i){
//printf("*%d", i);
if(is_dlsf(mac_inst, i)){
++j;
}
//printf("-");
if(i%10==9){
mac_inst->dlsf_table[i/10] = j;
}
}
for(i=0;i<256;++i){
mac_inst->sibs_table[i] = -1;
}
mac_inst->rrc_config.si_window_length = ms160;
mac_inst->rrc_config.sibs_NB_IoT_sched[0].si_periodicity = rf64;
mac_inst->rrc_config.si_radio_frame_offset = 1;
for(j=0;j<6;++j){
if(0x0 != mac_inst->rrc_config.sibs_NB_IoT_sched[j].sib_mapping_info){
k = mac_inst->rrc_config.sibs_NB_IoT_sched[j].si_periodicity / mac_inst->rrc_config.si_window_length;
for(i=0;i<(256/k);++i){
mac_inst->sibs_table[(i*k)+j] = j;
}
}
}
mac_inst->schedule_subframe_DL = 0;
//mac_inst->schedule_subframe_UL = 0;
available_resource_DL = available_resource_DL_last = (available_resource_DL_t *)0;
// init downlink list 0-100
init_dl_list(mac_inst);
for(i=0; i<MAX_NUMBER_OF_UE_MAX_NB_IoT; ++i){
mac_inst->RA_template[i].active = 0;
mac_inst->RA_template[i].msg3_retransmit_count = 0;
mac_inst->RA_template[i].msg4_retransmit_count = 0;
mac_inst->RA_template[i].ta = 0;
mac_inst->RA_template[i].preamble_index = 0;
mac_inst->RA_template[i].ue_rnti = 0x0;
mac_inst->RA_template[i].ra_rnti = 0x0;
mac_inst->RA_template[i].next = (RA_TEMPLATE_NB_IoT *)0;
mac_inst->RA_template[i].prev = (RA_TEMPLATE_NB_IoT *)0;
mac_inst->RA_template[i].wait_msg4_ack = 0;
mac_inst->RA_template[i].wait_msg3_ack = 0;
}
//3 CE level USS list
mac_inst->UE_list_spec = (UE_list_NB_IoT_t*)malloc(NUM_USS_PP*sizeof(UE_list_NB_IoT_t));
//initial UE list
LOG_I(MAC,"[init_mac_NB_IoT] Initial UE list\n");
mac_inst->num_uss_list = NUM_USS_PP;
for(i=0;i<NUM_USS_PP;++i)
{
//rrc_mac_config_req(&mac_inst->rrc_config, 0, 0, 1, i);
(mac_inst->UE_list_spec+i)->head = -1;
(mac_inst->UE_list_spec+i)->tail = -1;
//(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.R_max = mac_inst->rrc_config.npdcch_ConfigDedicated[i].R_max;
//(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.G = mac_inst->rrc_config.npdcch_ConfigDedicated[i].G;
//(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.a_offset = mac_inst->rrc_config.npdcch_ConfigDedicated[i].a_offset;
(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.R_max = 16;
(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.G = 4;
(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.a_offset = 0;
(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.T = (uint32_t)((double)(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.R_max * (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.G);
(mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.ss_start_uss = (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.T * (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.a_offset;
//SCHEDULE_LOG("[init_mac_NB_IoT][CE%d] Rmax %d G %d, a_offset %d, PP %d search space start %d\n", i, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.R_max, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.G, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.a_offset, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.T, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.ss_start_uss);
for(j=0;j<MAX_NUMBER_OF_UE_MAX_NB_IoT;++j)
{
(mac_inst->UE_list_spec+i)->UE_template_NB_IoT[j].active=0;
(mac_inst->UE_list_spec+i)->UE_template_NB_IoT[j].RRC_connected=0;
(mac_inst->UE_list_spec+i)->UE_template_NB_IoT[j].direction = -1;
}
LOG_I(MAC,"[init_mac_NB_IoT] List_number %d R_max %d G %.1f a_offset %.1f T %d SS_start %d\n", i, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.R_max, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.G, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.a_offset, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.T, (mac_inst->UE_list_spec+i)->NPDCCH_config_dedicated.ss_start_uss);
}
//UL initial
//Setting nprach configuration
setting_nprach();
//Initialize uplink resource from nprach configuration
Initialize_Resource();
//add_UL_Resource(mac_inst);
extend_available_resource_DL(mac_inst, mac_inst->current_subframe + 1 + 160);
}
void mac_top_init_eNB_NB_IoT(void)
{
// can be an input of this function, but now fix to 0
module_id_t i = 0;
//UE_list_t *UE_list;
//eNB_MAC_INST_NB_IoT *mac;
int nb_inst_NB_IOT_MAC= 1;
LOG_I(MAC,"[NB-IoT MAIN] Init function start:nb_nbiot_macrlc_inst=%d\n",nb_inst_NB_IOT_MAC);
if (nb_inst_NB_IOT_MAC>0) {
// only one inst exit in legacy OAI
mac_inst->Mod_id = i;
// IF Module Initialization linking
mac_inst->if_inst_NB_IoT = IF_Module_init_NB_IoT(i);
mac_inst->if_inst_NB_IoT->PHY_config_req = PHY_config_req_NB_IoT;
mac_inst->if_inst_NB_IoT->schedule_response = schedule_response_NB_IoT;
//reserve for fapi structure initializati
} else {
mac_inst = NULL;
}
// for NB-IoT UE list initialization will be in init_mac_NB_IoT
}
int l2_init_eNB_NB_IoT(void)
{
LOG_I(MAC,"[MAIN] MAC_INIT_GLOBAL_PARAM NB-IoT IN...\n");
mac_inst = (eNB_MAC_INST_NB_IoT *) malloc (sizeof(eNB_MAC_INST_NB_IoT));
memset(mac_inst,0,sizeof(eNB_MAC_INST_NB_IoT));
Is_rrc_registered_NB_IoT=0;
mac_init_global_param_NB_IoT();
Is_rrc_registered_NB_IoT=1;
//init_mac_NB_IoT(mac_inst);
return(1);
}

View File

@@ -1,198 +1,258 @@
/*
* 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
*/
/*! \file LAYER2/MAC/proto_NB_IoT.h
* \brief MAC functions prototypes for eNB and UE
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \email navid.nikaein@eurecom.fr
* \version 1.0
*/
#ifndef __LAYER2_MAC_PROTO_NB_IoT_H__
#define __LAYER2_MAC_PROTO_NB_IoT_H__
#include "openair1/PHY/LTE_TRANSPORT/defs_NB_IoT.h"
#include "LAYER2/MAC/defs_NB_IoT.h"
#include "COMMON/platform_types.h"
#include "openair2/RRC/LTE/defs_NB_IoT.h"
/** \addtogroup _mac
* @{
*/
int l2_init_eNB_NB_IoT(void);
///config
void rrc_mac_config_req_NB_IoT(
module_id_t Mod_idP,
int CC_idP,
int rntiP,
rrc_eNB_carrier_data_NB_IoT_t *carrier,
SystemInformationBlockType1_NB_t *sib1_NB_IoT,
RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon,
PhysicalConfigDedicated_NB_r13_t *physicalConfigDedicated,
LogicalChannelConfig_NB_r13_t *logicalChannelConfig, //FIXME: decide how to use it
uint8_t ded_flag,
uint8_t ue_list_ded_num);
///system
void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst);
//void init_rrc_NB_IoT();
void release_mac_inst(uint8_t order);
eNB_MAC_INST_NB_IoT *get_mac_inst(uint8_t order);
uint8_t register_mac_inst(eNB_MAC_INST_NB_IoT *inst, uint8_t order);
///tool
void init_tool(sib1_NB_IoT_sched_t *config);
void UE_info_setting(UE_TEMPLATE_NB_IoT *UE_info);
UE_TEMPLATE_NB_IoT *get_ue_from_rnti(eNB_MAC_INST_NB_IoT *inst, rnti_t rnti);
///scheduler
void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe);
void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe);
//Calvin temp define self-tools
int init_debug(eNB_MAC_INST_NB_IoT *inst);
void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst);
void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe);
available_resource_DL_t *check_sibs_resource(eNB_MAC_INST_NB_IoT *mac_inst, int check_start_subframe, int check_end_subframe, int num_subframe, int *residual_subframe, int *out_last_subframe, int *out_first_subframe);
uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe);
void init(eNB_MAC_INST_NB_IoT *mac_inst);
void init_dl_list(eNB_MAC_INST_NB_IoT *mac_inst);
int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void fill_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, available_resource_DL_t *node, int start_subframe, int end_subframe, schedule_result_t *new_node);
available_resource_DL_t *check_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int check_subframe, int num_subframes, int *out_last_subframe, int *out_first_subframe);
void print_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst);
void print_schedule_result_DL(void);
void print_schedule_result_UL(void);
void add_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce, uint32_t PHR, uint32_t ul_total_buffer);
void remove_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce);
// SIBs
void schedule_sibs(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t sibs_order, int start_subframe);
//RA
void msg3_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti);
void msg4_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti);
void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst);
void init_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint8_t preamble_index, ce_level_t ce_level, uint32_t sfn_id, uint16_t ta);
void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void receive_msg3_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti, uint32_t phr, uint32_t ul_total_buffer);
void schedule_msg3_retransimission_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void fill_rar_NB_IoT(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template, uint8_t msg3_schedule_delay, uint8_t msg3_rep, sched_temp_UL_NB_IoT_t *schedule_template);
void receive_msg4_ack_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t rnti);
//USS
void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int index_ss);
//DATA
uint8_t *parse_ulsch_header( uint8_t *mac_header,
uint8_t *num_ce,
uint8_t *num_sdu,
uint8_t *rx_ces,
uint8_t *rx_lcids,
uint16_t *rx_lengths,
uint16_t tb_length );
/*******UL Scheduler**********/
void print_scheduling_result_UL(void);
void print_available_UL_resource(void);
/*set nprach configuration at intial time*/
void setting_nprach(void);
/*Uplink main scheduler*/
int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info, uint32_t subframe, uint32_t frame, uint32_t H_SFN);
/*Check available uplink resource list, if there is available uplink resource, return 0, otherwise, return 1*/
int Check_UL_resource(uint32_t DL_end, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int multi_tone, int fmt2_flag);
/*Get I Repetition number in DCI*/
int get_I_REP(int N_rep);
/*Get N REP from preamble repeat*/
int get_N_REP(int CE_level);
/*Get TBS from mcs, multi-tone, Iru*/
int get_TBS_UL_NB_IoT(uint32_t mcs,uint32_t multi_tone,int Iru);
/*get I tbs from mcs and multi-tone*/
int get_I_TBS_NB_IoT(int x,int y);
/*Get DCI REP from R max and R*/
int get_DCI_REP(uint32_t R,uint32_t R_max);
/*Check single tone resource list*/
int single_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int fmt2_flag);
/*Check multi tone resource list*/
int multi_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info);
/*Generate scheduling result of DCI N0 and Uplink config*/
void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subframe, uint32_t UL_subframe, uint32_t UL_end_subframe, DCIFormatN0_t *DCI_inst, rnti_t rnti, uint8_t *ul_debug_str, uint8_t *dl_debug_str);
/*Adjust UL resource by removing the used resource*/
void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info);
/*Initialize resource by nprach configuration*/
void Initialize_Resource(void);
/*Function to extend uplink resource grid*/
//void add_UL_Resource(eNB_MAC_INST_NB_IoT *mac_inst);
void add_UL_Resource(void);
/*Get ACK/NAK resource field*/
int get_resource_field_value(int subcarrier, int k0);
/*Get DL Repetition index*/
uint8_t get_index_Rep_dl(uint16_t R);
/*******DL Scheduler********/
void schedule_DL_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, UE_TEMPLATE_NB_IoT *UE_info, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start);
int check_resource_NPDCCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, sched_temp_DL_NB_IoT_t *NPDCCH_info, uint32_t cdd_num, uint32_t dci_rep);
int check_resource_NPDSCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDSCH_info, uint32_t sf_end, uint32_t I_delay, uint32_t R_max, uint32_t R_dl, uint32_t n_sf);
int check_resource_DL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, uint32_t dlsf_require, sched_temp_DL_NB_IoT_t *schedule_info);
uint32_t get_I_mcs(int CE_level);
uint32_t get_max_tbs(uint32_t I_tbs);
uint32_t get_tbs(uint32_t data_size, uint32_t I_tbs, uint32_t *I_sf);
uint32_t get_num_sf(uint32_t I_sf);
uint32_t get_scheduling_delay(uint32_t I_delay, uint32_t R_max);
uint32_t get_HARQ_delay(int subcarrier_spacing, uint32_t HARQ_delay_index);
//void generate_scheduling_result_DL(uint32_t DCI_subframe, uint32_t NPDSCH_subframe, uint32_t HARQ_subframe, DCIFormatN1_t *DCI, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu);
void generate_scheduling_result_DL(sched_temp_DL_NB_IoT_t* DCI_info, sched_temp_DL_NB_IoT_t* NPDSCH_info, sched_temp_UL_NB_IoT_t* HARQ_info, DCIFormatN1_t *DCI_inst, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu);
void fill_DCI_N1(DCIFormatN1_t *DCI_N1, UE_TEMPLATE_NB_IoT *UE_info, uint32_t scheddly, uint32_t I_sf, uint32_t I_harq);
//Transfrom source into hyperSF, Frame, Subframe format
void convert_system_number(uint32_t source_sf,uint32_t *hyperSF, uint32_t *frame, uint32_t *subframe);
//Trnasform hyperSF, Frame, Subframe format into subframe unit
uint32_t convert_system_number_sf(uint32_t hyperSF, uint32_t frame, uint32_t subframe);
/*input start position amd num_dlsf DL subframe, caculate the last subframe number*/
uint32_t cal_num_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF, uint32_t frame, uint32_t subframe, uint32_t* hyperSF_result, uint32_t* frame_result, uint32_t* subframe_result, uint32_t num_dlsf_require);
void init_dlsf_info(eNB_MAC_INST_NB_IoT *mac_inst, DLSF_INFO_t *DLSF_info);
uint32_t generate_dlsch_header_NB_IoT(uint8_t *pdu, uint32_t num_sdu, logical_chan_id_t *logical_channel, uint32_t *sdu_length, uint8_t flag_drx, uint8_t flag_ta, uint32_t TBS);
void maintain_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDCCH_info, sched_temp_DL_NB_IoT_t *NPDSCH_info);
void init_tool_sib1(eNB_MAC_INST_NB_IoT *mac_inst);
//int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
/**DL test , delete**/
available_resource_DL_t* new_dl_node(uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf);
void initialize_dl_resource(available_resource_DL_t *DL_Resource_node, uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf);
void insert_dl_resource(available_resource_DL_t *DL_Resource_node);
void insert_schedule_result(schedule_result_t **list, int subframe, schedule_result_t *node);
//interface with IF
uint8_t *parse_ulsch_header_NB_IoT( uint8_t *mac_header, uint8_t *num_ce, uint8_t *num_sdu, uint8_t *rx_ces, uint8_t *rx_lcids, uint16_t *rx_lengths, uint16_t tb_length);
void rx_sdu_NB_IoT(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t subframe, uint16_t rnti, uint8_t *sdu, uint16_t length);
int output_handler(eNB_MAC_INST_NB_IoT *mac_inst, module_id_t module_id, int CC_id, uint32_t hypersfn, uint32_t frame, uint32_t subframe, uint8_t MIB_flag, uint8_t SIB1_flag, uint32_t current_time);
// main
void mac_top_init_eNB_NB_IoT(void);
uint32_t to_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_CarrierFreq, float m_dl);
uint32_t from_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_earfcn, float m_dl);
int32_t get_uldl_offset_NB_IoT(int eutra_band);
#endif
/*
* 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
*/
/*! \file LAYER2/MAC/proto_NB_IoT.h
* \brief MAC functions prototypes for eNB and UE
* \author NTUST BMW Lab./Nick HO, Xavier LIU, Calvin HSU
* \date 2017 - 2018
* \email: nick133371@gmail.com, sephiroth7277@gmail.com , kai-hsiang.hsu@eurecom.fr
* \version 1.0
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \email navid.nikaein@eurecom.fr
* \version 1.0
*/
#ifndef __LAYER2_MAC_PROTO_NB_IoT_H__
#define __LAYER2_MAC_PROTO_NB_IoT_H__
#include "openair1/PHY/NBIoT_TRANSPORT/defs_NB_IoT.h"
#include "LAYER2/MAC/defs_NB_IoT.h"
#include "COMMON/platform_types.h"
#include "openair2/RRC/NBIOT/defs_NB_IoT.h"
/** \addtogroup _mac
* @{
*/
void initiate_ra_proc_NB_IoT(module_id_t module_idP,int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframe,uint8_t f_id);
void mac_top_init_eNB_NB_IoT(void);
int l2_init_eNB_NB_IoT(void);
void config_mib_fapi_NB_IoT(
int physCellId,
uint8_t eutra_band,
int Ncp,
int Ncp_UL,
int p_eNB,
int p_rx_eNB,
int dl_CarrierFreq,
int ul_CarrierFreq,
long *eutraControlRegionSize,
LTE_BCCH_BCH_Message_NB_t *mib_NB_IoT
);
void config_sib2_fapi_NB_IoT(
int physCellId,
LTE_RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon
);
///config
void rrc_mac_config_req_NB_IoT(
module_id_t Mod_idP,
int CC_idP,
int rntiP,
rrc_eNB_carrier_data_NB_IoT_t *carrier,
LTE_SystemInformationBlockType1_NB_t *sib1_NB_IoT,
LTE_RadioResourceConfigCommonSIB_NB_r13_t *radioResourceConfigCommon,
LTE_PhysicalConfigDedicated_NB_r13_t *physicalConfigDedicated,
LTE_LogicalChannelConfig_NB_r13_t *logicalChannelConfig, //FIXME: decide how to use it
uint8_t ded_flag,
uint8_t ue_list_ded_num);
uint32_t get_SIB23_size(void);
///system
void init_mac_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst);
//void init_rrc_NB_IoT();
void release_mac_inst(uint8_t order);
eNB_MAC_INST_NB_IoT *get_mac_inst(uint8_t order);
uint8_t register_mac_inst(eNB_MAC_INST_NB_IoT *inst, uint8_t order);
///tool
void init_tool(sib1_NB_IoT_sched_t *config);
void UE_info_setting(UE_TEMPLATE_NB_IoT *UE_info);
UE_TEMPLATE_NB_IoT *get_ue_from_rnti(eNB_MAC_INST_NB_IoT *inst, rnti_t rnti);
///scheduler
void eNB_dlsch_ulsch_scheduler_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe);
void eNB_scheduler_computing_flag_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint32_t *scheduler_flags, uint32_t *common_flags, uint32_t *max_subframe);
//Calvin temp define self-tools
int init_debug(eNB_MAC_INST_NB_IoT *inst);
void maintain_available_resource(eNB_MAC_INST_NB_IoT *mac_inst);
void extend_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int max_subframe);
available_resource_DL_t *check_sibs_resource(eNB_MAC_INST_NB_IoT *mac_inst, int check_start_subframe, int check_end_subframe, int num_subframe, int *residual_subframe, int *out_last_subframe, int *out_first_subframe);
uint32_t calculate_DLSF(eNB_MAC_INST_NB_IoT *mac_inst, int abs_start_subframe, int abs_end_subframe);
void init(eNB_MAC_INST_NB_IoT *mac_inst);
void init_dl_list(eNB_MAC_INST_NB_IoT *mac_inst);
int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void fill_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, available_resource_DL_t *node, int start_subframe, int end_subframe, schedule_result_t *new_node);
available_resource_DL_t *check_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, int check_subframe, int num_subframes, int *out_last_subframe, int *out_first_subframe);
void print_available_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst);
void print_schedule_result_DL(void);
void print_schedule_result_UL(void);
void add_ue_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce, uint32_t PHR, uint32_t ul_total_buffer);
void remove_ue(eNB_MAC_INST_NB_IoT *mac_inst, uint16_t rnti, ce_level_t ce);
// SIBs
void schedule_sibs(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t sibs_order, int start_subframe);
//RA
void msg3_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti);
void msg4_do_retransmit_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti);
void schedule_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst);
void init_RA_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint8_t preamble_index, ce_level_t ce_level, uint32_t sfn_id, uint16_t ta);
void schedule_rar_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void receive_msg3_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t c_rnti, uint32_t phr, uint32_t ul_total_buffer, uint8_t* ccch_sdu, uint8_t* msg4_rrc_sdu);
void schedule_msg3_retransimission_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void schedule_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
void fill_rar_NB_IoT(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template, uint8_t msg3_schedule_delay, uint8_t msg3_rep, sched_temp_UL_NB_IoT_t *schedule_template);
void receive_msg4_ack_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, rnti_t rnti);
int fill_msg4_NB_IoT(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template);
int fill_msg4_NB_IoT_fixed(eNB_MAC_INST_NB_IoT *inst, RA_TEMPLATE_NB_IoT *ra_template);
//USS
void schedule_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int index_ss);
//DATA
uint8_t *parse_ulsch_header( uint8_t *mac_header,
uint8_t *num_ce,
uint8_t *num_sdu,
uint8_t *rx_ces,
uint8_t *rx_lcids,
uint16_t *rx_lengths,
uint16_t tb_length );
/*******UL Scheduler**********/
void print_scheduling_result_UL(void);
void print_available_UL_resource(void);
/*set nprach configuration at intial time*/
void setting_nprach(void);
/*Uplink main scheduler*/
//int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info, uint32_t subframe, uint32_t frame, uint32_t H_SFN);
int schedule_UL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst,UE_TEMPLATE_NB_IoT *UE_info, uint32_t subframe, uint32_t frame, uint32_t H_SFN, UE_SCHED_CTRL_NB_IoT_t *UE_sched_info);
/*Check available uplink resource list, if there is available uplink resource, return 0, otherwise, return 1*/
int Check_UL_resource(uint32_t DL_end, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int multi_tone, int fmt2_flag);
/*Get I Repetition number in DCI*/
int get_I_REP(int N_rep);
/*Get N REP from preamble repeat*/
int get_N_REP(int CE_level);
/*Get TBS from mcs, multi-tone, Iru*/
int get_TBS_UL_NB_IoT(uint32_t mcs,uint32_t multi_tone,int Iru);
/*get I tbs from mcs and multi-tone*/
int get_I_TBS_NB_IoT(int x,int y);
/*Get DCI REP from R max and R*/
int get_DCI_REP(uint32_t R,uint32_t R_max);
/*Check single tone resource list*/
int single_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info, int fmt2_flag);
/*Check multi tone resource list*/
int multi_tone_ru_allocation(uint32_t uplink_time, int total_ru, sched_temp_UL_NB_IoT_t *NPUSCH_info);
/*Generate scheduling result of DCI N0 and Uplink config*/
void generate_scheduling_result_UL(int32_t DCI_subframe, int32_t DCI_end_subframe, uint32_t UL_subframe, uint32_t UL_end_subframe, DCIFormatN0_t *DCI_inst, rnti_t rnti, uint8_t *ul_debug_str, uint8_t *dl_debug_str, uint8_t msg3_flag);
/*Adjust UL resource by removing the used resource*/
void adjust_UL_resource_list(sched_temp_UL_NB_IoT_t *NPUSCH_info);
/*Initialize resource by nprach configuration*/
void Initialize_Resource(void);
/*Function to extend uplink resource grid*/
//void add_UL_Resource(eNB_MAC_INST_NB_IoT *mac_inst);
void add_UL_Resource(void);
/*Get ACK/NAK resource field*/
int get_resource_field_value(int subcarrier, int k0);
/*Get DL Repetition index*/
uint8_t get_index_Rep_dl(uint16_t R);
/* \brief Function to retrieve result of scheduling (DCI) in current subframe. Can be called an arbitrary numeber of times after eNB_dlsch_ulsch_scheduler
in a given subframe.
@param Mod_id Instance ID of eNB
@param CC_id Component Carrier Index
@param subframe Index of current subframe
@returns Pointer to generated DCI for subframe
*/
DCI_PDU_NB_IoT *get_dci_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe);
/*******DL Scheduler********/
//void schedule_DL_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, UE_TEMPLATE_NB_IoT *UE_info, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start);
int check_resource_NPDCCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, sched_temp_DL_NB_IoT_t *NPDCCH_info, uint32_t cdd_num, uint32_t dci_rep);
int check_resource_NPDSCH_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDSCH_info, uint32_t sf_end, uint32_t I_delay, uint32_t R_max, uint32_t R_dl, uint32_t n_sf);
int check_resource_DL_NB_IoT(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, uint32_t dlsf_require, sched_temp_DL_NB_IoT_t *schedule_info);
uint32_t get_I_mcs(int CE_level);
uint32_t get_max_tbs(uint32_t I_tbs);
uint32_t get_tbs(uint32_t data_size, uint32_t I_tbs, uint32_t *I_sf);
uint32_t get_num_sf(uint32_t I_sf);
//////
uint8_t get_UL_I_TBS_from_MCS_NB_IoT(uint8_t I_mcs, uint8_t N_sc_RU, uint8_t Msg3_flag);
uint8_t test_signle_tone_UL_NB_IoT(uint8_t subcarrier_spacing, uint8_t I_sc, uint8_t npush_format);
//////
uint32_t get_scheduling_delay(uint32_t I_delay, uint32_t R_max);
uint32_t get_HARQ_delay(int subcarrier_spacing, uint32_t HARQ_delay_index);
//void generate_scheduling_result_DL(uint32_t DCI_subframe, uint32_t NPDSCH_subframe, uint32_t HARQ_subframe, DCIFormatN1_t *DCI, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu);
//void generate_scheduling_result_DL(sched_temp_DL_NB_IoT_t* DCI_info, sched_temp_DL_NB_IoT_t* NPDSCH_info, sched_temp_UL_NB_IoT_t* HARQ_info, DCIFormatN1_t *DCI_inst, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu);
void generate_scheduling_result_DL(uint32_t NPDCCH_sf_end, uint32_t NPDCCH_sf_start, uint32_t NPDSCH_sf_end, uint32_t NPDSCH_sf_start, uint32_t HARQ_sf_end, uint32_t HARQ_sf_start, DCIFormatN1_t *DCI_pdu, rnti_t rnti, uint32_t TBS, uint8_t *DLSCH_pdu);
//void fill_DCI_N1(DCIFormatN1_t *DCI_N1, UE_TEMPLATE_NB_IoT *UE_info, uint32_t scheddly, uint32_t I_sf, uint32_t I_harq);
//Transfrom source into hyperSF, Frame, Subframe format
void convert_system_number(uint32_t source_sf,uint32_t *hyperSF, uint32_t *frame, uint32_t *subframe);
//Trnasform hyperSF, Frame, Subframe format into subframe unit
uint32_t convert_system_number_sf(uint32_t hyperSF, uint32_t frame, uint32_t subframe);
/*input start position amd num_dlsf DL subframe, caculate the last subframe number*/
uint32_t cal_num_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t hyperSF, uint32_t frame, uint32_t subframe, uint32_t* hyperSF_result, uint32_t* frame_result, uint32_t* subframe_result, uint32_t num_dlsf_require);
void init_dlsf_info(eNB_MAC_INST_NB_IoT *mac_inst, DLSF_INFO_t *DLSF_info);
uint32_t generate_dlsch_header_NB_IoT(uint8_t *pdu, uint32_t num_sdu, logical_chan_id_t *logical_channel, uint32_t *sdu_length, uint8_t flag_drx, uint8_t flag_ta, uint32_t TBS);
void maintain_resource_DL(eNB_MAC_INST_NB_IoT *mac_inst, sched_temp_DL_NB_IoT_t *NPDCCH_info, sched_temp_DL_NB_IoT_t *NPDSCH_info);
void init_tool_sib1(eNB_MAC_INST_NB_IoT *mac_inst);
//int is_dlsf(eNB_MAC_INST_NB_IoT *mac_inst, int abs_subframe);
/**DL test , delete**/
available_resource_DL_t* new_dl_node(uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf);
void initialize_dl_resource(available_resource_DL_t *DL_Resource_node, uint32_t start_subframe, uint32_t end_subframe, uint32_t dlsf);
void insert_dl_resource(available_resource_DL_t *DL_Resource_node);
void insert_schedule_result(schedule_result_t **list, int subframe, schedule_result_t *node);
//interface with IF
uint8_t *parse_ulsch_header_NB_IoT( uint8_t *mac_header, uint8_t *num_ce, uint8_t *num_sdu, uint8_t *rx_ces, uint8_t *rx_lcids, uint16_t *rx_lengths, uint16_t tb_length);
void rx_sdu_NB_IoT(module_id_t module_id, int CC_id, frame_t frame, sub_frame_t subframe, uint16_t rnti, uint8_t *sdu, uint16_t length);
int output_handler(eNB_MAC_INST_NB_IoT *mac_inst, module_id_t module_id, int CC_id, uint32_t hypersfn, uint32_t frame, uint32_t subframe, uint8_t MIB_flag, uint8_t SIB1_flag, uint32_t current_time);
// main
uint32_t to_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_CarrierFreq, float m_dl);
uint32_t from_earfcn_NB_IoT(int eutra_bandP,uint32_t dl_earfcn, float m_dl);
int32_t get_uldl_offset_NB_IoT(int eutra_band);
/***Preprocessor***/
void preprocessor_uss_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, uint32_t subframe, uint32_t frame, uint32_t hypersfn, int UE_list_index);
void sort_UEs_uss(void);
int schedule_DL_NB_IoT(module_id_t module_id, eNB_MAC_INST_NB_IoT *mac_inst, UE_TEMPLATE_NB_IoT *UE_info, uint32_t hyperSF_start, uint32_t frame_start, uint32_t subframe_start, UE_SCHED_CTRL_NB_IoT_t *UE_sched_ctrl_info);
void fill_DCI_N0(DCIFormatN0_t *DCI_N0, UE_TEMPLATE_NB_IoT *UE_info, UE_SCHED_CTRL_NB_IoT_t *UE_sched_ctrl_info);
void fill_DCI_N1(DCIFormatN1_t *DCI_N1, UE_TEMPLATE_NB_IoT *UE_info, UE_SCHED_CTRL_NB_IoT_t *UE_sched_ctrl_info);
void USS_scheduling_module(eNB_MAC_INST_NB_IoT *mac_inst, uint32_t abs_subframe, uint8_t number_UE_list);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,154 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file vars_NB_IoT.h
* \brief declare the MAC global variables
* \author NTUST BMW Lab./
* \date 2017
* \email:
* \version 1.0
*
*/
#ifndef __MAC_VARS_NB_IOT_H__
#define __MAC_VARS_NB_IOT_H__
#ifdef USER_MODE
//#include "stdio.h"
#endif //USER_MODE
#include "LAYER2/MAC/defs_NB_IoT.h"
//NB-IoT--------------------------------------
eNB_MAC_INST_NB_IoT *mac_inst;
schedule_result_t *schedule_result_list_UL;
schedule_result_t *schedule_result_list_DL;
available_resource_DL_t *available_resource_DL;
available_resource_tones_UL_t *available_resource_UL;
available_resource_DL_t *available_resource_DL_last;
//should be utilized in: schedule_RA_NB_IoT,rx_sdu_NB_IoT, mac_top_init_NB_IoT,
uint8_t Is_rrc_registered_NB_IoT;
// array will be active when they are used
// 10 -> single-tone / 12 -> multi-tone
const uint32_t max_mcs[2] = {10, 12};
// [CE level] [0 - 3] -> single-tone / [CE level] [4-7] -> multi-tone
const uint32_t mapped_mcs[3][8]={{1,5,9,10,3,7,11,12},
{0,3,7,10,3,7,11,12},
{0,2,6,10,0,4,8,12}};
//TBS table for NPUSCH transmission TS 36.213 v14.2 table Table 16.5.1.2-2:
const int UL_TBS_Table[14][8]=
{
{16,32,56,88,120,152,208,256},
{24,56,88,144,176,208,256,344},
{32,72,144,176,208,256,328,424},
{40,104,176,208,256,328,440,568},
{56,120,208,256,328,408,552,680},
{72,144,224,328,424,504,680,872},
{88,176,256,392,504,600,808,1000},
{104,224,328,472,584,712,1000,1224},
{120,256,392,536,680,808,1096,1384},
{136,296,456,616,776,936,1256,1544},
{144,328,504,680,872,1000,1384,1736},
{176,376,584,776,1000,1192,1608,2024},
{208,440,680,1000,1128,1352,1800,2280},
{224,488,744,1128,1256,1544,2024,2536}
};
const int UL_TBS_Table_msg3[8]={88,88,88,0,0,0,0,0};
const int ULrep[8] = {1,2,4,8,16,32,64,128};
const int rachperiod[8]={40,80,160,240,320,640,1280,2560};
const int rachstart[8]={8,16,32,64,128,256,512,1024};
const int rachrepeat[8]={1,2,4,8,16,32,64,128};
const int rachscofst[7]={0,12,24,36,2,18,34};
const int rachnumsc[4]={12,24,36,48};
const int rawindow[8] = {2, 3, 4, 5, 6, 7, 8, 10};
const int rmax[12] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
const double gvalue[8] = {1.5f, 2, 4, 8, 16, 32, 48, 64};
const int candidate[4] = {1, 2, 4, 8};
const double pdcchoffset[4] = {0, 0.125f, 0.25f, 0.375f};
const int dlrepeat[16] = {1, 2, 4, 8, 16, 32, 64, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048};
const uint32_t RU_table[8]={1,2,3,4,5,6,8,10};
const uint32_t RU_table_msg3[8]={4,3,1,1,1,1,1,1};
const uint32_t scheduling_delay[4]={8,16,32,64};
const uint32_t msg3_scheduling_delay_table[4] = {12,16,32,64};
const uint32_t ack_nack_delay[4]={13,15,17,18};
const uint32_t R_dl_table[16]={1,2,4,8,16,32,64,128,192,256,384,512,768,1024,1536,2048};
// TBS table for the case not containing SIB1-NB_IoT, Table 16.4.1.5.1-1 in TS 36.213 v14.2
const uint32_t MAC_TBStable_NB_IoT[14][8] ={ //[ITBS][ISF]
{16,32,56,88,120.152,208,256},
{24,56,88,144,176,208,256,344},
{32,72,144,176,208,256,328,424},
{40,104,176,208,256,328,440,568},
{56,120,208,256,328,408,552,680},
{72,144,244,328,424,504,680,872},
{88,176,256,392,504,600,808,1032},
{104,224,328,472,584,680,968,1224},
{120,256,392,536,680,808,1096,1352},
{136,296,456,616,776,936,1256,1544},
{144,328,504,680,872,1032,1384,1736},
{176,376,584,776,1000,1192,1608,2024},
{208,440,680,904,1128,1352,1800,2280},
{224,488,744,1128,1256,1544,2024,2536}
};
//TBS table for the case containing S1B1-NB_IoT, Table 16.4.1.5.2-1 in TS 36.213 v14.2 (Itbs = 12 ~ 15 is reserved field
//mapping ITBS to SIB1-NB_IoT
const unsigned int MAC_TBStable_NB_IoT_SIB1[16] = {208,208,208,328,328,328,440,440,440,680,680,680,0,0,0,0};
const int DV_table[16]={0,10,14,19,26,36,49,67,91,125,171,234,321,768,1500,1500};
const int BSR_table[64]= {0,10,12,14,17,19,22,26,31,36,42,49,57,67,78,91,
105,125,146,171,200,234,274,321,376,440,515,603,706,826,967,1132,
1326,1552,1817,2127,2490,2915,3413,3995,4677,5467,6411,7505,8787,10287,12043,14099,
16507,19325,22624,26487,31009,36304,42502,49759,58255,68201,79846,93479,109439,128125,150000,300000
};
const int dl_rep[3] = {1, 2, 4};
const uint32_t dci_rep[3] = {1, 2, 4};
const uint32_t harq_rep[3] = {1, 2, 4};
int extend_space[2] = {256, 256};
int extend_alpha_offset[2] = {10, 10};
int uss_space = 320;
int uss_alpha_offset = 10;
rach_state_t UE_state_machine = initial_access;
const int si_repetition_pattern[4] = {20, 40, 80, 160};
int waiting_flag_from_RLC = 0;
int block_RLC = 0;
int Valid_msg3 = 1;
int RLC_RECEIVE_MSG5_FAILED = 0;
#endif

View File

@@ -73,7 +73,12 @@ typedef struct {
pdcp_data_ind_func_t pdcp_data_ind_func;
} pdcp_params_t;
/*
* SN size
*/
#define PDCP_SN_5BIT 5
#define PDCP_SN_7BIT 7
#define PDCP_SN_12BIT 12
#define PDCP_USE_NETLINK ( get_pdcp_optmask() & PDCP_USE_NETLINK_BIT)
#define LINK_ENB_PDCP_TO_IP_DRIVER ( get_pdcp_optmask() & LINK_ENB_PDCP_TO_IP_DRIVER_BIT)
@@ -200,6 +205,7 @@ typedef struct pdcp_s {
*/
pdcp_hfn_t tx_hfn;
pdcp_hfn_t rx_hfn;
pdcp_hfn_offset_t rx_hfn_offset; // related to sn mismatch
/*
* SN of the last PDCP SDU delivered to upper layers

View File

@@ -135,6 +135,16 @@ typedef struct rlc_am_entity_s {
uint16_t poll_pdu; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollPDU PDUs. */
uint32_t poll_byte; /*!< \brief This parameter is used by the transmitting side of each AM RLC entity to trigger a poll for every pollByte bytes. */
//----------------------------------------------------
// NB-IOT RLC Parameters
//----------------------------------------------------
//DL-AM-RLC Config NB-IoT parameter
uint32_t *enableStatusReportSN_Gap_NB_IoT;
//UL-AM-RLC Config. NB-IoT parameter
uint16_t max_retx_threshold_NB_IoT;
rlc_am_timer_t t_poll_retransmit_NB_IoT; //TIMER
//---------------------------------------------------------------------
// STATISTICS
//---------------------------------------------------------------------

View File

@@ -55,6 +55,14 @@ typedef volatile struct {
uint32_t t_status_prohibit; /*!< \brief t-StatusProhibit timer initial value. */
} rlc_am_info_t;
typedef volatile struct {
//UL-AM-RLC Configurations
uint16_t max_retx_threshold_NB_IoT;
uint32_t t_poll_retransmit_NB_IoT;
//DL-AM-RLC Configurations
uint32_t* enableStatusReportSN_Gap_NB_IoT; /*OPTIONAL*/
}rlc_am_info_NB_IoT_t;
//-----------------------------------------------------------------------------
/*! \fn void rlc_am_init (const protocol_ctxt_t* const ctxtP, rlc_am_entity_t * const rlc_pP)
* \brief Initialize the RLC AM protocol instance, reset variables, allocate buffers, lists, then, the next step in order have a running RLC AM instance is to configure and set debug informations for this RLC instance.

View File

@@ -36,6 +36,7 @@
# define __RLC_H__
# include "platform_types.h"
# include "platform_types_NB_IoT.h"
# include "platform_constants.h"
# include "hashtable.h"
# include "rlc_am.h"
@@ -62,6 +63,45 @@
typedef uint64_t hash_key_t;
#define HASHTABLE_NOT_A_KEY_VALUE ((uint64_t)-1)
//-----------------------------------------------------------------------------
# ifdef RLC_MAC_C
# define private_rlc_mac(x) x
# define public_rlc_mac(x) x
# else
# define private_rlc_mac(x)
# define public_rlc_mac(x) extern x
# endif
# ifdef RLC_MPLS_C
# define private_rlc_mpls(x) x
# define public_rlc_mpls(x) x
# else
# define private_rlc_mpls(x)
# define public_rlc_mpls(x) extern x
# endif
# ifdef RLC_RRC_C
# define private_rlc_rrc(x) x
# define public_rlc_rrc(x) x
# else
# define private_rlc_rrc(x)
# define public_rlc_rrc(x) extern x
# endif
# ifdef RLC_C
# define private_rlc(x) x
# define protected_rlc(x) x
# define public_rlc(x) x
# else
# define private_rlc(x)
# if defined(RLC_MAC_C) || defined(RLC_MPLS_C) || defined(RLC_RRC_C) || defined(RLC_AM_C) || defined(RLC_TM_C) || defined(RLC_UM_C) || defined (PDCP_C)
# define protected_rlc(x) extern x
# else
# define protected_rlc(x)
# endif
# define public_rlc(x) extern x
# endif
//-----------------------------------------------------------------------------
#define RLC_OP_STATUS_OK 1
#define RLC_OP_STATUS_BAD_PARAMETER 22
@@ -96,6 +136,7 @@ typedef volatile struct {
rlc_mode_t rlc_mode;
union {
rlc_am_info_t rlc_am_info; /*!< \sa rlc_am.h. */
rlc_am_info_NB_IoT_t rlc_am_info_NB_IoT; //integrate NB-IoT
rlc_tm_info_t rlc_tm_info; /*!< \sa rlc_tm.h. */
rlc_um_info_t rlc_um_info; /*!< \sa rlc_um.h. */
} rlc;
@@ -160,6 +201,28 @@ typedef void (rrc_data_conf_cb_t)(
const rlc_tx_status_t statusP);
//------------------------------------------------
// NB-IoT (may this stuff are no more used)
//------------------------------------------------
//pointer functions
protected_rlc(void (*rlc_rrc_data_ind_NB_IoT)(
const protocol_ctxt_t* const ctxtP,
const rb_id_t rb_idP,
const sdu_size_t sdu_sizeP,
const uint8_t * const sduP,
const srb1bis_flag_t srb1bis_flag);)
typedef void (rrc_data_ind_cb_NB_IoT_t)(
const protocol_ctxt_t* const ctxtP,
const rb_id_t rb_idP,
const sdu_size_t sdu_sizeP,
const uint8_t * const sduP,
const srb1bis_flag_t srb1bis_flag);
//------------------------------------------------
/*! \struct rlc_t
* \brief Structure to be instanciated to allocate memory for RLC protocol instances.
*/

View File

@@ -0,0 +1,256 @@
#include "IF_Module_L2_primitives_NB_IoT.h"
#include "LAYER2/MAC/proto_NB_IoT.h"
#include "LAYER2/MAC/extern_NB_IoT.h"
#include "openair2/LAYER2/MAC/vars_NB_IoT.h"
int tmp = 0;
//int block_rach = 0;
int first_msg4 = 0;
int rach_count = 0;
void simulate_preamble(UL_IND_NB_IoT_t *UL_INFO, int CE, int sc)
{
UL_INFO->nrach_ind.number_of_initial_scs_detected = 1;
UL_INFO->nrach_ind.nrach_pdu_list[0].nrach_indication_rel13.initial_sc = sc;
UL_INFO->nrach_ind.nrach_pdu_list[0].nrach_indication_rel13.timing_advance = 0;
UL_INFO->nrach_ind.nrach_pdu_list[0].nrach_indication_rel13.nrach_ce_level = CE;
}
void enable_preamble_simulation(UL_IND_NB_IoT_t *UL_INFO,int i)
{
if(i == 1)
{
// simulate preamble session
/*
if(UL_INFO->frame==60 && UL_INFO->subframe==2 && (tmp%3==0))
{
simulate_preamble(UL_INFO,0,2);
tmp++;
}
if(UL_INFO->frame==100 && UL_INFO->subframe==2 && (tmp%3==1))
{
simulate_preamble(UL_INFO,1,13);
tmp++;
}
*/
if(UL_INFO->frame==516 && UL_INFO->subframe==8)
{
simulate_preamble(UL_INFO,2,26);
//tmp++;
}
}
}
void simulate_msg3(UL_IND_NB_IoT_t *UL_INFO)
{
uint8_t *msg3 = NULL;
msg3 = (uint8_t *) malloc (11*sizeof(uint8_t));
msg3[0] = 0;
msg3[1] = 58;
msg3[2] = 42; // 2A
msg3[3] = 179; // B3
msg3[4] = 84; // 54
msg3[5] = 141; // 8D
msg3[6] = 43; // 2B
msg3[7] = 52; // 34
msg3[8] = 64; // 40
msg3[9] = 0;
msg3[10] = 0;
UL_INFO->RX_NPUSCH.number_of_pdus = 1;
UL_INFO->module_id = 0;
UL_INFO->CC_id = 0;
UL_INFO->frame = 521;
UL_INFO->subframe = 1;
UL_INFO->RX_NPUSCH.rx_pdu_list = (nfapi_rx_indication_pdu_t * )malloc(sizeof(nfapi_rx_indication_pdu_t));
UL_INFO->RX_NPUSCH.rx_pdu_list->rx_ue_information.rnti = 0x0101;
UL_INFO->RX_NPUSCH.rx_pdu_list->data = msg3;
UL_INFO->RX_NPUSCH.rx_pdu_list->rx_indication_rel8.length = 11;
}
void enable_msg3_simulation(UL_IND_NB_IoT_t *UL_INFO, int i)
{
if(i==1)
{
if(UL_INFO->frame==521 && UL_INFO->subframe==1)
{
simulate_msg3(UL_INFO);
}
}
}
// Sched_INFO as a input for the scheduler
void UL_indication_NB_IoT(UL_IND_NB_IoT_t *UL_INFO)
{
int i=0;
uint32_t abs_subframe;
UE_TEMPLATE_NB_IoT *ue_info = (UE_TEMPLATE_NB_IoT *)0;
uint16_t tmp_rnti;
enable_preamble_simulation(UL_INFO,0);
enable_msg3_simulation(UL_INFO,0);
//If there is a preamble, do the initiate RA procedure
if(UL_INFO->nrach_ind.number_of_initial_scs_detected>0)
{
// only use one preamble now
//for(i=0;i<UL_INFO->nrach_ind.number_of_initial_scs_detected;i++)
for(i=0;i<1;i++)
{
if(UE_state_machine == initial_access )
{
// initiate_ra here, some useful inforamtion :
LOG_D(MAC,"Init_RA_NB_IoT in, index of sc = %d\n",(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.initial_sc);
init_RA_NB_IoT(mac_inst,
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.initial_sc,
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.nrach_ce_level,
UL_INFO->frame,
//timing_offset = Timing_advance * 16
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.timing_advance*16
);
}else if (UE_state_machine == rach_for_auth_rsp)
{
LOG_N(MAC,"It is the second time that this UE try to rach\n");
init_RA_NB_IoT(mac_inst,
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.initial_sc,
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.nrach_ce_level,
UL_INFO->frame,
//timing_offset = Timing_advance * 16
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.timing_advance*16
);
//block_rach = 2;
}else if (UE_state_machine == rach_for_next || UE_state_machine == rach_for_TAU)
{
//rach_count++;
//if (rach_count%3==0)
//{
LOG_N(MAC,"It is the third time that this UE try to rach\n");
init_RA_NB_IoT(mac_inst,
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.initial_sc,
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.nrach_ce_level,
UL_INFO->frame,
//timing_offset = Timing_advance * 16
(UL_INFO->nrach_ind.nrach_pdu_list+i)->nrach_indication_rel13.timing_advance*16
);
UE_state_machine = rach_for_TAU;
//}
}
}
}
UL_INFO->nrach_ind.number_of_initial_scs_detected = 0;
/* Disable crc function for now
// crc indication if there is error for this round UL transmission
if(UL_INFO->crc_ind.number_of_crcs>0)
{
for(i=0;i<UL_INFO->crc_ind.number_of_crcs;i++)
{
if((UL_INFO->crc_ind.crc_pdu_list+i)->crc_indication_rel8.crc_flag == 0)
{
//unsuccessfully received this UE PDU
//UE_info = get_ue_from_rnti(mac_inst,((UL_INFO->crc_ind.crc_pdu_list)+i)->rx_ue_information.rnti);
//UE_info->HARQ_round++;
}
}
}
*/
// Check if there is any feed back of HARQ
if(UL_INFO->nb_harq_ind.nb_harq_indication_body.number_of_harqs>0)
{
//LOG_I(MAC,"Recieved Ack of DL Data, rnti : %x\n",UL_INFO->nb_harq_ind.nb_harq_indication_body.nb_harq_pdu_list[0].rx_ue_information.rnti);
ue_info = get_ue_from_rnti(mac_inst,UL_INFO->nb_harq_ind.nb_harq_indication_body.nb_harq_pdu_list[0].rx_ue_information.rnti);
if (ue_info->direction==3)
{
if(UL_INFO->nb_harq_ind.nb_harq_indication_body.nb_harq_pdu_list[0].nb_harq_indication_fdd_rel13.harq_tb1==1)
{
LOG_I(MAC,"This UE get the response of HARQ DL : ACK\n");
ue_info->direction=0;
}else
{
LOG_I(MAC,"This UE get the response of HARQ DL : ACK\n");
ue_info->direction=-1;
//ue_info->ul_total_buffer = 11;
UE_state_machine = rach_for_auth_rsp;
//LOG_I(MAC,"This UE get the response of HARQ DL : NACK, and will start the next harq round : %d\n",ue_info->HARQ_round);
//ue_info->direction=1;
//ue_info->HARQ_round++;
}
}
else
{
if(first_msg4 == 0)
{
receive_msg4_ack_NB_IoT(mac_inst,UL_INFO->nb_harq_ind.nb_harq_indication_body.nb_harq_pdu_list[0].rx_ue_information.rnti);
first_msg4 = 1;
}
}
}
UL_INFO->nb_harq_ind.nb_harq_indication_body.number_of_harqs = 0;
//If there is a Uplink SDU which needs to send to MAC
if(UL_INFO->RX_NPUSCH.number_of_pdus>0)
{
for(i=0;i<UL_INFO->RX_NPUSCH.number_of_pdus;i++)
{
printf("The Receive MAC PDU:");
int x = 0;
for (x = 0; x < (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_indication_rel8.length; x ++)
{
printf("%02x ", (UL_INFO->RX_NPUSCH.rx_pdu_list+i)->data[x]);
}
printf("\n");
//For MSG3, Normal Uplink Data, NAK
rx_sdu_NB_IoT(UL_INFO->module_id,
UL_INFO->CC_id,
UL_INFO->frame,
UL_INFO->subframe,
(UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_ue_information.rnti,
(UL_INFO->RX_NPUSCH.rx_pdu_list+i)->data,
(UL_INFO->RX_NPUSCH.rx_pdu_list+i)->rx_indication_rel8.length
);
}
}
UL_INFO->RX_NPUSCH.number_of_pdus = 0;
if(UL_INFO->hypersfn==1 && UL_INFO->frame==0)
{
LOG_D(MAC,"IF L2 hypersfn:%d frame: %d ,subframe: %d \n",UL_INFO->hypersfn,UL_INFO->frame,UL_INFO->subframe);
}
if (waiting_flag_from_RLC == 1)
{
tmp_rnti = 0x0101;
ue_info = get_ue_from_rnti(mac_inst,tmp_rnti);
ue_info->direction=1;
waiting_flag_from_RLC = 2;
}
abs_subframe = UL_INFO->hypersfn*10240+UL_INFO->frame*10+UL_INFO->subframe +4;
//abs_subframe = UL_INFO->frame*10+UL_INFO->subframe +4;
//LOG_I(MAC,"Enter scheduler in subframe %d\n",abs_subframe);
//scheduler here
//Schedule subframe should be next four subframe, means that UL_INFO->frame*10+UL_INFO->subframe + 4
eNB_dlsch_ulsch_scheduler_NB_IoT(mac_inst,abs_subframe);
mac_inst->if_inst_NB_IoT->schedule_response(&mac_inst->Sched_INFO);
LOG_D(MAC,"After scheduler & schedule response\n");
/*
free(SCHED_info->TX_req->tx_request_body.tx_pdu_list);
free(SCHED_info->HI_DCI0_req->hi_dci0_request_body.hi_dci0_pdu_list);
free(SCHED_info->DL_req->dl_config_request_body.dl_config_pdu_list);
free(SCHED_info->UL_req->ul_config_request_body.ul_config_pdu_list);
free(SCHED_info->TX_req);
free(SCHED_info->HI_DCI0_req);
free(SCHED_info->DL_req);
free(SCHED_info->UL_req);
*/
}

View File

@@ -0,0 +1,9 @@
#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
//#include "LAYER2/MAC/extern.h"
#ifndef __IF_MODULE_L2_PRIMITIVES_NB_IOT_H__
#define __IF_MODULE_L2_PRIMITIVES_NB_IOT_H__
#endif

View File

@@ -0,0 +1,29 @@
#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
#include "openair2/PHY_INTERFACE/IF_Module_L2_primitives_NB_IoT.h"
#include "openair1/SCHED_NBIOT/IF_Module_L1_primitives_NB_IoT.h"
#include "LAYER2/MAC/extern_NB_IoT.h"
//#include "LAYER2/MAC/proto_NB_IoT.h"
#define MAX_IF_MODULES_NB_IoT 1
IF_Module_NB_IoT_t *if_inst_NB_IoT[MAX_IF_MODULES_NB_IoT];
//#include "LAYER2/MAC/proto_NB_IoT.h"
IF_Module_NB_IoT_t *IF_Module_init_NB_IoT(int Mod_id){
AssertFatal(Mod_id<MAX_MODULES,"Asking for Module %d > %d\n",Mod_id,MAX_IF_MODULES_NB_IoT);
if (if_inst_NB_IoT[Mod_id]==NULL) {
if_inst_NB_IoT[Mod_id] = (IF_Module_NB_IoT_t*)malloc(sizeof(IF_Module_NB_IoT_t));
memset((void*)if_inst_NB_IoT[Mod_id],0,sizeof(IF_Module_NB_IoT_t));
//if_inst[Mod_id]->CC_mask=0;
if_inst_NB_IoT[Mod_id]->UL_indication = UL_indication_NB_IoT;
/*AssertFatal(pthread_mutex_init(&if_inst[Mod_id]->if_mutex,NULL)==0,
"allocation of if_inst[%d]->if_mutex fails\n",Mod_id);*/
}
return if_inst_NB_IoT[Mod_id];
}

View File

@@ -54,6 +54,7 @@ typedef struct{
uint16_t npdcch_Offset_USS; //Alfa_offset (see TS 36.213 ch 16.6)
LTE_ACK_NACK_NumRepetitions_NB_r13_t *ack_nack_numRepetitions_MSG4; //pointer to the first cell of a list of ack_nack_num_repetitions
//ulPowerControlCommon (UE side)
@@ -137,7 +138,9 @@ typedef struct{
/*preamble part*/
nfapi_nrach_indication_body_t NRACH;
nfapi_nrach_indication_body_t nrach_ind;
/*Uplink data part*/
@@ -182,13 +185,16 @@ typedef struct{
}Sched_Rsp_NB_IoT_t;
/*IF_Module_t a group for gathering the Interface
It should be allocated at the main () in lte-softmodem.c*/
typedef struct IF_Module_NB_IoT_s{
//define the function pointer
void (*UL_indication)(UL_IND_NB_IoT_t *UL_INFO);
void (*schedule_response)(Sched_Rsp_NB_IoT_t *Sched_INFO);
void (*PHY_config_req)(PHY_Config_NB_IoT_t* config_INFO);
}IF_Module_NB_IoT_t;
/*Initial */
@@ -201,15 +207,19 @@ void schedule_response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO);
* */
void PHY_config_req_NB_IoT(PHY_Config_NB_IoT_t* config_INFO);
//int IF_Module_init(IF_Module_t *if_inst);
/*Interface for Downlink, transmitting the DLSCH SDU, DCI SDU*/
//void Schedule_Response_NB_IoT(Sched_Rsp_NB_IoT_t *Sched_INFO);
/*Interface for uplink, transmitting the Preamble(list), ULSCH SDU, NAK, Tick (trigger scheduler)
*/
void UL_indication_NB_IoT(UL_IND_NB_IoT_t *UL_INFO);
/*Initial */
IF_Module_NB_IoT_t *IF_Module_init_NB_IoT(int Mod_id);
#endif

View File

@@ -1,260 +0,0 @@
/* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.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
*/
/*! \file proto_NB_IoT.h
* \brief RRC functions prototypes for eNB and UE for NB-IoT
* \author Navid Nikaein, Raymond Knopp and Michele Paffetti
* \date 2010 - 2014
* \email navid.nikaein@eurecom.fr, michele.paffetti@studio.unibo.it
* \version 1.0
*/
/** \addtogroup _rrc
* @{
*/
#include "RRC/LTE/defs_NB_IoT.h"
#include "pdcp.h"
#include "rlc.h"
#include "extern_NB_IoT.h"
#include "LAYER2/MAC/defs_NB_IoT.h"
/*NOTE: no static function should be declared in this header file (e.g. init_SI_NB)*/
/*------------------------common_nb_iot.c----------------------------------------*/
/** \brief configure BCCH & CCCH Logical Channels and associated rrc_buffers, configure associated SRBs
*/
void openair_rrc_on_NB_IoT(const protocol_ctxt_t* const ctxt_pP);
void rrc_config_buffer_NB_IoT(SRB_INFO_NB_IoT *srb_info, uint8_t Lchan_type, uint8_t Role);
int L3_xface_init_NB_IoT(void);
void openair_rrc_top_init_eNB_NB_IoT(void);
//void rrc_top_cleanup(void); -->seems not to be used
//rrc_t310_expiration-->seems not to be used
/** \brief Function to update timers every subframe. For UE it updates T300,T304 and T310.
@param ctxt_pP running context
@param enb_index
@param CC_id
*/
RRC_status_t rrc_rx_tx_NB_IoT(protocol_ctxt_t* const ctxt_pP, const uint8_t enb_index, const int CC_id);
//long binary_search_int(int elements[], long numElem, int value);--> seems not to be used
//long binary_search_float(float elements[], long numElem, float value);--> used only at UE side
//---------------------------------------
//defined in L2_interface
//called by rx_sdu only in case of CCCH message (e.g RRCConnectionRequest-NB)
int8_t mac_rrc_data_ind_eNB_NB_IoT(
const module_id_t module_idP,
const int CC_id,
const frame_t frameP,
const sub_frame_t sub_frameP,
const rnti_t rntiP,
const rb_id_t srb_idP,//could be skipped since always go through the CCCH channel
const uint8_t* sduP,
const sdu_size_t sdu_lenP
);
//-------------------------------------------
//defined in L2_interface
void dump_ue_list_NB_IoT(UE_list_NB_IoT_t *listP, int ul_flag);
//-------------------------------------------
//defined in L2_interface
void mac_eNB_rrc_ul_failure_NB_IoT(
const module_id_t mod_idP,
const int CC_idP,
const frame_t frameP,
const sub_frame_t subframeP,
const rnti_t rntiP);
//------------------------------------------
//defined in eNB_scheduler_primitives.c
int rrc_mac_remove_ue_NB_IoT(
module_id_t mod_idP,
rnti_t rntiP);
//------------------------------------------
//defined in L2_interface
void mac_eNB_rrc_ul_in_sync_NB_IoT(
const module_id_t mod_idP,
const int CC_idP,
const frame_t frameP,
const sub_frame_t subframeP,
const rnti_t rntiP);
//------------------------------------------
//defined in L2_interface
int mac_eNB_get_rrc_status_NB_IoT(
const module_id_t Mod_idP,
const rnti_t rntiP
);
//---------------------------
/*-----------eNB procedures (rrc_eNB_nb_iot.c)---------------*/
//---Initialization--------------
void openair_eNB_rrc_on_NB_IoT(
const protocol_ctxt_t* const ctxt_pP
);
void rrc_config_buffer_NB_IoT(
SRB_INFO_NB_IoT* Srb_info,
uint8_t Lchan_type,
uint8_t Role
);
char openair_rrc_eNB_configuration_NB_IoT(
const module_id_t enb_mod_idP,
NbIoTRrcConfigurationReq* configuration
);
//-----------------------------
/**\brief RRC eNB task. (starting of the RRC state machine)
\param void *args_p Pointer on arguments to start the task. */
void *rrc_enb_task_NB_IoT(void *args_p);
/**\brief Entry routine to decode a UL-CCCH-Message-NB. Invokes PER decoder and parses message.
\param ctxt_pP Running context
\param Srb_info Pointer to SRB0 information structure (buffer, etc.)*/
int rrc_eNB_decode_ccch_NB_IoT(
protocol_ctxt_t* const ctxt_pP,
const SRB_INFO_NB_IoT* const Srb_info,
const int CC_id
);
/**\brief Entry routine to decode a UL-DCCH-Message-NB. Invokes PER decoder and parses message.
\param ctxt_pP Context
\param Rx_sdu Pointer Received Message
\param sdu_size Size of incoming SDU*/
int rrc_eNB_decode_dcch_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
const rb_id_t Srb_id,
const uint8_t* const Rx_sdu,
const sdu_size_t sdu_sizeP
);
/**\brief Generate RRCConnectionReestablishmentReject-NB
\param ctxt_pP Running context
\param ue_context_pP UE context
\param CC_id Component Carrier ID*/
void rrc_eNB_generate_RRCConnectionReestablishmentReject_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP,
const int CC_id
);
void rrc_eNB_generate_RRCConnectionReject_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP,
const int CC_id
);
void rrc_eNB_generate_RRCConnectionSetup_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP,
const int CC_id
);
void rrc_eNB_process_RRCConnectionReconfigurationComplete_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* ue_context_pP,
const uint8_t xid //transaction identifier
);
void //was under ITTI
rrc_eNB_reconfigure_DRBs_NB_IoT(const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* ue_context_pP);
void //was under ITTI
rrc_eNB_generate_dedicatedRRCConnectionReconfiguration_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP
// const uint8_t ho_state
);
void rrc_eNB_process_RRCConnectionSetupComplete_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* ue_context_pP,
LTE_RRCConnectionSetupComplete_NB_r13_IEs_t * rrcConnectionSetupComplete_NB
);
void rrc_eNB_generate_SecurityModeCommand_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP
);
void rrc_eNB_generate_UECapabilityEnquiry_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP
);
void rrc_eNB_generate_defaultRRCConnectionReconfiguration_NB_IoT(const protocol_ctxt_t* const ctxt_pP,
rrc_eNB_ue_context_NB_IoT_t* const ue_context_pP
//no HO flag
);
/// Utilities------------------------------------------------
void rrc_eNB_free_UE_NB_IoT(
const module_id_t enb_mod_idP,
const struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP
);
void rrc_eNB_free_mem_UE_context_NB_IoT(
const protocol_ctxt_t* const ctxt_pP,
struct rrc_eNB_ue_context_NB_IoT_s* const ue_context_pP
);
/**\brief Function to get the next transaction identifier.
\param module_idP Instance ID for CH/eNB
\return a transaction identifier*/
uint8_t rrc_eNB_get_next_transaction_identifier_NB_IoT(module_id_t module_idP);
int rrc_init_global_param_NB_IoT(void);
//L2_interface.c
int8_t mac_rrc_data_req_eNB_NB_IoT(
const module_id_t Mod_idP,
const int CC_id,
const frame_t frameP,
const frame_t h_frameP,
const sub_frame_t subframeP, //need for the case in which both SIB1-NB_IoT and SIB23-NB_IoT will be scheduled in the same frame
const rb_id_t Srb_id,
uint8_t* const buffer_pP,
uint8_t flag
);

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More