Merge remote-tracking branch 'origin/develop' into merging-2019-w51-to-develop-nr

This commit is contained in:
Raphael Defosseux
2020-01-10 15:35:54 +01:00
184 changed files with 34802 additions and 1434 deletions
+4
View File
@@ -5,6 +5,10 @@
cmake_targets/log/
cmake_targets/*/build/
cmake_targets/ran_build/
cmake_targets/nas_sim_tools/build/
log/
lte_build_oai/
targets/bin/
# vscode
.vscode
+1
View File
@@ -93,3 +93,4 @@ v0.4 -> Merge of feature-131-new-license. It closes issue#131 and changes the li
v0.3 -> Last stable commit on develop branch before the merge of feature-131-new-license. This is the last commit with GPL License
v0.2 -> Merge of enhancement-10-harmony to include NGFI RRH + New Interface for RF/BBU
v0.1 -> Last stable commit on develop branch before enhancement-10-harmony
@@ -0,0 +1,273 @@
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 = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
// In seconds
rrc_inactivity_threshold = 30;
////////// 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 = 17;
downlink_frequency = 736000000L;
uplink_frequency_offset = -30000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -25;
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 = "CI_MME_IP_ADDR";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
}
);
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];
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "eth0";
FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
@@ -0,0 +1,417 @@
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 = 92; mnc_length = 2; } );
tr_s_preference = "local_mac"
// In seconds
rrc_inactivity_threshold = 30;
////////// 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 = 17;
downlink_frequency = 736000000L;
uplink_frequency_offset = -30000000;
Nid_cell = 0;
N_RB_DL = 25;
Nid_cell_mbsfn = 0;
nb_antenna_ports = 1;
nb_antennas_tx = 1;
nb_antennas_rx = 1;
tx_gain = 90;
rx_gain = 125;
pbch_repetition = "FALSE";
prach_root = 0;
prach_config_index = 0;
prach_high_speed = "DISABLE";
prach_zero_correlation = 1;
prach_freq_offset = 2;
pucch_delta_shift = 1;
pucch_nRB_CQI = 0;
pucch_nCS_AN = 0;
pucch_n1_AN = 0;
pdsch_referenceSignalPower = -25;
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 = "CI_MME_IP_ADDR";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
///M2
target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
enable_enb_m2 = "yes";
mbms_configuration_data_list = (
{
mbsfn_sync_area = 0x0001;
mbms_service_area_list=(
{
mbms_service_area=0x0001;
}
);
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR";
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24";
ENB_PORT_FOR_M2C = 36443; # Spec 36443
};
}
);
MCEs = (
{
MCE_ID = 0xe00;
MCE_name = "MCE-Vicomtech-LTEBox";
//M2
enable_mce_m2 = "yes";
//M3
enable_mce_m3 = "yes";
target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
MCE_INTERFACE_NAME_FOR_M2_ENB = "lo";
MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24";
MCE_PORT_FOR_M2C = 36443; # Spec 36443
MCE_INTERFACE_NAME_FOR_M3_MME = "lo";
MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24";
MCE_PORT_FOR_M3C = 36444; # Spec 36444
};
plnm:
{
mcc = 208;
mnc = 93;
mnc_length = 2;
};
mbms_sched_info :
{
mcch_update_time = 10;
mbms_area_config_list = (
{
common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6)
mbms_area_id = 0;
pmch_config_list = (
{
allocated_sf_end=64;
data_mcs=10;
mch_scheduling_period = 0; #rf8(0)
mbms_session_list = (
{
#plnm + service_id ->tmgi
plnm:
{
mcc = 208;
mnc = 93;
mnc_length = 2;
}
service_id=0;
lcid=8; #this must be properly defined lcid:8+service:0 -> rab_id:8
}
);
}
);
mbms_sf_config_list = (
{
radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5)
radioframe_alloocation_offset=0;
num_frame="oneFrame";
subframe_allocation=57; #xx100000
//num_frame="fourFrame";
//subframe_allocation=14548987; #
}
);
}
);
};
mcch_config_per_mbsfn_area = (
{
mbsfn_area = 0;
pdcch_length = 1; #s1(0), s2(1)
repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3)
offset = 0;
modification_period = 0; #rf512(0; rf1024(1)
subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100101
mcs = 0; #n2(0), n7(1), n13(2), n19(3)
}
);
#); #end mbms_scheduling_info
}
);
MMEs = (
{
MME_ID = 0xe00;
MME_name = "MME-MBMS-Vicomtech-LTEBox";
//M3
enable_mme_m3 = "yes";
NETWORK_INTERFACES :
{
MME_INTERFACE_NAME_FOR_M3_MCE = "lo";
MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24";
MME_PORT_FOR_M3C = 36444; # Spec 36444
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
phy_test_mode = 0;
puSch10xSnr = 160;
puCch10xSnr = 160;
}
);
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];
}
);
THREAD_STRUCT = (
{
#three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
parallel_config = "PARALLEL_SINGLE_THREAD";
#two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
worker_config = "WORKER_ENABLE";
}
);
NETWORK_CONTROLLER :
{
FLEXRAN_ENABLED = "no";
FLEXRAN_INTERFACE_NAME = "eth0";
FLEXRAN_IPV4_ADDRESS = "CI_MME_IP_ADDR";
FLEXRAN_PORT = 2210;
FLEXRAN_CACHE = "/mnt/oai_agent_cache";
FLEXRAN_AWAIT_RECONF = "no";
};
log_config :
{
global_log_level ="info";
global_log_verbosity ="medium";
hw_log_level ="info";
hw_log_verbosity ="medium";
phy_log_level ="info";
phy_log_verbosity ="medium";
mac_log_level ="info";
mac_log_verbosity ="high";
rlc_log_level ="info";
rlc_log_verbosity ="medium";
pdcp_log_level ="info";
pdcp_log_verbosity ="medium";
rrc_log_level ="info";
rrc_log_verbosity ="medium";
};
@@ -0,0 +1,378 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
# real_time choice in {hard, rt-preempt, no}
real_time = "no";
////////// 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 = 600;
plmn_list = ( { mcc = 208; mnc = 93; mnc_length = 2; } );
tr_s_preference = "local_mac"
////////// Physical parameters:
component_carriers = (
{
node_function = "NGFI_RCC_IF4p5";
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 = 2;
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 = -104;
pusch_alpha = "AL1";
pucch_p0_Nominal = -108;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
mbms_dedicated_serving_cell = "DISABLE"
}
);
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 = "192.168.15.130";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
////////// MCE parameters:
target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
///M2
enable_enb_m2 = "yes";
mbms_configuration_data_list = (
{
mbsfn_sync_area = 0x0001;
mbms_service_area_list=(
{
mbms_service_area=0x0001;
}
);
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "enp2s0";
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.10.15/24";
ENB_INTERFACE_NAME_FOR_S1U = "enp2s0";
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.10.15/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24";
ENB_PORT_FOR_M2C = 36443; # Spec 36443
};
}
);
MCEs = (
{
MCE_ID = 0xe00;
MCE_name = "MCE-Vicomtech-LTEBox";
//M2
enable_mce_m2 = "yes";
//M3
enable_mce_m3 = "yes";
target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
MCE_INTERFACE_NAME_FOR_M2_ENB = "lo";
MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24";
MCE_PORT_FOR_M2C = 36443; # Spec 36443
MCE_INTERFACE_NAME_FOR_M3_MME = "lo";
MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24";
MCE_PORT_FOR_M3C = 36444; # Spec 36444
};
plnm:
{
mcc = 208;
mnc = 93;
mnc_length = 2;
};
mbms_sched_info :
{
mcch_update_time = 10;
mbms_area_config_list = (
{
common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6)
mbms_area_id = 0;
pmch_config_list = (
{
allocated_sf_end=32;
data_mcs=14;
mch_scheduling_period = 0; #rf8(0)
mbms_session_list = (
{
#plnm + service_id ->tmgi
plnm:
{
mcc = 208;
mnc = 93;
mnc_length = 2;
}
service_id=0; #keep this allways as 0 (workaround for TUN if)
lcid=6; #this must be properly defined lcid:6+service:0 -> rab_id:6
}
);
}
);
mbms_sf_config_list = (
{
radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5)
radioframe_alloocation_offset=0;
num_frame="oneFrame";
subframe_allocation=57; #xx111001
//num_frame="fourFrame";
//subframe_allocation=14548987; #
}
);
}
);
};
mcch_config_per_mbsfn_area = (
{
mbsfn_area = 0;
pdcch_length = 1; #s1(0), s2(1)
repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3)
offset = 0;
modification_period = 0; #rf512(0; rf1024(1)
subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000
mcs = 1; #n2(0), n7(1), n13(2), n19(3)
}
);
#); #end mbms_scheduling_info
}
);
MMEs = (
{
MME_ID = 0xe00;
MME_name = "MME-MBMS-Vicomtech-LTEBox";
//M3
enable_mme_m3 = "yes";
NETWORK_INTERFACES :
{
MME_INTERFACE_NAME_FOR_M3_MCE = "lo";
MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24";
MME_PORT_FOR_M3C = 36444; # Spec 36444
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_if_name = "lo";
remote_address = "127.0.0.2";
local_address = "127.0.0.1";
local_portc = 50000;
remote_portc = 50000;
local_portd = 50001;
remote_portd = 50001;
local_rf = "no"
tr_preference = "udp_if4p5"
nb_tx = 2
nb_rx = 2
att_tx = 0
att_rx = 0;
eNB_instances = [0];
is_slave = "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_SINGLE_THREAD";
#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";
};
@@ -0,0 +1,378 @@
Active_eNBs = ( "eNB-Eurecom-LTEBox");
# Asn1_verbosity, choice in: none, info, annoying
Asn1_verbosity = "none";
eNBs =
(
{
# real_time choice in {hard, rt-preempt, no}
real_time = "no";
////////// 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 = "NGFI_RCC_IF4p5";
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 = 2;
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 = -104;
pusch_alpha = "AL1";
pucch_p0_Nominal = -108;
msg3_delta_Preamble = 6;
pucch_deltaF_Format1 = "deltaF2";
pucch_deltaF_Format1b = "deltaF3";
pucch_deltaF_Format2 = "deltaF0";
pucch_deltaF_Format2a = "deltaF0";
pucch_deltaF_Format2b = "deltaF0";
rach_numberOfRA_Preambles = 64;
rach_preamblesGroupAConfig = "DISABLE";
/*
rach_sizeOfRA_PreamblesGroupA = ;
rach_messageSizeGroupA = ;
rach_messagePowerOffsetGroupB = ;
*/
rach_powerRampingStep = 4;
rach_preambleInitialReceivedTargetPower = -108;
rach_preambleTransMax = 10;
rach_raResponseWindowSize = 10;
rach_macContentionResolutionTimer = 48;
rach_maxHARQ_Msg3Tx = 4;
pcch_default_PagingCycle = 128;
pcch_nB = "oneT";
bcch_modificationPeriodCoeff = 2;
ue_TimersAndConstants_t300 = 1000;
ue_TimersAndConstants_t301 = 1000;
ue_TimersAndConstants_t310 = 1000;
ue_TimersAndConstants_t311 = 10000;
ue_TimersAndConstants_n310 = 20;
ue_TimersAndConstants_n311 = 1;
ue_TransmissionMode = 1;
mbms_dedicated_serving_cell = "DISABLE"
}
);
srb1_parameters :
{
# timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500]
timer_poll_retransmit = 80;
# timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200]
timer_reordering = 35;
# timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500]
timer_status_prohibit = 0;
# poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)]
poll_pdu = 4;
# poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)]
poll_byte = 99999;
# max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32]
max_retx_threshold = 4;
}
# ------- SCTP definitions
SCTP :
{
# Number of streams to use in input/output
SCTP_INSTREAMS = 2;
SCTP_OUTSTREAMS = 2;
};
////////// MME parameters:
mme_ip_address = ( { ipv4 = "127.0.0.3";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
enable_measurement_reports = "no";
///X2
enable_x2 = "no";
t_reloc_prep = 1000; /* unit: millisecond */
tx2_reloc_overall = 2000; /* unit: millisecond */
////////// MCE parameters:
target_mce_m2_ip_address = ( { ipv4 = "127.0.0.7";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
///M2
enable_enb_m2 = "yes";
mbms_configuration_data_list = (
{
mbsfn_sync_area = 0x0001;
mbms_service_area_list=(
{
mbms_service_area=0x0001;
}
);
}
);
NETWORK_INTERFACES :
{
ENB_INTERFACE_NAME_FOR_S1_MME = "lo";
ENB_IPV4_ADDRESS_FOR_S1_MME = "127.0.0.2/24";
ENB_INTERFACE_NAME_FOR_S1U = "lo";
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.5/24";
ENB_PORT_FOR_S1U = 2152; # Spec 2152
ENB_IPV4_ADDRESS_FOR_X2C = "127.0.0.2/24";
ENB_PORT_FOR_X2C = 36422; # Spec 36422
ENB_IPV4_ADDRESS_FOR_M2C = "127.0.0.2/24";
ENB_PORT_FOR_M2C = 36443; # Spec 36443
};
}
);
MCEs = (
{
MCE_ID = 0xe00;
MCE_name = "MCE-Vicomtech-LTEBox";
//M2
enable_mce_m2 = "yes";
//M3
enable_mce_m3 = "yes";
target_mme_m3_ip_address = ( { ipv4 = "127.0.0.18";
ipv6 = "192:168:30::17";
active = "yes";
preference = "ipv4";
}
);
NETWORK_INTERFACES :
{
MCE_INTERFACE_NAME_FOR_M2_ENB = "lo";
MCE_IPV4_ADDRESS_FOR_M2C = "127.0.0.7/24";
MCE_PORT_FOR_M2C = 36443; # Spec 36443
MCE_INTERFACE_NAME_FOR_M3_MME = "lo";
MCE_IPV4_ADDRESS_FOR_M3C = "127.0.0.3/24";
MCE_PORT_FOR_M3C = 36444; # Spec 36444
};
plnm:
{
mcc = 208;
mnc = 93;
mnc_length = 2;
};
mbms_sched_info :
{
mcch_update_time = 10;
mbms_area_config_list = (
{
common_sf_allocation_period = 2; #rf4(0) rf8(1) rf16(2) rf32(3) rf64(4) rf128(5) rf256(6)
mbms_area_id = 0;
pmch_config_list = (
{
allocated_sf_end=32;
data_mcs=14;
mch_scheduling_period = 0; #rf8(0)
mbms_session_list = (
{
#plnm + service_id ->tmgi
plnm:
{
mcc = 208;
mnc = 93;
mnc_length = 2;
}
service_id=0; #keep this allways as 0 (workaround for TUN if)
lcid=6; #this must be properly defined lcid:6+service:0 -> rab_id:6
}
);
}
);
mbms_sf_config_list = (
{
radioframe_allocation_period=1; #n1(0) n2(1) n4(2) n8(3) n16(4) n32(5)
radioframe_alloocation_offset=0;
num_frame="oneFrame";
subframe_allocation=57; #xx111001
//num_frame="fourFrame";
//subframe_allocation=14548987; #
}
);
}
);
};
mcch_config_per_mbsfn_area = (
{
mbsfn_area = 0;
pdcch_length = 1; #s1(0), s2(1)
repetition_period = 0; #rf32(0), rf64(1), rf128(2), rf256(3)
offset = 0;
modification_period = 0; #rf512(0; rf1024(1)
subframe_allocation_info = 32; #BITSTRING (6bits -> one frame) xx100000
mcs = 1; #n2(0), n7(1), n13(2), n19(3)
}
);
#); #end mbms_scheduling_info
}
);
MMEs = (
{
MME_ID = 0xe00;
MME_name = "MME-MBMS-Vicomtech-LTEBox";
//M3
enable_mme_m3 = "yes";
NETWORK_INTERFACES :
{
MME_INTERFACE_NAME_FOR_M3_MCE = "lo";
MME_IPV4_ADDRESS_FOR_M3C = "127.0.0.18/24";
MME_PORT_FOR_M3C = 36444; # Spec 36444
};
}
);
MACRLCs = (
{
num_cc = 1;
tr_s_preference = "local_L1";
tr_n_preference = "local_RRC";
}
);
L1s = (
{
num_cc = 1;
tr_n_preference = "local_mac";
}
);
RUs = (
{
local_if_name = "lo";
remote_address = "127.0.0.2";
local_address = "127.0.0.1";
local_portc = 50000;
remote_portc = 50000;
local_portd = 50001;
remote_portd = 50001;
local_rf = "no"
tr_preference = "udp_if4p5"
nb_tx = 2
nb_rx = 2
att_tx = 0
att_rx = 0;
eNB_instances = [0];
is_slave = "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_SINGLE_THREAD";
#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";
};
+107 -27
View File
@@ -136,11 +136,13 @@ class SSHConnection():
self.eNB_serverId = ''
self.eNBLogFiles = ['', '', '']
self.eNBOptions = ['', '', '']
self.eNBmbmsEnables = [False, False, False]
self.ping_args = ''
self.ping_packetloss_threshold = ''
self.iperf_args = ''
self.iperf_packetloss_threshold = ''
self.iperf_profile = ''
self.iperf_options = ''
self.nbMaxUEtoAttach = -1
self.UEDevices = []
self.UEDevicesStatus = []
@@ -847,6 +849,17 @@ class SSHConnection():
self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2);
else:
self.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "no";/\' ' + ci_full_config_file, '\$', 2);
self.eNBmbmsEnables[int(self.eNB_instance)] = False
self.command('grep enable_enb_m2 ' + ci_full_config_file, '\$', 2);
result = re.search('yes', str(self.ssh.before))
if result is not None:
self.eNBmbmsEnables[int(self.eNB_instance)] = True
logging.debug('\u001B[1m MBMS is enabled on this eNB\u001B[0m')
result = re.search('noS1', str(self.Initialize_eNB_args))
eNBinNoS1 = False
if result is not None:
eNBinNoS1 = True
logging.debug('\u001B[1m eNB is in noS1 configuration \u001B[0m')
# Launch eNB with the modified config file
self.command('source oaienv', '\$', 5)
self.command('cd cmake_targets', '\$', 5)
@@ -865,6 +878,7 @@ class SSHConnection():
time.sleep(6)
doLoop = True
loopCounter = 20
enbDidSync = False
while (doLoop):
loopCounter = loopCounter - 1
if (loopCounter == 0):
@@ -903,11 +917,27 @@ class SSHConnection():
time.sleep(6)
else:
doLoop = False
self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m')
enbDidSync = True
time.sleep(10)
if enbDidSync and eNBinNoS1:
self.command('ifconfig oaitun_enb1', '\$', 4)
result = re.search('inet addr', str(self.ssh.before))
if result is not None:
logging.debug('\u001B[1m oaitun_enb1 interface is mounted and configured\u001B[0m')
else:
logging.error('\u001B[1m oaitun_enb1 interface is either NOT mounted or NOT configured\u001B[0m')
if self.eNBmbmsEnables[int(self.eNB_instance)]:
self.command('ifconfig oaitun_enm1', '\$', 4)
result = re.search('inet addr', str(self.ssh.before))
if result is not None:
logging.debug('\u001B[1m oaitun_enm1 interface is mounted and configured\u001B[0m')
else:
logging.error('\u001B[1m oaitun_enm1 interface is either NOT mounted or NOT configured\u001B[0m')
self.close()
self.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', ALL_PROCESSES_OK)
logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m')
def InitializeUE_common(self, device_id, idx):
try:
@@ -1102,13 +1132,17 @@ class SSHConnection():
logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m')
tunnelInterfaceStatus = True
else:
self.command('ifconfig oaitun_ue1', '\$', 4)
result = re.search('inet addr:1|inet 1', str(self.ssh.before))
logging.debug(str(self.ssh.before))
logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m')
tunnelInterfaceStatus = False
if self.eNBmbmsEnables[0]:
self.command('ifconfig oaitun_uem1', '\$', 4)
result = re.search('inet addr', str(self.ssh.before))
if result is not None:
logging.debug('\u001B[1m oaitun_ue1 interface is mounted and configured\u001B[0m')
tunnelInterfaceStatus = True
logging.debug('\u001B[1m oaitun_uem1 interface is mounted and configured\u001B[0m')
tunnelInterfaceStatus = tunnelInterfaceStatus and True
else:
logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m')
logging.error('\u001B[1m oaitun_uem1 interface is either NOT mounted or NOT configured\u001B[0m')
tunnelInterfaceStatus = False
else:
tunnelInterfaceStatus = True
@@ -1126,7 +1160,10 @@ class SSHConnection():
self.UEDevicesStatus.append(UE_STATUS_DETACHED)
else:
if self.air_interface == 'lte':
self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured'
if self.eNBmbmsEnables[0]:
self.htmlUEFailureMsg = 'oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured'
else:
self.htmlUEFailureMsg = 'oaitun_ue1 interface is either NOT mounted or NOT configured'
self.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE')
else:
self.htmlUEFailureMsg = 'nr-uesoftmodem did NOT synced'
@@ -2691,17 +2728,18 @@ class SSHConnection():
iClientIPAddr = self.eNBIPAddress
iClientUser = self.eNBUserName
iClientPasswd = self.eNBPassword
# Starting the iperf server
self.open(iServerIPAddr, iServerUser, iServerPasswd)
# args SHALL be "-c client -u any"
# -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1
# -B 10.0.1.1 -u -s -i 1 -fm
server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args))
server_options = server_options.replace('-c','-B')
self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5)
self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5)
time.sleep(0.5)
self.close()
if self.iperf_options != 'sink':
# Starting the iperf server
self.open(iServerIPAddr, iServerUser, iServerPasswd)
# args SHALL be "-c client -u any"
# -c 10.0.1.2 -u -b 1M -t 30 -i 1 -fm -B 10.0.1.1
# -B 10.0.1.1 -u -s -i 1 -fm
server_options = re.sub('-u.*$', '-u -s -i 1 -fm', str(self.iperf_args))
server_options = server_options.replace('-c','-B')
self.command('rm -f /tmp/tmp_iperf_server_' + self.testCase_id + '.log', '\$', 5)
self.command('echo $USER; nohup iperf ' + server_options + ' > /tmp/tmp_iperf_server_' + self.testCase_id + '.log 2>&1 &', iServerUser, 5)
time.sleep(0.5)
self.close()
# Starting the iperf client
modified_options = self.Iperf_ComputeModifiedBW(0, 1)
@@ -2717,14 +2755,22 @@ class SSHConnection():
logging.debug('\u001B[1;37;41m ' + message + ' \u001B[0m')
clientStatus = -2
else:
clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options)
if self.iperf_options == 'sink':
clientStatus = 0
status_queue.put(0)
status_queue.put('OAI-UE')
status_queue.put('10.0.1.2')
status_queue.put('Sink Test : no check')
else:
clientStatus = self.Iperf_analyzeV2Output(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options)
self.close()
# Stopping the iperf server
self.open(iServerIPAddr, iServerUser, iServerPasswd)
self.command('killall --signal SIGKILL iperf', '\$', 5)
time.sleep(0.5)
self.close()
if self.iperf_options != 'sink':
self.open(iServerIPAddr, iServerUser, iServerPasswd)
self.command('killall --signal SIGKILL iperf', '\$', 5)
time.sleep(0.5)
self.close()
if (clientStatus == -1):
if (os.path.isfile('iperf_server_' + self.testCase_id + '.log')):
os.remove('iperf_server_' + self.testCase_id + '.log')
@@ -2732,9 +2778,10 @@ class SSHConnection():
self.Iperf_analyzeV2Server(lock, '10.0.1.2', 'OAI-UE', status_queue, modified_options)
# copying on the EPC server for logCollection
copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
if (copyin_res == 0):
self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts')
if (clientStatus == -1):
copyin_res = self.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log')
if (copyin_res == 0):
self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts')
copyin_res = self.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log')
if (copyin_res == 0):
self.copyout(self.EPCIPAddress, self.EPCUserName, self.EPCPassword, 'iperf_' + self.testCase_id + '_OAI-UE.log', self.EPCSourceCodePath + '/scripts')
@@ -3027,6 +3074,7 @@ class SSHConnection():
ulschFailure = 0
cdrxActivationMessageCount = 0
dropNotEnoughRBs = 0
mbmsRequestMsg = 0
self.htmleNBFailureMsg = ''
isRRU = False
isSlave = False
@@ -3145,6 +3193,10 @@ class SSHConnection():
result = re.search('dropping, not enough RBs', str(line))
if result is not None:
dropNotEnoughRBs += 1
if self.eNBmbmsEnables[int(self.eNB_instance)]:
result = re.search('MBMS USER-PLANE.*Requesting.*bytes from RLC', str(line))
if result is not None:
mbmsRequestMsg += 1
enb_log_file.close()
logging.debug(' File analysis completed')
self.htmleNBFailureMsg = ''
@@ -3196,6 +3248,11 @@ class SSHConnection():
rrcMsg = ' -- ' + str(rrcReestablishReject) + ' were rejected'
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
self.htmleNBFailureMsg += rrcMsg + '\n'
if self.eNBmbmsEnables[int(self.eNB_instance)]:
if mbmsRequestMsg > 0:
rrcMsg = 'eNB requested ' + str(mbmsRequestMsg) + ' times the RLC for MBMS USER-PLANE'
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
self.htmleNBFailureMsg += rrcMsg + '\n'
if X2HO_inNbProcedures > 0:
rrcMsg = 'eNB completed ' + str(X2HO_inNbProcedures) + ' X2 Handover Connection procedure(s)'
logging.debug('\u001B[1;30;43m ' + rrcMsg + ' \u001B[0m')
@@ -3271,6 +3328,7 @@ class SSHConnection():
nrDecodeMib = 0
nrFoundDCI = 0
nrCRCOK = 0
mbms_messages = 0
self.htmlUEFailureMsg = ''
for line in ue_log_file.readlines():
result = re.search('nr_synchro_time', str(line))
@@ -3323,6 +3381,10 @@ class SSHConnection():
result = re.search('No cell synchronization found, abandoning', str(line))
if result is not None:
no_cell_sync_found = True
if self.eNBmbmsEnables[0]:
result = re.search('TRIED TO PUSH MBMS DATA', str(line))
if result is not None:
mbms_messages += 1
result = re.search("MIB Information => ([a-zA-Z]{1,10}), ([a-zA-Z]{1,10}), NidCell (?P<nidcell>\d{1,3}), N_RB_DL (?P<n_rb_dl>\d{1,3}), PHICH DURATION (?P<phich_duration>\d), PHICH RESOURCE (?P<phich_resource>.{1,4}), TX_ANT (?P<tx_ant>\d)", str(line))
if result is not None and (not mib_found):
try:
@@ -3433,6 +3495,14 @@ class SSHConnection():
statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1A" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
self.htmlUEFailureMsg += statMsg + '\n'
if self.eNBmbmsEnables[0]:
if mbms_messages > 0:
statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)'
logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m')
else:
statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)'
logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m')
self.htmlUEFailureMsg += statMsg + '\n'
if foundSegFault:
logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m')
if not nrUEFlag:
@@ -3542,6 +3612,7 @@ class SSHConnection():
logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m')
self.htmleNBFailureMsg = 'Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!'
self.CreateHtmlTestRow('N/A', 'KO', ENB_PROCESS_NOLOGFILE_TO_ANALYZE)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return
if self.eNB_serverId != '0':
self.copyout(self.eNBIPAddress, self.eNBUserName, self.eNBPassword, './' + fileToAnalyze, self.eNBSourceCodePath + '/cmake_targets/')
@@ -3550,11 +3621,13 @@ class SSHConnection():
if (logStatus < 0):
self.CreateHtmlTestRow('N/A', 'KO', logStatus)
self.preamtureExit = True
self.eNBmbmsEnables[int(self.eNB_instance)] = False
return
else:
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
else:
self.CreateHtmlTestRow('N/A', 'OK', ALL_PROCESSES_OK)
self.eNBmbmsEnables[int(self.eNB_instance)] = False
def TerminateHSS(self):
self.open(self.EPCIPAddress, self.EPCUserName, self.EPCPassword)
@@ -4558,6 +4631,13 @@ def GetParametersFromXML(action):
if SSH.iperf_profile != 'balanced' and SSH.iperf_profile != 'unbalanced' and SSH.iperf_profile != 'single-ue':
logging.debug('ERROR: test-case has wrong profile ' + SSH.iperf_profile)
SSH.iperf_profile = 'balanced'
SSH.iperf_options = test.findtext('iperf_options')
if (SSH.iperf_options is None):
SSH.iperf_options = 'check'
else:
if SSH.iperf_options != 'check' and SSH.iperf_options != 'sink':
logging.debug('ERROR: test-case has wrong option ' + SSH.iperf_options)
SSH.iperf_options = 'check'
if action == 'IdleSleep':
string_field = test.findtext('idle_sleep_time_in_sec')
@@ -0,0 +1,82 @@
<!--
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
-->
<testCaseList>
<htmlTabRef>test-05-tm1-mbms-nos1-tunnel</htmlTabRef>
<htmlTabName>Test-05MHz-MBMS-TM1-noS1-tunnel</htmlTabName>
<htmlTabIcon>tasks</htmlTabIcon>
<repeatCount>2</repeatCount>
<TestCaseRequestedList>
030201 090109
030103 000001 090103 000002 040605 000001 090109 030201
</TestCaseRequestedList>
<TestCaseExclusionList></TestCaseExclusionList>
<testCase id="000001">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>10</idle_sleep_time_in_sec>
</testCase>
<testCase id="000002">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>15</idle_sleep_time_in_sec>
</testCase>
<testCase id="000003">
<class>IdleSleep</class>
<desc>Sleep</desc>
<idle_sleep_time_in_sec>60</idle_sleep_time_in_sec>
</testCase>
<testCase id="030103">
<class>Initialize_eNB</class>
<desc>Initialize eNB (FDD/Band7/5MHz/MBMS)</desc>
<Initialize_eNB_args>-O ci-scripts/conf_files/enb.band17.tm1.mbms.25PRB.usrpb210.conf --noS1 --eNBs.[0].rrc_inactivity_threshold 0 --nokrnmod 1 --eNBs.[0].component_carriers.[0].eutra_band 7 --eNBs.[0].component_carriers.[0].downlink_frequency 2680000000 --eNBs.[0].component_carriers.[0].uplink_frequency_offset -120000000</Initialize_eNB_args>
</testCase>
<testCase id="030201">
<class>Terminate_eNB</class>
<desc>Terminate eNB</desc>
</testCase>
<testCase id="090103">
<class>Initialize_OAI_UE</class>
<desc>Initialize OAI UE (FDD/Band7/5MHz/MBMS)</desc>
<Initialize_OAI_UE_args>-C 2680000000 -r 25 --ue-rxgain 120 --ue-txgain 0 --ue-max-power 0 --ue-scan-carrier --nokrnmod 1 --noS1</Initialize_OAI_UE_args>
</testCase>
<testCase id="090109">
<class>Terminate_OAI_UE</class>
<desc>Terminate OAI UE</desc>
</testCase>
<testCase id="040605">
<class>Iperf</class>
<desc>iperf (5MHz - DL/1.5Mbps/UDP/MBMS-sink)(20 sec)</desc>
<iperf_args>-c 10.0.2.2 -u -b 1.5M -t 20 -i 1 -fm -B 10.0.2.1</iperf_args>
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
<iperf_options>sink</iperf_options>
</testCase>
</testCaseList>
+175 -16
View File
@@ -395,6 +395,145 @@ add_library(S1AP_ENB
)
add_dependencies(S1AP_ENB rrc_flag s1ap_flag)
#M2AP
# Same limitation as described in RRC/S1AP: unknown generated file list
# so we generate it at cmake time
##############
add_list1_option(M2AP_RELEASE R14 "M2AP ASN.1 grammar version" R14)
set(M2AP_DIR ${OPENAIR2_DIR}/M2AP)
if (${M2AP_RELEASE} STREQUAL "R8")
make_version(M2AP_VERSION 8 9 0)
set(M2AP_ASN_FILES m2ap-8.9.0.asn1)
elseif (${M2AP_RELEASE} STREQUAL "R11")
make_version(M2AP_VERSION 11 9 0)
set(M2AP_ASN_FILES m2ap-11.9.0.asn1)
elseif (${M2AP_RELEASE} STREQUAL "R12")
make_version(M2AP_VERSION 12 9 0)
set(M2AP_ASN_FILES m2ap-12.9.0.asn1)
elseif (${M2AP_RELEASE} STREQUAL "R14")
make_version(M2AP_VERSION 14 0 0)
set(M2AP_ASN_FILES m2ap-14.0.0.asn1)
elseif (${M2AP_RELEASE} STREQUAL "R15")
make_version(M2AP_VERSION 15 1 0)
set(M2AP_ASN_FILES m2ap-15.1.0.asn1)
endif(${M2AP_RELEASE} STREQUAL "R8")
add_definitions(-DM2AP_VERSION=${M2AP_VERSION})
set(M2AP_ASN_DIR ${M2AP_DIR}/MESSAGES/ASN1/${M2AP_RELEASE})
set(M2AP_C_DIR ${asn1_generated_dir}/M2AP_${M2AP_RELEASE})
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}" "M2AP_" -fno-include-deps -DEMIT_ASN_DEBUG=1
RESULT_VARIABLE ret)
if (NOT ${ret} STREQUAL 0)
message(FATAL_ERROR "${ret}: error")
endif (NOT ${ret} STREQUAL 0)
file(GLOB M2AP_source ${M2AP_C_DIR}/*.c)
add_custom_target (
m2_flag ALL
COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M2AP_C_DIR}" "${M2AP_ASN_DIR}/${M2AP_ASN_FILES}" "M2AP_" -fno-include-deps
DEPENDS ${M2AP_ASN_DIR}/${M2AP_ASN_FILES}
)
add_library(M2AP_LIB
${M2AP_source}
${M2AP_DIR}/m2ap_common.c
)
add_dependencies(M2AP_LIB rrc_flag m2_flag)
include_directories ("${M2AP_C_DIR}")
include_directories ("${M2AP_DIR}")
add_library(M2AP_ENB
${M2AP_DIR}/m2ap_eNB.c
${M2AP_DIR}/m2ap_MCE.c
${M2AP_DIR}/m2ap_decoder.c
${M2AP_DIR}/m2ap_encoder.c
${M2AP_DIR}/m2ap_MCE_handler.c
${M2AP_DIR}/m2ap_eNB_handler.c
${M2AP_DIR}/m2ap_itti_messaging.c
${M2AP_DIR}/m2ap_eNB_management_procedures.c
${M2AP_DIR}/m2ap_eNB_generate_messages.c
${M2AP_DIR}/m2ap_MCE_management_procedures.c
${M2AP_DIR}/m2ap_MCE_generate_messages.c
${M2AP_DIR}/m2ap_ids.c
${M2AP_DIR}/m2ap_timers.c
${M2AP_DIR}/m2ap_MCE_interface_management.c
${M2AP_DIR}/m2ap_eNB_interface_management.c
)
add_dependencies(M2AP_ENB rrc_flag m2_flag)
#M3AP
# Same limitation as described in RRC/S1AP: unknown generated file list
# so we generate it at cmake time
##############
add_list1_option(M3AP_RELEASE R14 "M3AP ASN.1 grammar version" R14)
set(M3AP_DIR ${OPENAIR3_DIR}/M3AP)
if (${M3AP_RELEASE} STREQUAL "R8")
make_version(M3AP_VERSION 8 9 0)
set(M3AP_ASN_FILES m3ap-8.9.0.asn1)
elseif (${M3AP_RELEASE} STREQUAL "R11")
make_version(M3AP_VERSION 11 9 0)
set(M3AP_ASN_FILES m3ap-11.9.0.asn1)
elseif (${M3AP_RELEASE} STREQUAL "R12")
make_version(M3AP_VERSION 12 9 0)
set(M3AP_ASN_FILES m3ap-12.9.0.asn1)
elseif (${M3AP_RELEASE} STREQUAL "R14")
make_version(M3AP_VERSION 14 0 0)
set(M3AP_ASN_FILES m3ap-14.0.0.asn1)
elseif (${M3AP_RELEASE} STREQUAL "R15")
make_version(M3AP_VERSION 15 1 0)
set(M3AP_ASN_FILES m3ap-15.1.0.asn1)
endif(${M3AP_RELEASE} STREQUAL "R8")
add_definitions(-DM3AP_VERSION=${M3AP_VERSION})
set(M3AP_ASN_DIR ${M3AP_DIR}/MESSAGES/ASN1/${M3AP_RELEASE})
set(M3AP_C_DIR ${asn1_generated_dir}/M3AP_${M3AP_RELEASE})
# Warning: if you modify ASN.1 source file to generate new C files, cmake should be re-run instead of make
execute_process(COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}" "M3AP_" -fno-include-deps
RESULT_VARIABLE ret)
if (NOT ${ret} STREQUAL 0)
message(FATAL_ERROR "${ret}: error")
endif (NOT ${ret} STREQUAL 0)
file(GLOB M3AP_source ${M3AP_C_DIR}/*.c)
add_custom_target (
m3_flag ALL
COMMAND ${OPENAIR_CMAKE}/tools/make_asn1c_includes.sh "${M3AP_C_DIR}" "${M3AP_ASN_DIR}/${M3AP_ASN_FILES}" "M3AP_" -fno-include-deps
DEPENDS ${M3AP_ASN_DIR}/${M3AP_ASN_FILES}
)
add_library(M3AP_LIB
${M3AP_source}
${M3AP_DIR}/m3ap_common.c
)
add_dependencies(M3AP_LIB rrc_flag m3_flag)
include_directories ("${M3AP_C_DIR}")
include_directories ("${M3AP_DIR}")
add_library(M3AP_ENB
${M3AP_DIR}/m3ap_decoder.c
${M3AP_DIR}/m3ap_encoder.c
${M3AP_DIR}/m3ap_MCE_handler.c
${M3AP_DIR}/m3ap_MME_handler.c
${M3AP_DIR}/m3ap_MME.c
${M3AP_DIR}/m3ap_MME_management_procedures.c
${M3AP_DIR}/m3ap_MME_interface_management.c
${M3AP_DIR}/m3ap_MCE.c
${M3AP_DIR}/m3ap_MCE_management_procedures.c
${M3AP_DIR}/m3ap_MCE_interface_management.c
${M3AP_DIR}/m3ap_itti_messaging.c
${M3AP_DIR}/m3ap_ids.c
${M3AP_DIR}/m3ap_timers.c
)
add_dependencies(M3AP_ENB rrc_flag m3_flag)
#X2AP
# Same limitation as described in RRC/S1AP: unknown generated file list
# so we generate it at cmake time
@@ -749,6 +888,7 @@ include_directories("${OPENAIR2_DIR}")
include_directories("${OPENAIR3_DIR}/NAS/TOOLS")
include_directories("${OPENAIR2_DIR}/ENB_APP")
include_directories("${OPENAIR2_DIR}/GNB_APP")
include_directories("${OPENAIR2_DIR}/MCE_APP")
include_directories("${OPENAIR2_DIR}/LAYER2/RLC")
include_directories("${OPENAIR2_DIR}/LAYER2/RLC/AM_v9.3.0")
include_directories("${OPENAIR2_DIR}/LAYER2/RLC/UM_v9.3.0")
@@ -771,9 +911,12 @@ include_directories("${OPENAIR3_DIR}/SECU")
include_directories("${OPENAIR3_DIR}/SCTP")
include_directories("${OPENAIR3_DIR}/S1AP")
include_directories("${OPENAIR2_DIR}/X2AP")
include_directories("${OPENAIR2_DIR}/M2AP")
include_directories("${OPENAIR2_DIR}/F1AP")
include_directories("${OPENAIR3_DIR}/UDP")
include_directories("${OPENAIR3_DIR}/GTPV1-U")
include_directories("${OPENAIR3_DIR}/M3AP")
include_directories("${OPENAIR3_DIR}/MME_APP")
include_directories("${OPENAIR_DIR}/targets/COMMON")
include_directories("${OPENAIR_DIR}/targets/ARCH/COMMON")
include_directories("${OPENAIR2_DIR}/ENB_APP/CONTROL_MODULES/PHY")
@@ -1529,6 +1672,7 @@ set(L2_SRC
# ${RRC_DIR}/rrc_UE.c
${RRC_DIR}/rrc_eNB.c
${RRC_DIR}/rrc_eNB_S1AP.c
${RRC_DIR}/rrc_eNB_M2AP.c
${RRC_DIR}/rrc_eNB_UE_context.c
${RRC_DIR}/rrc_common.c
${RRC_DIR}/L2_interface.c
@@ -1647,12 +1791,18 @@ set (GNB_APP_SRC
${OPENAIR2_DIR}/GNB_APP/gnb_config.c
)
set (MCE_APP_SRC
${OPENAIR2_DIR}/MCE_APP/mce_app.c
${OPENAIR2_DIR}/MCE_APP/mce_config.c
)
add_library(L2
${L2_SRC}
${MAC_SRC}
${ENB_APP_SRC}
${MCE_APP_SRC}
)
add_dependencies(L2 rrc_flag s1ap_flag x2_flag)
add_dependencies(L2 rrc_flag s1ap_flag x2_flag m2_flag m3_flag)
add_library(MAC_NR
${MAC_NR_SRC}
@@ -1717,6 +1867,13 @@ set (GTPV1U_SRC
add_library(GTPV1U ${GTPV1U_SRC})
add_dependencies(GTPV1U rrc_flag)
set (MME_APP_SRC
${OPENAIR3_DIR}/MME_APP/mme_app.c
${OPENAIR3_DIR}/MME_APP/mme_config.c
)
add_library(MME_APP ${MME_APP_SRC})
add_dependencies(MME_APP rrc_flag s1ap_flag x2_flag m2_flag m3_flag)
set(SCTP_SRC
${OPENAIR3_DIR}/SCTP/sctp_common.c
${OPENAIR3_DIR}/SCTP/sctp_eNB_task.c
@@ -2298,6 +2455,7 @@ add_executable(lte-softmodem
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
${OPENAIR_TARGETS}/COMMON/create_tasks_mbms.c
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
@@ -2317,7 +2475,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
RRC_LIB S1AP_LIB S1AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB SCHED_RU_LIB
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB} ${PROTO_AGENT_LIB}
-Wl,--end-group z dl)
@@ -2389,9 +2547,10 @@ if (NOT ${NOS1})
endif()
target_link_libraries (lte-uesoftmodem
-Wl,--start-group
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP F1AP_LIB GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
PHY_UE PHY_RU LFDS L2_UE L2_LTE SIMU ${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${ATLAS_LIBRARIES}
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP F1AP_LIB
GTPV1U SECU_CN SECU_OSA UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON
PHY_UE PHY_RU LFDS L2_UE L2_LTE LFDS7 SIMU NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
${MSC_LIB} ${RAL_LIB} ${NAS_UE_LIB} ${ITTI_LIB} ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${ATLAS_LIBRARIES}
-Wl,--end-group z dl)
target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES})
@@ -2654,7 +2813,7 @@ add_executable(test_epc_generate_scenario
${OPENAIR3_DIR}/S1AP/s1ap_eNB_defs.h
)
target_link_libraries (test_epc_generate_scenario
-Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
-Wl,--start-group RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY LFDS ${ITTI_LIB} ${MSC_LIB} L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
)
add_executable(test_epc_play_scenario
@@ -2673,7 +2832,7 @@ add_executable(test_epc_play_scenario
)
target_include_directories(test_epc_play_scenario PUBLIC /usr/local/share/asn1c)
target_link_libraries (test_epc_play_scenario
-Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
-Wl,--start-group RRC_LIB S1AP_LIB X2AP_LIB X2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP UDP SCHED_LIB PHY_COMMON PHY PHY_UE LFDS ${ITTI_LIB} ${MSC_LIB} -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} ${CONFIG_LIBRARIES}
)
@@ -2711,15 +2870,15 @@ if (${T_TRACER})
syncsim nr_ulsim nr_dlsim nr_dlschsim nr_pbchsim nr_pucchsim
nr_ulschsim ldpctest polartest smallblocktest cu_test du_test
#all "add_library" definitions
ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB F1AP_LIB
F1AP params_libconfig oai_exmimodevif oai_usrpdevif oai_bladerfdevif
oai_lmssdrdevif oai_eth_transpro oai_mobipass tcp_bridge tcp_bridge_oai
coding FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO
SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB
SCHED_NR_UE_LIB NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB
NFAPI_USER_LIB PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_UE PHY_RU PHY_MEX
L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR CN_UTILS GTPV1U
SCTP_CLIENT UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB)
ITTI RRC_LIB NR_RRC_LIB S1AP_LIB S1AP_ENB X2AP_LIB X2AP_ENB M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP
params_libconfig oai_exmimodevif oai_usrpdevif oai_bladerfdevif oai_lmssdrdevif
oai_eth_transpro oai_mobipass tcp_bridge tcp_bridge_oai
coding FLPT_MSG ASYNC_IF FLEXRAN_AGENT HASHTABLE MSC UTIL OMG_SUMO
SECU_OSA SECU_CN SCHED_LIB SCHED_NR_LIB SCHED_RU_LIB SCHED_UE_LIB SCHED_NR_UE_LIB default_sched remote_sched RAL
NFAPI_COMMON_LIB NFAPI_LIB NFAPI_PNF_LIB NFAPI_VNF_LIB NFAPI_USER_LIB
PHY_COMMON PHY PHY_UE PHY_NR PHY_NR_UE PHY_RU PHY_MEX
L2 L2_LTE L2_NR L2_UE NR_L2_UE MAC_NR_COMMON MAC_NR MAC_UE_NR
CN_UTILS GTPV1U SCTP_CLIENT MME_APP UDP LIB_NAS_UE NB_IoT LFDS LFDS7 SIMU SIMU_ETH OPENAIR0_LIB)
if (TARGET ${i})
add_dependencies(${i} generate_T)
endif()
+3 -1
View File
@@ -41,11 +41,13 @@ typedef enum {
ngran_ng_eNB_CU = 4,
ngran_gNB_CU = 5,
ngran_eNB_DU = 6,
ngran_gNB_DU = 7
ngran_gNB_DU = 7,
ngran_eNB_MBMS_STA = 8
} ngran_node_t;
#define NODE_IS_MONOLITHIC(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB || (nOdE_TyPe) == ngran_ng_eNB || (nOdE_TyPe) == ngran_gNB)
#define NODE_IS_CU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_CU || (nOdE_TyPe) == ngran_ng_eNB_CU || (nOdE_TyPe) == ngran_gNB_CU)
#define NODE_IS_DU(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_DU || (nOdE_TyPe) == ngran_gNB_DU)
#define NODE_IS_MBMS(nOdE_TyPe) ((nOdE_TyPe) == ngran_eNB_MBMS_STA)
#endif
+4
View File
@@ -418,6 +418,8 @@ int logInit (void)
register_log_component("eRAL","",RAL_ENB);
register_log_component("mRAL","",RAL_UE);
register_log_component("ENB_APP","log",ENB_APP);
register_log_component("MCE_APP","log",MCE_APP);
register_log_component("MME_APP","log",MME_APP);
register_log_component("FLEXRAN_AGENT","log",FLEXRAN_AGENT);
register_log_component("PROTO_AGENT","log",PROTO_AGENT);
register_log_component("TMR","",TMR);
@@ -431,6 +433,8 @@ int logInit (void)
register_log_component("GTPV1U","",GTPU);
register_log_component("S1AP","",S1AP);
register_log_component("F1AP","",F1AP);
register_log_component("M2AP","",M2AP);
register_log_component("M3AP","",M3AP);
register_log_component("SCTP","",SCTP);
register_log_component("X2AP","",X2AP);
register_log_component("LOADER","log",LOADER);
+4
View File
@@ -215,6 +215,8 @@ typedef enum {
RAL_ENB,
RAL_UE,
ENB_APP,
MCE_APP,
MME_APP,
FLEXRAN_AGENT,
TMR,
USIM,
@@ -222,6 +224,8 @@ typedef enum {
PROTO_AGENT,
F1U,
X2AP,
M2AP,
M3AP,
GNB_APP,
NR_RRC,
NR_MAC,
+2
View File
@@ -470,6 +470,8 @@ const char* eurecomFunctionsNames[] = {
"pdcp_fifo_read_buffer",
"pdcp_fifo_flush",
"pdcp_fifo_flush_buffer",
"pdcp_mbms_fifo_read",
"pdcp_mbms_fifo_read_buffer",
/* RRC signals */
"rrc_rx_tx",
"rrc_mac_config_req",
+2
View File
@@ -454,6 +454,8 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_READ_BUFFER,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_FIFO_FLUSH_BUFFER,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER,
/* RRC signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,
+1 -1
View File
@@ -73,7 +73,7 @@ typedef struct {
} T_cache_t;
/* number of VCD functions (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_FUNCTIONS (245)
#define VCD_NUM_FUNCTIONS (247)
/* number of VCD variables (to be kept up to date! see in T_messages.txt) */
#define VCD_NUM_VARIABLES (186)
+93
View File
@@ -405,6 +405,48 @@ ID = LEGACY_X2AP_TRACE
GROUP = ALL:LEGACY_X2AP:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_M2AP_INFO
DESC = M2AP legacy logs - info level
GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_INFO:LEGACY
FORMAT = string,log
ID = LEGACY_M2AP_ERROR
DESC = M2AP legacy logs - error level
GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
ID = LEGACY_M2AP_WARNING
DESC = M2AP legacy logs - warning level
GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_WARNING:LEGACY
FORMAT = string,log
ID = LEGACY_M2AP_DEBUG
DESC = M2AP legacy logs - debug level
GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_DEBUG:LEGACY
FORMAT = string,log
ID = LEGACY_M2AP_TRACE
DESC = M2AP legacy logs - trace level
GROUP = ALL:LEGACY_M2AP:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_M3AP_INFO
DESC = M3AP legacy logs - info level
GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_INFO:LEGACY
FORMAT = string,log
ID = LEGACY_M3AP_ERROR
DESC = M3AP legacy logs - error level
GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
ID = LEGACY_M3AP_WARNING
DESC = M3AP legacy logs - warning level
GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_WARNING:LEGACY
FORMAT = string,log
ID = LEGACY_M3AP_DEBUG
DESC = M3AP legacy logs - debug level
GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_DEBUG:LEGACY
FORMAT = string,log
ID = LEGACY_M3AP_TRACE
DESC = M3AP legacy logs - trace level
GROUP = ALL:LEGACY_M3AP:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_RRC_INFO
DESC = RRC legacy logs - info level
GROUP = ALL:LEGACY_RRC:LEGACY_GROUP_INFO:LEGACY
@@ -529,6 +571,47 @@ ID = LEGACY_GNB_APP_DEBUG
ID = LEGACY_GNB_APP_TRACE
DESC = GNB_APP legacy logs - trace level
GROUP = ALL:LEGACY_GNB_APP:LEGACY_GROUP_TRACE:LEGACY
ID = LEGACY_MCE_APP_INFO
DESC = MCE_APP legacy logs - info level
GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_INFO:LEGACY
FORMAT = string,log
ID = LEGACY_MCE_APP_ERROR
DESC = MCE_APP legacy logs - error level
GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
ID = LEGACY_MCE_APP_WARNING
DESC = MCE_APP legacy logs - warning level
GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_WARNING:LEGACY
FORMAT = string,log
ID = LEGACY_MCE_APP_DEBUG
DESC = MCE_APP legacy logs - debug level
GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_DEBUG:LEGACY
FORMAT = string,log
ID = LEGACY_MCE_APP_TRACE
DESC = MCE_APP legacy logs - trace level
GROUP = ALL:LEGACY_MCE_APP:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_MME_APP_INFO
DESC = MME_APP legacy logs - info level
GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_INFO:LEGACY
FORMAT = string,log
ID = LEGACY_MME_APP_ERROR
DESC = MME_APP legacy logs - error level
GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_ERROR:LEGACY
FORMAT = string,log
ID = LEGACY_MME_APP_WARNING
DESC = MME_APP legacy logs - warning level
GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_WARNING:LEGACY
FORMAT = string,log
ID = LEGACY_MME_APP_DEBUG
DESC = MME_APP legacy logs - debug level
GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_DEBUG:LEGACY
FORMAT = string,log
ID = LEGACY_MME_APP_TRACE
DESC = MME_APP legacy logs - trace level
GROUP = ALL:LEGACY_MME_APP:LEGACY_GROUP_TRACE:LEGACY
FORMAT = string,log
ID = LEGACY_FLEXRAN_AGENT_INFO
@@ -3098,6 +3181,16 @@ ID = VCD_FUNCTION_PDCP_FIFO_FLUSH_BUFFER
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = pdcp_fifo_flush_buffer
ID = VCD_FUNCTION_PDCP_MBMS_FIFO_READ
DESC = VCD function PDCP_MBMS_FIFO_READ
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = pdcp_mbms_fifo_read
ID = VCD_FUNCTION_PDCP_MBMS_FIFO_READ_BUFFER
DESC = VCD function PDCP_MBMS_FIFO_READ_BUFFER
GROUP = ALL:VCD:ENB:VCD_FUNCTION
FORMAT = int,value
VCD_NAME = pdcp_mbms_fifo_read_buffer
ID = VCD_FUNCTION_RRC_RX_TX
DESC = VCD function RRC_RX_TX
GROUP = ALL:VCD:ENB:VCD_FUNCTION
+2
View File
@@ -9,6 +9,8 @@
#endif
#include "openair2/COMMON/s1ap_messages_def.h"
#include "openair2/COMMON/x2ap_messages_def.h"
#include "openair2/COMMON/m2ap_messages_def.h"
#include "openair2/COMMON/m3ap_messages_def.h"
#include "openair2/COMMON/sctp_messages_def.h"
#include "openair2/COMMON/udp_messages_def.h"
#include "openair2/COMMON/gtpv1_u_messages_def.h"
@@ -206,6 +206,8 @@ typedef struct IttiMsgText_s {
#endif
#include <openair2/COMMON/s1ap_messages_types.h>
#include <openair2/COMMON/x2ap_messages_types.h>
#include <openair2/COMMON/m2ap_messages_types.h>
#include <openair2/COMMON/m3ap_messages_types.h>
#include <openair2/COMMON/sctp_messages_types.h>
#include <openair2/COMMON/udp_messages_types.h>
#include <openair2/COMMON/gtpv1_u_messages_types.h>
@@ -231,6 +233,7 @@ typedef struct IttiMsgText_s {
#include <openair3/NAS/UE/user_defs.h>
#include <openair3/NAS/UE/nas_ue_task.h>
#include <openair3/S1AP/s1ap_eNB.h>
#include <openair3/MME_APP/mme_app.h>
//#include <proto.h>
#include <openair3/GTPV1-U/gtpv1u_eNB_task.h>
@@ -290,9 +293,16 @@ typedef struct {
TASK_DEF(TASK_RAL_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_M2AP_ENB, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_M2AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_M3AP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_M3AP_MME, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_M3AP_MCE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_SCTP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_ENB_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_GNB_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_MCE_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_MME_APP, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_FLEXRAN_AGENT,TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_PHY_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
TASK_DEF(TASK_MAC_UE, TASK_PRIORITY_MED, 200, NULL, NULL) \
+4
View File
@@ -44,10 +44,14 @@ uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end);
uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
typedef uint8_t (*pack_array_elem_fn)(void* elem, uint8_t **ppWritePackedMsg, uint8_t *end);
uint8_t packarray(void* array, uint16_t elem_size, uint16_t max_count, uint16_t count, uint8_t **ppWritePackedMsg, uint8_t *end, pack_array_elem_fn fn);
@@ -735,6 +735,23 @@ typedef struct {
#define NFAPI_PUCCH_CONFIG_N_AN_CS_TAG 0x003E
#define NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG 0x003F
typedef struct{
nfapi_uint8_tlv_t mbsfn_area_idx;
nfapi_uint16_tlv_t mbsfn_area_id_r9;
} nfapi_embms_sib13_config_t;
#define NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG 0x0039
#define NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG 0x0040
typedef struct {
nfapi_tl_t tl;
uint16_t num_mbsfn_config;
uint16_t radioframe_allocation_period[8];
uint16_t radioframe_allocation_offset[8];
uint8_t fourframes_flag[8];
int32_t mbsfn_subframeconfig[8];
} nfapi_embms_mbsfn_config_t;
#define NFAPI_EMBMS_MBSFN_CONFIG_TAG 0x0041
typedef struct {
nfapi_uint8_tlv_t radioframe_allocation_period;
nfapi_uint8_tlv_t radioframe_allocation_offset;
@@ -1143,6 +1160,9 @@ typedef struct {
nfapi_prach_config_t prach_config;
nfapi_pusch_config_t pusch_config;
nfapi_pucch_config_t pucch_config;
// addition nfpai tlvs for embms MBSFN config //TOBE REVIEWED
nfapi_embms_sib13_config_t embms_sib13_config;
nfapi_embms_mbsfn_config_t embms_mbsfn_config;
nfapi_fembms_config_t fembms_config;
nfapi_srs_config_t srs_config;
nfapi_uplink_reference_signal_config_t uplink_reference_signal_config;
@@ -1165,6 +1185,9 @@ typedef struct {
nfapi_prach_config_t prach_config;
nfapi_pusch_config_t pusch_config;
nfapi_pucch_config_t pucch_config;
// addition nfpai tlvs for embms MBSFN config //TOBE REVIEWED
nfapi_embms_sib13_config_t embms_sib13_config;
nfapi_embms_mbsfn_config_t embms_mbsfn_config;
nfapi_fembms_config_t fembms_config;
nfapi_srs_config_t srs_config;
nfapi_uplink_reference_signal_config_t uplink_reference_signal_config;
+109
View File
@@ -405,7 +405,116 @@ uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **ou
return 0;
}
}
uint32_t pullarray32(uint8_t **in, uint32_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
{
if(len == 0)
return 1;
if(len > max_len)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
return 0;
}
if((end - (*in)) >= sizeof(uint32_t) * len)
{
uint32_t idx;
for(idx = 0; idx < len; ++idx)
{
if(!pull32(in, &out[idx], end))
return 0;
}
return sizeof(uint32_t) * len;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
return 0;
}
}
uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
{
if(len == 0)
return 1;
if(len > max_len)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
return 0;
}
if((end - (*in)) >= sizeof(uint32_t) * len)
{
uint32_t idx;
for(idx = 0; idx < len; ++idx)
{
if(!pulls32(in, &out[idx], end))
return 0;
}
return sizeof(uint32_t) * len;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
return 0;
}
}
uint32_t pusharray32(uint32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
{
if(len == 0)
return 1;
if(len > max_len)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
return 0;
}
if((end - (*out)) >= sizeof(uint32_t) * len)
{
uint32_t idx;
for(idx = 0; idx < len; ++idx)
{
if(!push32(in[idx], out, end))
return 0;
}
return sizeof(uint32_t) * len;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
return 0;
}
}
uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end)
{
if(len == 0)
return 1;
if(len > max_len)
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s exceed array size (%d > %d)\n", __FUNCTION__, len, max_len);
return 0;
}
if((end - (*out)) >= sizeof(uint32_t) * len)
{
uint32_t idx;
for(idx = 0; idx < len; ++idx)
{
pushs32(in[idx], out, end);
}
return sizeof(uint32_t) * len;
}
else
{
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__);
return 0;
}
}
uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end)
{
if(len == 0)
+25 -1
View File
@@ -404,7 +404,26 @@ static uint8_t unpack_nmm_frequency_bands_value(void* tlv, uint8_t **ppReadPacke
return ( pull16(ppReadPackedMsg, &value->number_of_rf_bands, end) &&
pullarray16(ppReadPackedMsg, value->bands, NFAPI_MAX_NMM_FREQUENCY_BANDS, value->number_of_rf_bands, end));
}
static uint8_t pack_embms_mbsfn_config_value(void* tlv, uint8_t **ppWritePackedMsg, uint8_t *end)
{
nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv;
return ( push16(value->num_mbsfn_config, ppWritePackedMsg, end) &&
pusharray16(value->radioframe_allocation_period, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) &&
pusharray16(value->radioframe_allocation_offset, 8,value->num_mbsfn_config ,ppWritePackedMsg, end) &&
pusharray8(value->fourframes_flag, 8,value->num_mbsfn_config,ppWritePackedMsg, end) &&
pusharrays32(value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, ppWritePackedMsg, end));
}
//static uint8_t unpack_embms_mbsfn_config_value(void* tlv, uint8_t **ppReadPackedMsg, uint8_t* end)
//{
// nfapi_embms_mbsfn_config_t* value = (nfapi_embms_mbsfn_config_t*)tlv;
//
// return ( pull16(ppReadPackedMsg, &value->num_mbsfn_config, end) &&
// pull16(ppReadPackedMsg, &value->radioframe_allocation_period, end) &&
// pull16(ppReadPackedMsg, &value->radioframe_allocation_offset, end) &&
// pull8(ppReadPackedMsg, &value->fourframes_flag, end) &&
// pullarrays32(ppReadPackedMsg, value->mbsfn_subframeconfig, 8, value->num_mbsfn_config, end));
//}
static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t* config)
{
nfapi_param_response_t *pNfapiMsg = (nfapi_param_response_t*)msg;
@@ -461,6 +480,11 @@ static uint8_t pack_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_
pack_tlv(NFAPI_PUCCH_CONFIG_N_AN_CS_TAG, &(pNfapiMsg->pucch_config.n_an_cs), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
pack_tlv(NFAPI_PUCCH_CONFIG_N1_PUCCH_AN_TAG, &(pNfapiMsg->pucch_config.n1_pucch_an), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_idx), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG, &(pNfapiMsg->embms_sib13_config.mbsfn_area_id_r9), ppWritePackedMsg, end, &pack_uint16_tlv_value) &&
pack_tlv(NFAPI_EMBMS_MBSFN_CONFIG_TAG, &(pNfapiMsg->embms_mbsfn_config), ppWritePackedMsg, end, &pack_embms_mbsfn_config_value) &&
pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_PERIOD_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_period), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
pack_tlv(NFAPI_FEMBMS_CONFIG_RADIOFRAME_ALLOCATION_OFFSET_TAG, &(pNfapiMsg->fembms_config.radioframe_allocation_offset), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
pack_tlv(NFAPI_FEMBMS_CONFIG_NON_MBSFN_FLAG_TAG, &(pNfapiMsg->fembms_config.non_mbsfn_config_flag), ppWritePackedMsg, end, &pack_uint8_tlv_value) &&
+49
View File
@@ -69,6 +69,9 @@ l1_north_init_eNB () {
LOG_I(PHY,"%s() RC.eNB[%d][%d] installing callbacks\n", __FUNCTION__, i, j);
RC.eNB[i][j]->if_inst->PHY_config_req = phy_config_request;
RC.eNB[i][j]->if_inst->schedule_response = schedule_response;
RC.eNB[i][j]->if_inst->PHY_config_update_sib2_req = phy_config_update_sib2_request;
RC.eNB[i][j]->if_inst->PHY_config_update_sib13_req = phy_config_update_sib13_request;
}
}
} else {
@@ -283,7 +286,53 @@ void phy_config_request(PHY_Config_t *phy_config) {
LOG_I (PHY, "eNB %d/%d configured\n", Mod_id, CC_id);
}
void phy_config_update_sib2_request(PHY_Config_t *phy_config) {
uint8_t Mod_id = phy_config->Mod_id;
int CC_id = phy_config->CC_id;
int i;
nfapi_config_request_t *cfg = phy_config->cfg;
LOG_I(PHY,"Configure sib2 Mod_id(%d), CC_id(%d) cfg %p\n",Mod_id,CC_id,cfg);
LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms;
fp->num_MBSFN_config = cfg->embms_mbsfn_config.num_mbsfn_config;
for( i=0; i < cfg->embms_mbsfn_config.num_mbsfn_config; i++){
fp->MBSFN_config[i].radioframeAllocationPeriod = cfg->embms_mbsfn_config.radioframe_allocation_period[i];
fp->MBSFN_config[i].radioframeAllocationOffset = cfg->embms_mbsfn_config.radioframe_allocation_offset[i];
fp->MBSFN_config[i].fourFrames_flag = cfg->embms_mbsfn_config.fourframes_flag[i];
fp->MBSFN_config[i].mbsfn_SubframeConfig = cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]; // 6-bit subframe configuration
LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i,
fp->MBSFN_config[i].mbsfn_SubframeConfig);
}
}
void phy_config_update_sib13_request(PHY_Config_t *phy_config) {
uint8_t Mod_id = phy_config->Mod_id;
int CC_id = phy_config->CC_id;
nfapi_config_request_t *cfg = phy_config->cfg;
LOG_I(PHY,"configure sib3 Mod_id(%d), CC_id(%d) cfg %p\n",Mod_id,CC_id,cfg);
LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms;
LOG_I (PHY, "[eNB%d] Applying MBSFN_Area_id %d for index %d\n", Mod_id, (uint16_t)cfg->embms_sib13_config.mbsfn_area_id_r9.value, (uint8_t)cfg->embms_sib13_config.mbsfn_area_idx.value);
//cfg->embms_sib13_config.mbsfn_area_idx;
//cfg->embms_sib13_config.mbsfn_area_id_r9;
AssertFatal((uint8_t)cfg->embms_sib13_config.mbsfn_area_idx.value == 0, "Fix me: only called when mbsfn_Area_idx == 0\n");
if (cfg->embms_sib13_config.mbsfn_area_idx.value == 0) {
fp->Nid_cell_mbsfn = (uint16_t)cfg->embms_sib13_config.mbsfn_area_id_r9.value;
LOG_I(PHY,"Fix me: only called when mbsfn_Area_idx == 0)\n");
}
lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn);
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn);
#endif
}
void phy_config_sib13_eNB(module_id_t Mod_id,int CC_id,int mbsfn_Area_idx,
long mbsfn_AreaId_r9) {
+63 -4
View File
@@ -154,6 +154,42 @@ void phy_config_sib2_ue(module_id_t Mod_id,int CC_id,
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_UE_CONFIG_SIB2, VCD_FUNCTION_OUT);
}
void phy_config_mbsfn_list_ue(module_id_t Mod_id,
int CC_id,
struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList){
// MBSFN
PHY_VARS_UE *ue = PHY_vars_UE_g[Mod_id][CC_id];
LTE_DL_FRAME_PARMS *fp = &ue->frame_parms;
int i;
if (mbsfn_SubframeConfigList != NULL) {
fp->num_MBSFN_config = mbsfn_SubframeConfigList->list.count;
for (i=0; i<mbsfn_SubframeConfigList->list.count; i++) {
fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationPeriod;
fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigList->list.array[i]->radioframeAllocationOffset;
if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
fp->MBSFN_config[i].fourFrames_flag = 0;
fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %d\n", i,
fp->MBSFN_config[i].mbsfn_SubframeConfig);
} else if (mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
fp->MBSFN_config[i].fourFrames_flag = 1;
fp->MBSFN_config[i].mbsfn_SubframeConfig =
mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
(mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
(mbsfn_SubframeConfigList->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
LOG_I(PHY, "[CONFIG] LTE_MBSFN_SubframeConfig[%d] pattern is %x\n", i,
fp->MBSFN_config[i].mbsfn_SubframeConfig);
}
}
}
}
void phy_config_sib13_ue(module_id_t Mod_id,int CC_id,uint8_t eNB_id,int mbsfn_Area_idx,
long mbsfn_AreaId_r9) {
LTE_DL_FRAME_PARMS *fp = &PHY_vars_UE_g[Mod_id][CC_id]->frame_parms;
@@ -578,7 +614,8 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
LTE_UE_PDSCH **const pdsch_vars_SI = ue->pdsch_vars_SI;
LTE_UE_PDSCH **const pdsch_vars_ra = ue->pdsch_vars_ra;
LTE_UE_PDSCH **const pdsch_vars_p = ue->pdsch_vars_p;
LTE_UE_PDSCH **const pdsch_vars_mch = ue->pdsch_vars_MCH;
//LTE_UE_PDSCH **const pdsch_vars_mch = ue->pdsch_vars_MCH;
LTE_UE_PDSCH* (*pdsch_vars_MCH_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdsch_vars_MCH;
LTE_UE_PDSCH* (*pdsch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX+1] = &ue->pdsch_vars;
LTE_UE_PDCCH* (*pdcch_vars_th)[][NUMBER_OF_CONNECTED_eNB_MAX] = &ue->pdcch_vars;
LTE_UE_PBCH **const pbch_vars = ue->pbch_vars;
@@ -660,6 +697,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
for (eNB_id=0; eNB_id<ue->n_connected_eNB; eNB_id++) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
(*pdsch_vars_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
(*pdsch_vars_MCH_th)[th_id][eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
@@ -669,12 +707,13 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
pdsch_vars_SI[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
pdsch_vars_ra[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
pdsch_vars_p[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
pdsch_vars_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
//pdsch_vars_mch[eNB_id] = (LTE_UE_PDSCH *)malloc16_clear(sizeof(LTE_UE_PDSCH));
prach_vars[eNB_id] = (LTE_UE_PRACH *)malloc16_clear(sizeof(LTE_UE_PRACH));
pbch_vars[eNB_id] = (LTE_UE_PBCH *)malloc16_clear(sizeof(LTE_UE_PBCH));
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
phy_init_lte_ue__PDSCH( (*pdsch_vars_th)[th_id][eNB_id], fp );
phy_init_lte_ue__PDSCH( (*pdsch_vars_MCH_th)[th_id][eNB_id], fp );
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
@@ -683,16 +722,25 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
(*pdsch_vars_th)[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
(*pdsch_vars_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) );
(*pdsch_vars_th)[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->llr_shifts = (uint8_t *)malloc16_clear(7*2*fp->N_RB_DL*12);
(*pdsch_vars_MCH_th)[th_id][eNB_id]->llr_shifts_p = (*pdsch_vars_th)[0][eNB_id]->llr_shifts;
(*pdsch_vars_MCH_th)[th_id][eNB_id]->llr[1] = (int16_t *)malloc16_clear( (8*((3*8*6144)+12))*sizeof(int16_t) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->llr128_2ndstream = (int16_t **)malloc16_clear( sizeof(int16_t *) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->rho = (int32_t **)malloc16_clear( fp->nb_antennas_rx*sizeof(int32_t *) );
}
for (int i=0; i<fp->nb_antennas_rx; i++) {
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
(*pdsch_vars_th)[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->rho[i] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
}
}
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
(*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho2_ext = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
}
for (i=0; i<fp->nb_antennas_rx; i++)
@@ -702,6 +750,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
(*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho2_ext[idx] = (int32_t *)malloc16_clear( sizeof(int32_t) * num );
}
}
@@ -713,6 +762,11 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
(*pdsch_vars_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
(*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
(*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->rxdataF_comp1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_mag1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_magb1[k][l] = (int32_t **)malloc16_clear( 8*sizeof(int32_t *) );
}
for (int i=0; i<fp->nb_antennas_rx; i++)
@@ -724,6 +778,11 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
(*pdsch_vars_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
(*pdsch_vars_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
(*pdsch_vars_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_rho_ext[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->rxdataF_comp1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_mag1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
(*pdsch_vars_MCH_th)[th_id][eNB_id]->dl_ch_magb1[k][l][idx] = (int32_t *)malloc16_clear( 7*2*sizeof(int32_t)*(fp->N_RB_DL*12) );
}
}
}
@@ -732,7 +791,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp );
phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp );
phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp );
phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
//phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
@@ -770,7 +829,7 @@ int init_lte_ue_signal(PHY_VARS_UE *ue,
phy_init_lte_ue__PDSCH( pdsch_vars_SI[eNB_id], fp );
phy_init_lte_ue__PDSCH( pdsch_vars_ra[eNB_id], fp );
phy_init_lte_ue__PDSCH( pdsch_vars_p[eNB_id], fp );
phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
//phy_init_lte_ue__PDSCH( pdsch_vars_mch[eNB_id], fp );
// 100 PRBs * 12 REs/PRB * 4 PDCCH SYMBOLS * 2 LLRs/RE
for (th_id=0; th_id<RX_NB_TH_MAX; th_id++) {
+15
View File
@@ -178,6 +178,18 @@ void phy_config_sib2_ue(module_id_t Mod_id,
LTE_AdditionalSpectrumEmission_t *additionalSpectrumEmission,
struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList);
/*!
\fn void phy_config_mbsfn_list_ue(module_id_t Mod_id,uint8_t CC_id
struct MBSFN_SubframeConfigList *mbsfn_SubframeConfigList)
\brief Configure LTE_DL_FRAME_PARMS with components derived after reception of MBSFN config list from SIB2 (at UE).
@param Mod_id Instance id
@param CC_id
@param mbsfn_SubframeConfigList MBSFN subframe configuration
*/
void phy_config_mbsfn_list_ue(module_id_t Mod_id,
int CC_id,
struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigList);
/*!
\fn phy_config_afterHO_ue
@@ -374,6 +386,9 @@ void phy_config_dedicated_scell_eNB(uint8_t Mod_id,
void phy_cleanup(void);
void phy_config_request(PHY_Config_t *phy_config);
void phy_config_update_sib2_request(PHY_Config_t *phy_config);
void phy_config_update_sib13_request(PHY_Config_t *phy_config);
int init_frame_parms(LTE_DL_FRAME_PARMS *frame_parms,uint8_t osf);
void dump_frame_parms(LTE_DL_FRAME_PARMS *frame_parms);
@@ -1946,11 +1946,11 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
case 2: //QPSK
// LOG_I(PHY,"%d : %d,%d => ",tti_offset,((int16_t*)&txdataF[0][tti_offset])[0],((int16_t*)&txdataF[0][tti_offset])[1]);
((int16_t*)&txdataF[4][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
((int16_t*)&txdataF[0][tti_offset])[0] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //I //b_i
*jj = *jj + 1;
((int16_t*)&txdataF[4][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
((int16_t*)&txdataF[0][tti_offset])[1] = (x0[*jj]==1) ? (-gain_lin_QPSK) : gain_lin_QPSK; //Q //b_{i+1}
*jj = *jj + 1;
@@ -1989,8 +1989,8 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
*jj=*jj+1;
((int16_t *)&txdataF[4][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam16_table_offset_re];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_re])>>15);
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam16_table_offset_im];//(int16_t)(((int32_t)amp*qam16_table[qam16_table_offset_im])>>15);
break;
@@ -2029,8 +2029,8 @@ int allocate_REs_in_RB_MCH(int32_t **txdataF,
*jj=*jj+1;
((int16_t *)&txdataF[4][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
((int16_t *)&txdataF[4][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
((int16_t *)&txdataF[0][tti_offset])[0]=qam_table_s[qam64_table_offset_re];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_re])>>15);
((int16_t *)&txdataF[0][tti_offset])[1]=qam_table_s[qam64_table_offset_im];//(int16_t)(((int32_t)amp*qam64_table[qam64_table_offset_im])>>15);
break;
default:
+5 -1
View File
@@ -96,13 +96,17 @@ void generate_mch(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,uint8_t *a)
get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs),1,
2,proc->frame_tx,subframe,0);
eNB->dlsch_MCH->harq_processes[0]->Qm = get_Qm(eNB->dlsch_MCH->harq_processes[0]->mcs);
generate_mbsfn_pilot(eNB,proc,
eNB->common_vars.txdataF,
AMP);
AssertFatal(eNB->dlsch_MCH->harq_processes[0]->pdu != NULL, "attempt to encode a NULL harq PDU\n");
AssertFatal(dlsch_encoding(eNB,
a,
// a,
eNB->dlsch_MCH->harq_processes[0]->pdu,
1,
eNB->dlsch_MCH,
proc->frame_tx,
+26 -19
View File
@@ -57,10 +57,10 @@ void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,in
#define NSYMB_PMCH 12
sprintf(fname,"mch_rxF_ext0.m");
sprintf(vname,"pmch_rxF_ext0");
LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_ext[0],12*(ue->frame_parms.N_RB_DL)*12,1,1);
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_ext[0],12*(ue->frame_parms.N_RB_DL)*12,1,1);
sprintf(fname,"mch_ch_ext00.m");
sprintf(vname,"pmch_ch_ext00");
LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_estimates_ext[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_estimates_ext[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
/*
LOG_M("dlsch%d_ch_ext01.m","dl01_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[1],12*N_RB_DL*NSYMB_PMCH,1,1);
LOG_M("dlsch%d_ch_ext10.m","dl10_ch0_ext",pdsch_vars[eNB_id]->dl_ch_estimates_ext[2],12*N_RB_DL*NSYMB_PMCH,1,1);
@@ -69,16 +69,16 @@ void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,in
*/
sprintf(fname,"mch_rxF_comp0.m");
sprintf(vname,"pmch_rxF_comp0");
LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->rxdataF_comp0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->rxdataF_comp0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
sprintf(fname,"mch_rxF_llr.m");
sprintf(vname,"pmch_llr");
LOG_M(fname,vname, ue->pdsch_vars_MCH[eNB_id]->llr[0],coded_bits_per_codeword,1,0);
LOG_M(fname,vname, ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->llr[0],coded_bits_per_codeword,1,0);
sprintf(fname,"mch_mag1.m");
sprintf(vname,"pmch_mag1");
LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_mag0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_mag0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
sprintf(fname,"mch_mag2.m");
sprintf(vname,"pmch_mag2");
LOG_M(fname,vname,ue->pdsch_vars_MCH[eNB_id]->dl_ch_magb0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
LOG_M(fname,vname,ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id]->dl_ch_magb0[0],12*(ue->frame_parms.N_RB_DL)*NSYMB_PMCH,1,1);
LOG_M("mch00_ch0.m","pmch00_ch0",
&(ue->common_vars.common_vars_rx_data_per_thread[ue->current_thread_id[subframe]].dl_ch_estimates[eNB_id][0][0]),
ue->frame_parms.ofdm_symbol_size*12,1,1);
@@ -96,6 +96,7 @@ void dump_mch(PHY_VARS_UE *ue,uint8_t eNB_id,uint16_t coded_bits_per_codeword,in
void fill_UE_dlsch_MCH(PHY_VARS_UE *ue,int mcs,int ndi,int rvidx,int eNB_id) {
LTE_UE_DLSCH_t *dlsch = ue->dlsch_MCH[eNB_id];
LTE_DL_FRAME_PARMS *frame_parms=&ue->frame_parms;
dlsch->Mdlharq = 1;
// dlsch->rnti = M_RNTI;
dlsch->harq_processes[0]->mcs = mcs;
dlsch->harq_processes[0]->rvidx = rvidx;
@@ -242,15 +243,16 @@ void mch_channel_level(int **dl_ch_estimates_ext,
for (i=0; i<(nre>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128 = _mm_add_epi32(avg128,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),log2_approx(nre>>2)-1));
#elif defined(__arm__)
#endif
}
avg[aarx] = (((int *)&avg128)[0] +
((int *)&avg128)[1] +
((int *)&avg128)[2] +
((int *)&avg128)[3])/nre;
avg[aarx] = (((((int*)&avg128)[0] +
((int*)&avg128)[1] +
((int*)&avg128)[2] +
((int*)&avg128)[3])/(nre>>factor2(nre)))*(1<<(log2_approx(nre>>2)-1-factor2(nre))));
// printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
}
@@ -289,16 +291,21 @@ void mch_channel_level_khz_1dot25(int **dl_ch_estimates_ext,
for (i=0; i<(nre>>2); i++) {
#if defined(__x86_64__) || defined(__i386__)
avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
//avg128 = _mm_add_epi32(avg128,_mm_madd_epi16(dl_ch128[0],dl_ch128[0]));
avg128 = _mm_add_epi32(avg128,_mm_srai_epi32(_mm_madd_epi16(dl_ch128[0],dl_ch128[0]),log2_approx(nre>>2)-1));
#elif defined(__arm__)
#endif
}
avg[aarx] = (((int *)&avg128)[0] +
((int *)&avg128)[1] +
((int *)&avg128)[2] +
((int *)&avg128)[3])/nre;
//printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
// avg[aarx] = (((int*)&avg128)[0] +
// ((int*)&avg128)[1] +
// ((int*)&avg128)[2] +
// ((int*)&avg128)[3])/nre;
avg[aarx] = (((((int*)&avg128)[0] +
((int*)&avg128)[1] +
((int*)&avg128)[2] +
((int*)&avg128)[3])/(nre>>factor2(nre)))*(1<<(log2_approx(nre>>2)-1-factor2(nre))));
//printf("Channel level : %d\n",avg[(aatx<<1)+aarx]);
}
#if defined(__x86_64__) || defined(__i386__)
@@ -1215,7 +1222,7 @@ int rx_pmch(PHY_VARS_UE *ue,
uint8_t subframe,
unsigned char symbol) {
LTE_UE_COMMON *common_vars = &ue->common_vars;
LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[eNB_id];
LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id];
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id];
int avgs,aarx;
@@ -1301,7 +1308,7 @@ int rx_pmch_khz_1dot25(PHY_VARS_UE *ue,
,int mcs) { // currently work around TOFIX
//unsigned int symbol;
LTE_UE_COMMON *common_vars = &ue->common_vars;
LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[eNB_id];
LTE_UE_PDSCH **pdsch_vars = &ue->pdsch_vars_MCH[ue->current_thread_id[subframe]][eNB_id];
LTE_DL_FRAME_PARMS *frame_parms = &ue->frame_parms;
//LTE_UE_DLSCH_t **dlsch = &ue->dlsch_MCH[eNB_id];
int avgs,aarx;
+7 -1
View File
@@ -617,7 +617,9 @@ typedef enum {
RRU_sync_ok=6,
RRU_frame_resynch=7,
RRU_MSG_max_num=8,
RRU_check_sync = 9
RRU_check_sync = 9,
RRU_config_update=10,
RRU_config_update_ok=11
} rru_config_msg_type_t;
@@ -711,6 +713,10 @@ typedef struct RRU_config_s {
time_stats_t ru_arrival_time;
/// mask for RUs serving eNB (PRACH)
int RU_mask_prach;
/// embms mbsfn sf config
int num_MBSFN_config;
/// embms mbsfn sf config
MBSFN_config_t MBSFN_config[8];
} RRU_config_t;
#endif //__PHY_DEFS_RU__H__
+1 -1
View File
@@ -671,7 +671,7 @@ typedef struct {
LTE_UE_PDSCH *pdsch_vars_SI[NUMBER_OF_CONNECTED_eNB_MAX+1];
LTE_UE_PDSCH *pdsch_vars_ra[NUMBER_OF_CONNECTED_eNB_MAX+1];
LTE_UE_PDSCH *pdsch_vars_p[NUMBER_OF_CONNECTED_eNB_MAX+1];
LTE_UE_PDSCH *pdsch_vars_MCH[NUMBER_OF_CONNECTED_eNB_MAX];
LTE_UE_PDSCH *pdsch_vars_MCH[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
LTE_UE_PBCH *pbch_vars[NUMBER_OF_CONNECTED_eNB_MAX];
LTE_UE_PDCCH *pdcch_vars[RX_NB_TH_MAX][NUMBER_OF_CONNECTED_eNB_MAX];
LTE_UE_PRACH *prach_vars[NUMBER_OF_CONNECTED_eNB_MAX];
-1
View File
@@ -72,7 +72,6 @@
#define MAX_NUM_RU_PER_eNB 64
#define MAX_NUM_RX_PRACH_PREAMBLES 4
typedef struct {
/// \brief Pointers (dynamic) to the received data in the time domain.
/// - first index: rx antenna [0..nb_antennas_rx[
+69 -2
View File
@@ -137,7 +137,6 @@ void handle_nfapi_bch_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
// adjust transmit amplitude here based on NFAPI info
}
extern uint32_t localRIV2alloc_LUT6[32];
extern uint32_t localRIV2alloc_LUT25[512];
extern uint32_t localRIV2alloc_LUT50_0[1600];
@@ -147,6 +146,52 @@ extern uint32_t localRIV2alloc_LUT100_1[6000];
extern uint32_t localRIV2alloc_LUT100_2[6000];
extern uint32_t localRIV2alloc_LUT100_3[6000];
void handle_nfapi_mch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t *sdu){
nfapi_dl_config_mch_pdu_rel8_t *rel8 = &dl_config_pdu->mch_pdu.mch_pdu_rel8;
LTE_eNB_DLSCH_t *dlsch = eNB->dlsch_MCH;
LTE_DL_FRAME_PARMS *frame_parms=&eNB->frame_parms;
// dlsch->rnti = M_RNTI;
dlsch->harq_processes[0]->mcs = rel8->modulation;
// dlsch->harq_processes[0]->Ndi = ndi;
dlsch->harq_processes[0]->rvidx = 0;//rvidx;
dlsch->harq_processes[0]->Nl = 1;
dlsch->harq_processes[0]->TBS = TBStable[get_I_TBS(dlsch->harq_processes[0]->mcs)][frame_parms->N_RB_DL-1];
// dlsch->harq_ids[subframe] = 0;
dlsch->harq_processes[0]->nb_rb = frame_parms->N_RB_DL;
switch(frame_parms->N_RB_DL) {
case 6:
dlsch->harq_processes[0]->rb_alloc[0] = 0x3f;
break;
case 25:
dlsch->harq_processes[0]->rb_alloc[0] = 0x1ffffff;
break;
case 50:
dlsch->harq_processes[0]->rb_alloc[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[1] = 0x3ffff;
break;
case 100:
dlsch->harq_processes[0]->rb_alloc[0] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[1] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[2] = 0xffffffff;
dlsch->harq_processes[0]->rb_alloc[3] = 0xf;
break;
}
dlsch->harq_ids[proc->frame_tx%2][proc->subframe_tx] = 0;
dlsch->harq_processes[0]->pdu = sdu;
dlsch->active = 1;
}
void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
@@ -807,8 +852,30 @@ void schedule_response(Sched_Rsp_t *Sched_INFO) {
break;
case NFAPI_DL_CONFIG_MCH_PDU_TYPE:
case NFAPI_DL_CONFIG_MCH_PDU_TYPE:{
// handle_nfapi_mch_dl_pdu(eNB,dl_config_pdu);
//AssertFatal(1==0,"OK\n");
nfapi_dl_config_mch_pdu_rel8_t *mch_pdu_rel8 = &dl_config_pdu->mch_pdu.mch_pdu_rel8;
uint16_t pdu_index = mch_pdu_rel8->pdu_index;
uint16_t tx_pdus = TX_req->tx_request_body.number_of_pdus;
uint16_t invalid_pdu = pdu_index == -1;
uint8_t *sdu = invalid_pdu ? NULL : pdu_index >= tx_pdus ? NULL : TX_req->tx_request_body.tx_pdu_list[pdu_index].segments[0].segment_data;
LOG_D(PHY,"%s() [PDU:%d] NFAPI_DL_CONFIG_MCH_PDU_TYPE SFN/SF:%04d%d TX:%d/%d RX:%d/%d pdu_index:%d sdu:%p\n",
__FUNCTION__, i,
NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),
proc->frame_tx, proc->subframe_tx,
proc->frame_rx, proc->subframe_rx,
pdu_index, sdu);
if (sdu) { //sdu != NULL)
if (NFAPI_MODE!=NFAPI_MODE_VNF)
handle_nfapi_mch_pdu(eNB,NFAPI_SFNSF2SFN(DL_req->sfn_sf),NFAPI_SFNSF2SF(DL_req->sfn_sf),proc,dl_config_pdu, sdu);
} else {
dont_send=1;
LOG_E(MAC,"%s() NFAPI_DL_CONFIG_MCH_PDU_TYPE sdu is NULL DL_CFG:SFN/SF:%d:pdu_index:%d TX_REQ:SFN/SF:%d:pdus:%d\n", __FUNCTION__, NFAPI_SFNSF2DEC(DL_req->sfn_sf), pdu_index,
NFAPI_SFNSF2DEC(TX_req->sfn_sf), tx_pdus);
}
do_oai=1;
}
break;
case NFAPI_DL_CONFIG_DLSCH_PDU_TYPE: {
+5
View File
@@ -53,6 +53,11 @@ void handle_nfapi_dlsch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_pro
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t codeword_index,
uint8_t *sdu);
void handle_nfapi_mch_pdu(PHY_VARS_eNB *eNB,int frame,int subframe,L1_rxtx_proc_t *proc,
nfapi_dl_config_request_pdu_t *dl_config_pdu,
uint8_t *sdu);
void handle_nfapi_ul_pdu(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc,
nfapi_ul_config_request_pdu_t *ul_config_pdu,
uint16_t frame,uint8_t subframe,uint8_t srs_present);
+18 -2
View File
@@ -48,6 +48,8 @@
#include "intertask_interface.h"
#define MBMS_NFAPI_SCHEDULER
nfapi_ue_release_request_body_t release_rntis;
int16_t get_hundred_times_delta_IF_eNB(PHY_VARS_eNB *eNB,uint16_t UE_id,uint8_t harq_pid, uint8_t bw_factor) {
@@ -118,11 +120,21 @@ lte_subframe_t get_subframe_direction(uint8_t Mod_id,uint8_t CC_id,uint8_t subfr
return(subframe_select(&RC.eNB[Mod_id][CC_id]->frame_parms,subframe));
}
#ifdef MBMS_NFAPI_SCHEDULER
void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
int subframe = proc->subframe_tx;
// This is DL-Cell spec pilots in Control region
generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1);
if(eNB->dlsch_MCH->active==1)
generate_mch (eNB, proc,NULL/*, eNB->dlsch_MCH->harq_processes[0]->pdu*/);
eNB->dlsch_MCH->active = 0;
}
#else
void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
MCH_PDU *mch_pduP=NULL;
// uint8_t sync_area=255;
int subframe = proc->subframe_tx;
AssertFatal (1 == 0, "pmch not tested for the moment, exiting\n");
AssertFatal (1 == 1, "pmch not tested for the moment, exiting\n");
// This is DL-Cell spec pilots in Control region
generate_pilots_slot (eNB, eNB->common_vars.txdataF, AMP, subframe << 1, 1);
@@ -134,6 +146,7 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
proc->frame_tx,
subframe);
*/
mch_pduP= &RC.mac[eNB->Mod_id]->common_channels[eNB->CC_id].MCH_pdu;
if ((mch_pduP->Pdu_size > 0) && (mch_pduP->sync_area == 0)) // TEST: only transmit mcch for sync area 0
LOG_D(PHY,"[eNB%"PRIu8"] Frame %d subframe %d : Got MCH pdu for MBSFN (MCS %"PRIu8", TBS %d) \n",
eNB->Mod_id,proc->frame_tx,subframe,mch_pduP->mcs,
@@ -147,12 +160,15 @@ void pmch_procedures(PHY_VARS_eNB *eNB,L1_rxtx_proc_t *proc) {
if (mch_pduP) {
fill_eNB_dlsch_MCH (eNB, mch_pduP->mcs, 1, 0);
eNB->dlsch_MCH->harq_ids[proc->frame_tx%2][subframe] = 0;
eNB->dlsch_MCH->harq_processes[0]->pdu=(uint8_t *) mch_pduP->payload;
// Generate PMCH
generate_mch (eNB, proc, (uint8_t *) mch_pduP->payload);
generate_mch (eNB, proc, NULL/*(uint8_t *) mch_pduP->payload*/);
} else {
LOG_D (PHY, "[eNB/RN] Frame %d subframe %d: MCH not generated \n", proc->frame_tx, subframe);
}
}
#endif
void common_signal_procedures (PHY_VARS_eNB *eNB,int frame, int subframe) {
LTE_DL_FRAME_PARMS *fp=&eNB->frame_parms;
+1 -1
View File
@@ -150,7 +150,7 @@ void prach_procedures(PHY_VARS_eNB *eNB,
} else {
if ((eNB->prach_energy_counter == 100) &&
(max_preamble_energy[0] > eNB->measurements.prach_I0+eNB->prach_DTX_threshold)) {
LOG_I(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
LOG_D(PHY,"[eNB %d/%d][RAPROC] Frame %d, subframe %d Initiating RA procedure with preamble %d, energy %d.%d dB, delay %d\n",
eNB->Mod_id,
eNB->CC_id,
frame,
+74 -37
View File
@@ -83,42 +83,66 @@ void feptx0(RU_t *ru,
//LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d\n",ru->proc.frame_tx, ru->proc.subframe_tx,slot);
for (aa=0; aa<ru->nb_tx; aa++) {
if (fp->Ncp == EXTENDED) PHY_ofdm_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
fp->ofdm_symbol_size,
6,
fp->nb_prefix_samples,
CYCLIC_PREFIX);
else {
/* AssertFatal(ru->generate_dmrs_sync==1 && (fp->frame_type != TDD || ru->is_slave == 1),
"ru->generate_dmrs_sync should not be set, frame_type %d, is_slave %d\n",
fp->frame_type,ru->is_slave);
*/
int num_symb = 7;
if (fp->Ncp == EXTENDED) {
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
fp->ofdm_symbol_size,
6,
fp->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)){
if (slot == 0) {//just use one slot chance
normal_prefix_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
2,
fp);
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][slot*slot_sizeF+fp->ofdm_symbol_size*2],
(int*)&ru->common.txdata[aa][slot_offset+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2)],
fp->ofdm_symbol_size,
10,
fp->ofdm_symbol_size>>2,
CYCLIC_PREFIX);
LOG_D(PHY,"SFN/SF:RU:TX:%d/%d Generating slot %d F(%d) t(%d) IS PMCH(%d)\n",
ru->proc.frame_tx,
ru->proc.subframe_tx,
slot,
slot*slot_sizeF+fp->ofdm_symbol_size*2,
slot_offset+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2),
is_pmch_subframe(ru->proc.frame_tx,subframe,fp));
}
} else {
/* AssertFatal(ru->generate_dmrs_sync==1 && (fp->frame_type != TDD || ru->is_slave == 1),
"ru->generate_dmrs_sync should not be set, frame_type %d, is_slave %d\n",
fp->frame_type,ru->is_slave);
*/
int num_symb = 7;
if (subframe_select(fp,subframe) == SF_S) num_symb=fp->dl_symbols_in_S_subframe+1;
if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) {
//int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
//int32_t *dmrsp[2] ={dmrs,NULL}; //{&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL};
generate_drs_pusch((PHY_VARS_UE *)NULL,
(UE_rxtx_proc_t*)NULL,
fp,
ru->common.txdataF_BF,
0,
AMP,
0,
0,
fp->N_RB_DL,
aa);
}
normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
num_symb,
fp);
if (subframe_select(fp,subframe) == SF_S)
num_symb = fp->dl_symbols_in_S_subframe+1;
if (ru->generate_dmrs_sync == 1 && slot == 0 && subframe == 1 && aa==0) {
//int32_t dmrs[ru->frame_parms.ofdm_symbol_size*14] __attribute__((aligned(32)));
//int32_t *dmrsp[2] ={dmrs,NULL}; //{&dmrs[(3-ru->frame_parms.Ncp)*ru->frame_parms.ofdm_symbol_size],NULL};
generate_drs_pusch((PHY_VARS_UE *)NULL,
(UE_rxtx_proc_t*)NULL,
fp,
ru->common.txdataF_BF,
0,
AMP,
0,
0,
fp->N_RB_DL,
aa);
}
normal_prefix_mod(&ru->common.txdataF_BF[aa][(slot&1)*slot_sizeF],
(int*)&ru->common.txdata[aa][slot_offset],
num_symb,
fp);
}
}
/*
len = fp->samples_per_tti>>1;
@@ -152,10 +176,10 @@ void feptx0(RU_t *ru,
tx_offset = (int)slot_offset+i-ru->N_TA_offset/2;
if (tx_offset<0)
tx_offset += LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
if (tx_offset>=(LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti))
tx_offset -= LTE_NUMBER_OF_SUBFRAMES_PER_FRAME*fp->samples_per_tti;
ru->common.txdata[aa][tx_offset] = 0x00000000;
}
}*/
@@ -237,7 +261,7 @@ void feptx_ofdm_2thread(RU_t *ru,
exit_fun( "ERROR pthread_cond_signal" );
return;
}
//start_meas(&ru->ofdm_mod_wakeup_stats);
//start_meas(&ru->ofdm_mod_wakeup_stats);
pthread_mutex_unlock( &proc->mutex_feptx );
}
@@ -297,16 +321,29 @@ void feptx_ofdm(RU_t *ru,
fp->nb_prefix_samples,
CYCLIC_PREFIX);
} else {
if(is_pmch_subframe(ru->proc.frame_tx,subframe,fp)/*subframe==1*/){
normal_prefix_mod(&ru->common.txdataF_BF[aa][0],
dummy_tx_b,
2,
fp);
PHY_ofdm_mod(&ru->common.txdataF_BF[aa][fp->ofdm_symbol_size*2],
dummy_tx_b+((fp->ofdm_symbol_size>>2)*2+fp->ofdm_symbol_size*2),
fp->ofdm_symbol_size,
10,
fp->ofdm_symbol_size>>2,
CYCLIC_PREFIX);
}else{
normal_prefix_mod(&ru->common.txdataF_BF[aa][slot_offset_F],
dummy_tx_b,
7,
fp);
// if S-subframe generate first slot only
// if S-subframe generate first slot only
if (subframe_select(fp,subframe) == SF_DL)
normal_prefix_mod(&ru->common.txdataF_BF[aa][slot_offset_F+slot_sizeF],
dummy_tx_b+(fp->samples_per_tti>>1),
7,
fp);
}
}
// if S-subframe generate first slot only
+2 -2
View File
@@ -2957,7 +2957,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
dlsch_unscrambling(&ue->frame_parms,1,ue->dlsch_MCH[0],
ue->dlsch_MCH[0]->harq_processes[0]->G,
ue->pdsch_vars_MCH[0]->llr[0],0,subframe_rx<<1);
ue->pdsch_vars_MCH[ue->current_thread_id[subframe_rx]][0]->llr[0],0,subframe_rx<<1);
LOG_D(PHY,"start turbo decode for MCH %d.%d --> nb_rb %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->nb_rb);
LOG_D(PHY,"start turbo decode for MCH %d.%d --> rb_alloc_even %x \n", frame_rx, subframe_rx, (unsigned int)((intptr_t)ue->dlsch_MCH[0]->harq_processes[0]->rb_alloc_even));
LOG_D(PHY,"start turbo decode for MCH %d.%d --> Qm %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->Qm);
@@ -2965,7 +2965,7 @@ void ue_pmch_procedures(PHY_VARS_UE *ue,
LOG_D(PHY,"start turbo decode for MCH %d.%d --> G %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->harq_processes[0]->G);
LOG_D(PHY,"start turbo decode for MCH %d.%d --> Kmimo %d \n", frame_rx, subframe_rx, ue->dlsch_MCH[0]->Kmimo);
ret = dlsch_decoding(ue,
ue->pdsch_vars_MCH[0]->llr[0],
ue->pdsch_vars_MCH[ue->current_thread_id[subframe_rx]][0]->llr[0],
&ue->frame_parms,
ue->dlsch_MCH[0],
ue->dlsch_MCH[0]->harq_processes[0],
@@ -58,6 +58,8 @@ struct iovec nas_iov_rx = {nl_rx_buf, sizeof(nl_rx_buf)};
int nas_sock_fd[MAX_MOBILES_PER_ENB];
int nas_sock_mbms_fd[8];
struct msghdr nas_msg_tx;
struct msghdr nas_msg_rx;
@@ -92,6 +94,64 @@ static int tun_alloc(char *dev) {
return fd;
}
int netlink_init_mbms_tun(char *ifprefix, int num_if) {
int ret;
char ifname[64];
int i= num_if-1;
sprintf(ifname, "oaitun_%.3s%d",ifprefix,i+1);
nas_sock_mbms_fd[i] = tun_alloc(ifname);
if (nas_sock_mbms_fd[i] == -1) {
printf("[NETLINK] Error opening socket %s (%d:%s)\n",ifname,errno, strerror(errno));
exit(1);
}
printf("[NETLINK]Opened socket %s with fd %d\n",ifname,nas_sock_mbms_fd[i]);
ret = fcntl(nas_sock_mbms_fd[i],F_SETFL,O_NONBLOCK);
if (ret == -1) {
printf("[NETLINK] Error fcntl (%d:%s)\n",errno, strerror(errno));
if (LINK_ENB_PDCP_TO_IP_DRIVER) {
exit(1);
}
}
memset(&nas_src_addr, 0, sizeof(nas_src_addr));
nas_src_addr.nl_family = AF_NETLINK;
nas_src_addr.nl_pid = 1;//getpid(); /* self pid */
nas_src_addr.nl_groups = 0; /* not in mcast groups */
ret = bind(nas_sock_mbms_fd[i], (struct sockaddr *)&nas_src_addr, sizeof(nas_src_addr));
memset(&nas_dest_addr, 0, sizeof(nas_dest_addr));
nas_dest_addr.nl_family = AF_NETLINK;
nas_dest_addr.nl_pid = 0; /* For Linux Kernel */
nas_dest_addr.nl_groups = 0; /* unicast */
// TX PART
nas_nlh_tx=(struct nlmsghdr *)malloc(NLMSG_SPACE(NL_MAX_PAYLOAD));
memset(nas_nlh_tx, 0, NLMSG_SPACE(NL_MAX_PAYLOAD));
/* Fill the netlink message header */
nas_nlh_tx->nlmsg_len = NLMSG_SPACE(NL_MAX_PAYLOAD);
nas_nlh_tx->nlmsg_pid = 1;//getpid(); /* self pid */
nas_nlh_tx->nlmsg_flags = 0;
nas_iov_tx.iov_base = (void *)nas_nlh_tx;
nas_iov_tx.iov_len = nas_nlh_tx->nlmsg_len;
memset(&nas_msg_tx,0,sizeof(nas_msg_tx));
nas_msg_tx.msg_name = (void *)&nas_dest_addr;
nas_msg_tx.msg_namelen = sizeof(nas_dest_addr);
nas_msg_tx.msg_iov = &nas_iov_tx;
nas_msg_tx.msg_iovlen = 1;
// RX PART
memset(&nas_msg_rx,0,sizeof(nas_msg_rx));
nas_msg_rx.msg_name = (void *)&nas_src_addr;
nas_msg_rx.msg_namelen = sizeof(nas_src_addr);
nas_msg_rx.msg_iov = &nas_iov_rx;
nas_msg_rx.msg_iovlen = 1;
return 1;
}
int netlink_init_tun(char *ifprefix, int num_if) {
int ret;
char ifname[64];
@@ -63,5 +63,6 @@ void clear_eNB_transport_info(uint8_t);
void clear_UE_transport_info(uint8_t);
int netlink_init(void);
int netlink_init_tun(char *ifsuffix, int num_if);
int netlink_init_mbms_tun(char *ifsuffix, int num_if);
#endif /* EMU_PROTO_H_ */
+94
View File
@@ -0,0 +1,94 @@
/*
* 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
*/
/* eNB application layer -> M2AP messages */
/* ITTI LOG messages */
/* ENCODER */
MESSAGE_DEF(M2AP_RESET_REQUST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_reset_request_log)
MESSAGE_DEF(M2AP_RESOURCE_STATUS_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_resource_status_response_log)
MESSAGE_DEF(M2AP_RESOURCE_STATUS_FAILURE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_resource_status_failure_log)
/* Messages for M2AP logging */
MESSAGE_DEF(M2AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m2ap_setup_request_log)
/* eNB application layer -> M2AP messages */
MESSAGE_DEF(M2AP_REGISTER_ENB_REQ , MESSAGE_PRIORITY_MED, m2ap_register_enb_req_t , m2ap_register_enb_req)
MESSAGE_DEF(M2AP_SUBFRAME_PROCESS , MESSAGE_PRIORITY_MED, m2ap_subframe_process_t , m2ap_subframe_process)
/* M2AP -> eNB application layer messages */
MESSAGE_DEF(M2AP_REGISTER_ENB_CNF , MESSAGE_PRIORITY_MED, m2ap_register_enb_cnf_t , m2ap_register_enb_cnf)
MESSAGE_DEF(M2AP_DEREGISTERED_ENB_IND , MESSAGE_PRIORITY_MED, m2ap_deregistered_enb_ind_t , m2ap_deregistered_enb_ind)
/* handover messages M2AP <-> RRC */
//MESSAGE_DEF(M2AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, m2ap_handover_req_t , m2ap_handover_req)
//MESSAGE_DEF(M2AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, m2ap_handover_req_ack_t , m2ap_handover_req_ack)
//MESSAGE_DEF(M2AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, m2ap_handover_cancel_t , m2ap_handover_cancel)
/* handover messages M2AP <-> S1AP */
//MESSAGE_DEF(M2AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, m2ap_ue_context_release_t , m2ap_ue_context_release)
/* M2AP -> SCTP */
MESSAGE_DEF(M2AP_MCE_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_mce_sctp_req_t , m2ap_mce_sctp_req)
//MESSAGE_DEF(M2AP_ENB_SCTP_REQ , MESSAGE_PRIORITY_MED, m2ap_enb_setup_req_t , f1ap_enb_setup_req)
/* eNB_DU application layer -> M2AP messages or CU M2AP -> RRC*/
MESSAGE_DEF(M2AP_SETUP_REQ , MESSAGE_PRIORITY_MED, m2ap_setup_req_t , m2ap_setup_req)
MESSAGE_DEF(M2AP_SETUP_RESP , MESSAGE_PRIORITY_MED, m2ap_setup_resp_t , m2ap_setup_resp)
MESSAGE_DEF(M2AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED, m2ap_setup_failure_t , m2ap_setup_failure)
MESSAGE_DEF(M2AP_RESET , MESSAGE_PRIORITY_MED, m2ap_reset_t , m2ap_reset)
MESSAGE_DEF(M2AP_REGISTER_MCE_REQ , MESSAGE_PRIORITY_MED, m2ap_register_mce_req_t , m2ap_register_mce_req)
MESSAGE_DEF(M2AP_MBMS_SCHEDULING_INFORMATION , MESSAGE_PRIORITY_MED, m2ap_mbms_scheduling_information_t , m2ap_mbms_scheduling_information)
MESSAGE_DEF(M2AP_MBMS_SCHEDULING_INFORMATION_RESP , MESSAGE_PRIORITY_MED, m2ap_mbms_scheduling_information_resp_t , m2ap_mbms_scheduling_information_resp)
MESSAGE_DEF(M2AP_MBMS_SESSION_START_REQ , MESSAGE_PRIORITY_MED, m2ap_session_start_req_t ,m2ap_session_start_req )
MESSAGE_DEF(M2AP_MBMS_SESSION_START_RESP , MESSAGE_PRIORITY_MED, m2ap_session_start_resp_t ,m2ap_session_start_resp )
MESSAGE_DEF(M2AP_MBMS_SESSION_START_FAILURE , MESSAGE_PRIORITY_MED, m2ap_session_start_failure_t ,m2ap_session_start_failure )
MESSAGE_DEF(M2AP_MBMS_SESSION_STOP_REQ , MESSAGE_PRIORITY_MED, m2ap_session_stop_req_t ,m2ap_session_stop_req )
MESSAGE_DEF(M2AP_MBMS_SESSION_STOP_RESP , MESSAGE_PRIORITY_MED, m2ap_session_stop_resp_t ,m2ap_session_stop_resp )
MESSAGE_DEF(M2AP_ENB_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED, m2ap_enb_configuration_update_t, m2ap_enb_configuration_update )
MESSAGE_DEF(M2AP_ENB_CONFIGURATION_UPDATE_ACK , MESSAGE_PRIORITY_MED, m2ap_enb_configuration_update_ack_t, m2ap_enb_configuration_update_ack )
MESSAGE_DEF(M2AP_ENB_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, m2ap_enb_configuration_update_failure_t, m2ap_enb_configuration_update_failure )
MESSAGE_DEF(M2AP_MCE_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED, m2ap_mce_configuration_update_t, m2ap_mce_configuration_update )
MESSAGE_DEF(M2AP_MCE_CONFIGURATION_UPDATE_ACK , MESSAGE_PRIORITY_MED, m2ap_mce_configuration_update_ack_t, m2ap_mce_configuration_update_ack )
MESSAGE_DEF(M2AP_MCE_CONFIGURATION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, m2ap_mce_configuration_update_failure_t, m2ap_mce_configuration_update_failure )
MESSAGE_DEF(M2AP_ERROR_INDICATION , MESSAGE_PRIORITY_MED, m2ap_error_indication_t, m2ap_error_indication )
MESSAGE_DEF(M2AP_MBMS_SESSION_UPDATE_REQ , MESSAGE_PRIORITY_MED, m2ap_mbms_session_update_req_t, m2ap_mbms_session_update_req )
MESSAGE_DEF(M2AP_MBMS_SESSION_UPDATE_RESP , MESSAGE_PRIORITY_MED, m2ap_mbms_session_update_resp_t, m2ap_mbms_session_update_resp )
MESSAGE_DEF(M2AP_MBMS_SESSION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED, m2ap_mbms_session_update_failure_t, m2ap_mbms_session_update_failure )
MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_REPORT , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_report_t, m2ap_mbms_service_counting_report )
MESSAGE_DEF(M2AP_MBMS_OVERLOAD_NOTIFICATION , MESSAGE_PRIORITY_MED, m2ap_mbms_overload_notification_t, m2ap_mbms_overload_notification )
MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_REQ , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_req_t, m2ap_mbms_service_counting_req )
MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_RESP , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_resp_t, m2ap_mbms_service_counting_resp )
MESSAGE_DEF(M2AP_MBMS_SERVICE_COUNTING_FAILURE , MESSAGE_PRIORITY_MED, m2ap_mbms_service_counting_failure_t, m2ap_mbms_service_counting_failure )
+666
View File
@@ -0,0 +1,666 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef M2AP_MESSAGES_TYPES_H_
#define M2AP_MESSAGES_TYPES_H_
#include "s1ap_messages_types.h"
#include "LTE_PhysCellId.h"
//-------------------------------------------------------------------------------------------//
// Defines to access message fields.
#define M2AP_MCE_SCTP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_sctp_req
#define M2AP_REGISTER_ENB_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_register_enb_req
//#define M2AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_handover_req
//#define M2AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.m2ap_handover_req_ack
#define M2AP_REGISTER_ENB_CNF(mSGpTR) (mSGpTR)->ittiMsg.m2ap_register_enb_cnf
#define M2AP_DEREGISTERED_ENB_IND(mSGpTR) (mSGpTR)->ittiMsg.m2ap_deregistered_enb_ind
//#define M2AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_ue_context_release
//#define M2AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.m2ap_handover_cancel
#define M2AP_ENB_SCTP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_sctp_req
#define M2AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_setup_req
#define M2AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_setup_resp
#define M2AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_setup_failure
#define M2AP_REGISTER_MCE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_register_mce_req
#define M2AP_MBMS_SCHEDULING_INFORMATION(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_scheduling_information
#define M2AP_MBMS_SCHEDULING_INFORMATION_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_scheduling_information_resp
#define M2AP_MBMS_SESSION_START_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_start_req
#define M2AP_MBMS_SESSION_START_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_start_resp
#define M2AP_MBMS_SESSION_START_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_start_failure
#define M2AP_MBMS_SESSION_STOP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_stop_req
#define M2AP_MBMS_SESSION_STOP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_session_stop_resp
#define M2AP_RESET(mSGpTR) (mSGpTR)->ittiMsg.m2ap_reset
#define M2AP_ENB_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_configuration_update
#define M2AP_ENB_CONFIGURATION_UPDATE_ACK(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_configuration_update_ack
#define M2AP_ENB_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_enb_configuration_update_failure
#define M2AP_MCE_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_configuration_update
#define M2AP_MCE_CONFIGURATION_UPDATE_ACK(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_configuration_update_ack
#define M2AP_MCE_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mce_configuration_update_failure
#define M2AP_ERROR_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.m2ap_error_indication
#define M2AP_MBMS_SESSION_UPDATE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_session_update_req
#define M2AP_MBMS_SESSION_UPDATE_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_session_update_resp
#define M2AP_MBMS_SESSION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_session_update_failure
#define M2AP_MBMS_SERVICE_COUNTING_REPORT(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_report
#define M2AP_MBMS_OVERLOAD_NOTIFICATION(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_overload_notification
#define M2AP_MBMS_SERVICE_COUNTING_REQ(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_req
#define M2AP_MBMS_SERVICE_COUNTING_RESP(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_resp
#define M2AP_MBMS_SERVICE_COUNTING_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m2ap_mbms_service_counting_failure
#define M2AP_MAX_NB_ENB_IP_ADDRESS 2
#define M2AP_MAX_NB_MCE_IP_ADDRESS 2
#define M2AP_MAX_NB_CELLS 2
typedef struct m2ap_net_ip_address_s {
unsigned ipv4:1;
unsigned ipv6:1;
char ipv4_address[16];
char ipv6_address[46];
} m2ap_net_ip_address_t;
typedef struct m2ap_enb_setup_req_s {
//
} m2ap_enb_setup_req_t;
typedef struct m2ap_setup_req_s {
// Midhaul networking parameters
/* Connexion id used between SCTP/M2AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* The eNB IP address to bind */
m2ap_net_ip_address_t MCE_M2_ip_address;
m2ap_net_ip_address_t ENB_M2_ip_address;
/* Number of SCTP streams used for a mme association */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint16_t default_sctp_stream_id;
// M2_Setup_Req payload
uint64_t eNB_id;
char *eNB_name;
uint64_t GlobalENB_ID;
char * ENBname;
uint16_t num_mbms_available;
/* M2AP_MBSFN_SynchronisationArea_ID_t */
long mbsfn_synchronization_area[M2AP_MAX_NB_CELLS];
/* eCGI->eCGI.pLMN_Identity */
uint16_t plmn_identity[M2AP_MAX_NB_CELLS];
/* eCGI->eCGI.eUTRANcellIdentifier */
uint16_t eutran_cell_identifier[M2AP_MAX_NB_CELLS];
struct{
uint16_t mbsfn_sync_area;
uint16_t mbms_service_area_list[8];
uint16_t num_mbms_service_area_list;
}mbms_configuration_data_list[8];
uint16_t num_mbms_configuration_data_list;
//
// /* The type of the cell */
// enum cell_type_e cell_type;
//
// /// number of DU cells available
// uint16_t num_cells_available; //0< num_cells_available <= 512;
//
// //
// uint16_t num_mbms_available;
//
// // Served Cell Information
// /* Tracking area code */
// uint16_t tac[M2AP_MAX_NB_CELLS];
//
// /* Mobile Country Codes
// * Mobile Network Codes
// */
// uint16_t mcc[M2AP_MAX_NB_CELLS];//[6];
// uint16_t mnc[M2AP_MAX_NB_CELLS];//[6];
// uint8_t mnc_digit_length[M2AP_MAX_NB_CELLS];//[6];
//
// // NR Global Cell Id
// uint64_t nr_cellid[M2AP_MAX_NB_CELLS];
// // NR Physical Cell Ids
// uint16_t nr_pci[M2AP_MAX_NB_CELLS];
// // Number of slide support items (max 16, could be increased to as much as 1024)
// uint16_t num_ssi[M2AP_MAX_NB_CELLS];//[6];
// uint8_t sst[M2AP_MAX_NB_CELLS];//[16][6];
// uint8_t sd[M2AP_MAX_NB_CELLS];//[16][6];
// // fdd_flag = 1 means FDD, 0 means TDD
// int fdd_flag;
//
// /* eCGI->eCGI.pLMN_Identity */
// uint16_t plmn_identity[M2AP_MAX_NB_CELLS];
// /* eCGI->eCGI.eUTRANcellIdentifier */
// uint16_t eutran_cell_identifier[M2AP_MAX_NB_CELLS];
//
// /* M2AP_MBSFN_SynchronisationArea_ID_t */
// long mbsfn_synchronization_area[M2AP_MAX_NB_CELLS];
//
// uint16_t service_area_id[M2AP_MAX_NB_CELLS][4];
//
// union {
// struct {
// uint32_t ul_nr_arfcn;
// uint8_t ul_scs;
// uint8_t ul_nrb;
//
// uint32_t dl_nr_arfcn;
// uint8_t dl_scs;
// uint8_t dl_nrb;
//
// uint32_t sul_active;
// uint32_t sul_nr_arfcn;
// uint8_t sul_scs;
// uint8_t sul_nrb;
//
// uint8_t ul_num_frequency_bands;
// uint16_t ul_nr_band[32];
// uint8_t ul_num_sul_frequency_bands;
// uint16_t ul_nr_sul_band[32];
//
// uint8_t dl_num_frequency_bands;
// uint16_t dl_nr_band[32];
// uint8_t dl_num_sul_frequency_bands;
// uint16_t dl_nr_sul_band[32];
// } fdd;
// struct {
//
// uint32_t nr_arfcn;
// uint8_t scs;
// uint8_t nrb;
//
// uint32_t sul_active;
// uint32_t sul_nr_arfcn;
// uint8_t sul_scs;
// uint8_t sul_nrb;
//
// uint8_t num_frequency_bands;
// uint16_t nr_band[32];
// uint8_t num_sul_frequency_bands;
// uint16_t nr_sul_band[32];
//
// } tdd;
// } nr_mode_info[M2AP_MAX_NB_CELLS];
//
// char *measurement_timing_information[M2AP_MAX_NB_CELLS];
// uint8_t ranac[M2AP_MAX_NB_CELLS];
//
// // System Information
// uint8_t *mib[M2AP_MAX_NB_CELLS];
// int mib_length[M2AP_MAX_NB_CELLS];
// uint8_t *sib1[M2AP_MAX_NB_CELLS];
// int sib1_length[M2AP_MAX_NB_CELLS];
} m2ap_setup_req_t;
typedef struct m2ap_setup_resp_s {
struct {
uint8_t mbsfn_area;
uint8_t pdcch_length;
uint8_t repetition_period;
uint8_t offset;
uint8_t modification_period;
uint8_t subframe_allocation_info;
uint8_t mcs;
} mcch_config_per_mbsfn[8];
/* Connexion id used between SCTP/M2AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Number of SCTP streams used for a mme association */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint64_t MCE_id;
char *MCE_name;
uint8_t num_mcch_config_per_mbsfn;
// /// string holding gNB_CU_name
// char *gNB_CU_name;
// /// number of DU cells to activate
// uint16_t num_cells_to_activate; //0< num_cells_to_activate <= 512;
// /// mcc of DU cells
// //uint16_t mcc[M2AP_MAX_NB_CELLS];
uint16_t mcc;//[M2AP_MAX_NB_CELLS];
/// mnc of DU cells
//uint16_t mnc[M2AP_MAX_NB_CELLS];
uint16_t mnc;//[M2AP_MAX_NB_CELLS];
/// mnc digit length of DU cells
//uint8_t mnc_digit_length[M2AP_MAX_NB_CELLS];
uint8_t mnc_digit_length;//[M2AP_MAX_NB_CELLS];
// NR Global Cell Id
// uint64_t nr_cellid[M2AP_MAX_NB_CELLS];
// /// NRPCI
// uint16_t nrpci[M2AP_MAX_NB_CELLS];
// /// num SI messages per DU cell
// uint8_t num_SI[M2AP_MAX_NB_CELLS];
// /// SI message containers (up to 21 messages per cell)
// uint8_t *SI_container[M2AP_MAX_NB_CELLS][21];
// int SI_container_length[M2AP_MAX_NB_CELLS][21];
} m2ap_setup_resp_t;
typedef struct m2ap_setup_failure_s {
uint16_t cause;
uint16_t time_to_wait;
uint16_t criticality_diagnostics;
} m2ap_setup_failure_t;
// eNB application layer -> M2AP messages
/* M2AP UE CONTEXT RELEASE */
//typedef struct m2ap_ue_context_release_s {
// /* used for M2AP->RRC in source and RRC->M2AP in target */
// int rnti;
//
// int source_assoc_id;
//} m2ap_ue_context_release_t;
//typedef enum {
// M2AP_T_RELOC_PREP_TIMEOUT,
// M2AP_TX2_RELOC_OVERALL_TIMEOUT
//} m2ap_handover_cancel_cause_t;
//typedef struct m2ap_handover_cancel_s {
// int rnti;
// m2ap_handover_cancel_cause_t cause;
//} m2ap_handover_cancel_t;
typedef struct m2ap_register_mce_req_s {
/* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long.
* For home eNB ids this field should be 28 bits long.
*/
uint32_t MCE_id;
/* The type of the cell */
enum cell_type_e cell_type;
/* Optional name for the cell
* NOTE: the name can be NULL (i.e no name) and will be cropped to 150
* characters.
*/
char *MCE_name;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/*
* CC Params
*/
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
/* To be considered for TDD */
//uint16_t tdd_EARFCN;
//uint16_t tdd_Transmission_Bandwidth;
/* The local eNB IP address to bind */
net_ip_address_t mce_m2_ip_address;
/* Nb of MME to connect to */
uint8_t nb_m2;
/* List of target eNB to connect to for M2*/
net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_ENB_IP_ADDRESS];
/* Number of SCTP streams used for associations */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
/* eNB port for M2C*/
uint32_t mce_port_for_M2C;
/* timers (unit: millisecond) */
int t_reloc_prep;
int tm2_reloc_overall;
} m2ap_register_mce_req_t;
typedef struct m2ap_register_enb_req_s {
/* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long.
* For home eNB ids this field should be 28 bits long.
*/
uint32_t eNB_id;
/* The type of the cell */
enum cell_type_e cell_type;
/* Optional name for the cell
* NOTE: the name can be NULL (i.e no name) and will be cropped to 150
* characters.
*/
char *eNB_name;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
struct{
uint16_t mbsfn_sync_area;
uint16_t mbms_service_area_list[8];
uint16_t num_mbms_service_area_list;
}mbms_configuration_data_list[8];
uint16_t num_mbms_configuration_data_list;
/*
* CC Params
*/
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
/* To be considered for TDD */
//uint16_t tdd_EARFCN;
//uint16_t tdd_Transmission_Bandwidth;
/* The local eNB IP address to bind */
net_ip_address_t enb_m2_ip_address;
/* Nb of MME to connect to */
uint8_t nb_m2;
/* List of target eNB to connect to for M2*/
net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_ENB_IP_ADDRESS];
/* Number of SCTP streams used for associations */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
/* eNB port for M2C*/
uint32_t enb_port_for_M2C;
/* timers (unit: millisecond) */
int t_reloc_prep;
int tm2_reloc_overall;
} m2ap_register_enb_req_t;
typedef struct m2ap_subframe_process_s {
/* nothing, we simply use the module ID in the header */
} m2ap_subframe_process_t;
//-------------------------------------------------------------------------------------------//
// M2AP -> eNB application layer messages
typedef struct m2ap_register_enb_cnf_s {
/* Nb of connected eNBs*/
uint8_t nb_m2;
} m2ap_register_enb_cnf_t;
typedef struct m2ap_deregistered_enb_ind_s {
/* Nb of connected eNBs */
uint8_t nb_m2;
} m2ap_deregistered_enb_ind_t;
typedef struct m2ap_mbms_scheduling_information_s {
uint16_t mcch_update_time;
struct{
uint8_t common_sf_allocation_period;
uint8_t mbms_area_id;
struct{
uint8_t allocated_sf_end;
uint8_t data_mcs;
uint8_t mch_scheduling_period;
struct{
//struct{
uint32_t service_id;
uint16_t lcid;
uint8_t mcc;
uint8_t mnc;
uint8_t mnc_length;
//}mbms_session_per_pmch[8];
//int num_mbms_session_per_pmch;
}mbms_session_list[8];
int num_mbms_session_list;
}pmch_config_list[8];
int num_pmch_config_list;
struct{
uint8_t radioframe_allocation_period;
uint8_t radioframe_allocation_offset;
uint8_t is_four_sf;
uint32_t subframe_allocation;
}mbms_sf_config_list[8];
int num_mbms_sf_config_list;
}mbms_area_config_list[8];
uint8_t num_mbms_area_config_list;
uint16_t mcc[M2AP_MAX_NB_CELLS];//[6];
uint16_t mnc[M2AP_MAX_NB_CELLS];//[6];
uint8_t mnc_digit_length[M2AP_MAX_NB_CELLS];//[6];
uint8_t TMGI[5]; // {4,3,2,1,0};
uint8_t is_one_frame;
uint8_t buf1; //i.e 0x38<<2
uint8_t buf2; //i.e 0x38<<2
uint8_t buf3; //i.e 0x38<<2
uint16_t common_subframe_allocation_period;
} m2ap_mbms_scheduling_information_t;
typedef struct m2ap_mce_sctp_req_s {
/* The local MCE IP address to bind */
net_ip_address_t mce_m2_ip_address;
/* eNB port for M2C*/
uint32_t mce_port_for_M2C;
}m2ap_mce_sctp_req_t;
typedef struct m2ap_mbms_scheduling_information_resp_s {
} m2ap_mbms_scheduling_information_resp_t;
typedef struct m2ap_session_start_req_s {
} m2ap_session_start_req_t;
typedef struct m2ap_session_start_resp_s {
} m2ap_session_start_resp_t;
typedef struct m2ap_session_start_failure_s {
} m2ap_session_start_failure_t;
typedef struct m2ap_session_stop_req_s {
} m2ap_session_stop_req_t;
typedef struct m2ap_session_stop_resp_s {
} m2ap_session_stop_resp_t;
typedef struct m2ap_reset_s {
} m2ap_reset_t;
typedef struct m2ap_enb_configuration_update_s {
} m2ap_enb_configuration_update_t;
typedef struct m2ap_enb_configuration_update_ack_s {
} m2ap_enb_configuration_update_ack_t;
typedef struct m2ap_enb_configuration_update_failure_s {
} m2ap_enb_configuration_update_failure_t;
typedef struct m2ap_mce_configuration_update_s {
} m2ap_mce_configuration_update_t;
typedef struct m2ap_mce_configuration_update_ack_s {
} m2ap_mce_configuration_update_ack_t;
typedef struct m2ap_mce_configuration_update_failure_s {
} m2ap_mce_configuration_update_failure_t;
typedef struct m2ap_error_indication_s {
}m2ap_error_indication_t;
typedef struct m2ap_mbms_session_update_req_s {
} m2ap_mbms_session_update_req_t;
typedef struct m2ap_mbms_session_update_resp_s {
} m2ap_mbms_session_update_resp_t;
typedef struct m2ap_mbms_session_update_failure_s {
} m2ap_mbms_session_update_failure_t;
typedef struct m2ap_mbms_service_counting_report_s {
} m2ap_mbms_service_counting_report_t;
typedef struct m2ap_mbms_overload_notification_s {
} m2ap_mbms_overload_notification_t;
typedef struct m2ap_mbms_service_counting_req_s {
} m2ap_mbms_service_counting_req_t;
typedef struct m2ap_mbms_service_counting_resp_s {
} m2ap_mbms_service_counting_resp_t;
typedef struct m2ap_mbms_service_counting_failure_s {
} m2ap_mbms_service_counting_failure_t;
//-------------------------------------------------------------------------------------------//
// M2AP <-> RRC
//typedef struct m2ap_gummei_s {
// uint16_t mcc;
// uint16_t mnc;
// uint8_t mnc_len;
// uint8_t mme_code;
// uint16_t mme_group_id;
//} m2ap_gummei_t;
//
//typedef struct m2ap_lastvisitedcell_info_s {
// uint16_t mcc;
// uint16_t mnc;
// uint8_t mnc_len;
// LTE_PhysCellId_t target_physCellId;
// cell_type_t cell_type;
// uint64_t time_UE_StayedInCell;
//}m2ap_lastvisitedcell_info_t;
//
//typedef struct m2ap_handover_req_s {
// /* used for RRC->M2AP in source eNB */
// int rnti;
//
// /* used for M2AP->RRC in target eNB */
// int x2_id;
//
// LTE_PhysCellId_t target_physCellId;
//
// m2ap_gummei_t ue_gummei;
//
// /*UE-ContextInformation */
//
// /* MME UE id */
// uint32_t mme_ue_s1ap_id;
//
// security_capabilities_t security_capabilities;
//
// uint8_t kenb[32]; // keNB or keNB*
//
// /*next_hop_chaining_coun */
// long int kenb_ncc;
//
// /* UE aggregate maximum bitrate */
// ambr_t ue_ambr;
//
// uint8_t nb_e_rabs_tobesetup;
//
// /* list of e_rab setup-ed by RRC layers */
// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB];
//
// /* list of e_rab to be setup by RRC layers */
// e_rab_t e_rab_param[S1AP_MAX_E_RAB];
//
// m2ap_lastvisitedcell_info_t lastvisitedcell_info;
//
// uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
// int rrc_buffer_size;
//
// int target_assoc_id;
//} m2ap_handover_req_t;
//
//typedef struct m2ap_handover_req_ack_s {
// /* used for RRC->M2AP in target and M2AP->RRC in source */
// int rnti;
//
// /* used for RRC->M2AP in target */
// int x2_id_target;
//
// int source_assoc_id;
//
// uint8_t nb_e_rabs_tobesetup;
//
// /* list of e_rab setup-ed by RRC layers */
// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB];
//
// /* list of e_rab to be setup by RRC layers */
// e_rab_t e_rab_param[S1AP_MAX_E_RAB];
//
// uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
// int rrc_buffer_size;
//
// uint32_t mme_ue_s1ap_id;
//} m2ap_handover_req_ack_t;
//
#endif /* M2AP_MESSAGES_TYPES_H_ */
+71
View File
@@ -0,0 +1,71 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/* eNB application layer -> M3AP messages */
/* ITTI LOG messages */
/* ENCODER */
MESSAGE_DEF(M3AP_RESET_REQUST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_reset_request_log)
MESSAGE_DEF(M3AP_RESOURCE_STATUS_RESPONSE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_resource_status_response_log)
MESSAGE_DEF(M3AP_RESOURCE_STATUS_FAILURE_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_resource_status_failure_log)
/* Messages for M3AP logging */
MESSAGE_DEF(M3AP_SETUP_REQUEST_LOG , MESSAGE_PRIORITY_MED, IttiMsgText , m3ap_setup_request_log)
/* eNB application layer -> M3AP messages */
MESSAGE_DEF(M3AP_REGISTER_MCE_REQ , MESSAGE_PRIORITY_MED, m3ap_register_mce_req_t , m3ap_register_mce_req)
MESSAGE_DEF(M3AP_SUBFRAME_PROCESS , MESSAGE_PRIORITY_MED, m3ap_subframe_process_t , m3ap_subframe_process)
/* M3AP -> eNB application layer messages */
MESSAGE_DEF(M3AP_REGISTER_MCE_CNF , MESSAGE_PRIORITY_MED, m3ap_register_mce_cnf_t , m3ap_register_mce_cnf)
MESSAGE_DEF(M3AP_DEREGISTERED_MCE_IND , MESSAGE_PRIORITY_MED, m3ap_deregistered_mce_ind_t , m3ap_deregistered_mce_ind)
/* handover messages M3AP <-> RRC */
//MESSAGE_DEF(M3AP_HANDOVER_REQ , MESSAGE_PRIORITY_MED, m3ap_handover_req_t , m3ap_handover_req)
//MESSAGE_DEF(M3AP_HANDOVER_REQ_ACK , MESSAGE_PRIORITY_MED, m3ap_handover_req_ack_t , m3ap_handover_req_ack)
//MESSAGE_DEF(M3AP_HANDOVER_CANCEL , MESSAGE_PRIORITY_MED, m3ap_handover_cancel_t , m3ap_handover_cancel)
/* handover messages M3AP <-> S1AP */
//MESSAGE_DEF(M3AP_UE_CONTEXT_RELEASE , MESSAGE_PRIORITY_MED, m3ap_ue_context_release_t , m3ap_ue_context_release)
MESSAGE_DEF(M3AP_MME_SCTP_REQ , MESSAGE_PRIORITY_MED, m3ap_mme_sctp_req_t , m3ap_mme_sctp_req)
MESSAGE_DEF(M3AP_MBMS_SESSION_START_REQ , MESSAGE_PRIORITY_MED ,m3ap_session_start_req_t ,m3ap_session_start_req)
MESSAGE_DEF(M3AP_MBMS_SESSION_START_RESP , MESSAGE_PRIORITY_MED ,m3ap_session_start_resp_t ,m3ap_session_start_resp)
MESSAGE_DEF(M3AP_MBMS_SESSION_START_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_session_start_failure_t ,m3ap_session_start_failure)
MESSAGE_DEF(M3AP_MBMS_SESSION_STOP_REQ , MESSAGE_PRIORITY_MED ,m3ap_session_stop_req_t ,m3ap_session_stop_req)
MESSAGE_DEF(M3AP_MBMS_SESSION_STOP_RESP , MESSAGE_PRIORITY_MED ,m3ap_session_stop_resp_t ,m3ap_session_stop_resp)
MESSAGE_DEF(M3AP_MBMS_SESSION_STOP_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_session_stop_failure_t ,m3ap_session_stop_failure)
MESSAGE_DEF(M3AP_ERROR_INDICATION , MESSAGE_PRIORITY_MED ,m3ap_error_indication_t ,m3ap_error_indication)
MESSAGE_DEF(M3AP_RESET , MESSAGE_PRIORITY_MED ,m3ap_reset_t ,m3ap_reset)
MESSAGE_DEF(M3AP_RESET_ACK , MESSAGE_PRIORITY_MED ,m3ap_reset_ack_t ,m3ap_reset_ack)
MESSAGE_DEF(M3AP_MBMS_SESSION_UPDATE_REQ , MESSAGE_PRIORITY_MED ,m3ap_mbms_session_update_req_t ,m3ap_mbms_session_update_req)
MESSAGE_DEF(M3AP_MBMS_SESSION_UPDATE_RESP , MESSAGE_PRIORITY_MED ,m3ap_mbms_session_update_resp_t ,m3ap_mbms_session_update_resp)
MESSAGE_DEF(M3AP_MBMS_SESSION_UPDATE_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_mbms_session_update_failure_t ,m3ap_mbms_session_update_failure)
MESSAGE_DEF(M3AP_SETUP_REQ , MESSAGE_PRIORITY_MED ,m3ap_setup_req_t ,m3ap_setup_req)
MESSAGE_DEF(M3AP_SETUP_RESP , MESSAGE_PRIORITY_MED ,m3ap_setup_resp_t ,m3ap_setup_resp)
MESSAGE_DEF(M3AP_SETUP_FAILURE , MESSAGE_PRIORITY_MED ,m3ap_setup_failure_t ,m3ap_setup_failure)
MESSAGE_DEF(M3AP_MCE_CONFIGURATION_UPDATE , MESSAGE_PRIORITY_MED ,m3ap_mce_configuration_update_t ,m3ap_mce_configuration_update)
MESSAGE_DEF(M3AP_MCE_CONFIGURATION_UPDATE_ACK , MESSAGE_PRIORITY_MED ,m3ap_mce_configuration_update_ack_t ,m3ap_mce_configuration_update_ack)
MESSAGE_DEF(M3AP_MCE_CONFIGURATION_UPDATE_FAILURE, MESSAGE_PRIORITY_MED ,m3ap_mce_configuration_update_failure_t ,m3ap_mce_configuration_update_failure)
+330
View File
@@ -0,0 +1,330 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#ifndef M3AP_MESSAGES_TYPES_H_
#define M3AP_MESSAGES_TYPES_H_
#include "s1ap_messages_types.h"
#include "LTE_PhysCellId.h"
//-------------------------------------------------------------------------------------------//
// Defines to access message fields.
#define M3AP_MME_SCTP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mme_sctp_req
#define M3AP_REGISTER_MCE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_register_mce_req
//#define M3AP_HANDOVER_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_handover_req
//#define M3AP_HANDOVER_REQ_ACK(mSGpTR) (mSGpTR)->ittiMsg.m3ap_handover_req_ack
#define M3AP_REGISTER_MCE_CNF(mSGpTR) (mSGpTR)->ittiMsg.m3ap_register_mce_cnf
#define M3AP_DEREGISTERED_MCE_IND(mSGpTR) (mSGpTR)->ittiMsg.m3ap_deregistered_mce_ind
//#define M3AP_UE_CONTEXT_RELEASE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_ue_context_release
//#define M3AP_HANDOVER_CANCEL(mSGpTR) (mSGpTR)->ittiMsg.m3ap_handover_cancel
#define M3AP_MBMS_SESSION_START_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_start_req
#define M3AP_MBMS_SESSION_START_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_start_resp
#define M3AP_MBMS_SESSION_START_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_start_failure
#define M3AP_MBMS_SESSION_STOP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_stop_req
#define M3AP_MBMS_SESSION_STOP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_stop_resp
#define M3AP_MBMS_SESSION_STOP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_session_stop_failure
#define M3AP_ERROR_INDICATION(mSGpTR) (mSGpTR)->ittiMsg.m3ap_error_indication
#define M3AP_RESET(mSGpTR) (mSGpTR)->ittiMsg.m3ap_reset
#define M3AP_RESET_ACK(mSGpTR) (mSGpTR)->ittiMsg.m3ap_reset_ack
#define M3AP_MBMS_SESSION_UPDATE_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mbms_session_update_req
#define M3AP_MBMS_SESSION_UPDATE_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mbms_session_update_resp
#define M3AP_MBMS_SESSION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mbms_session_update_failure
#define M3AP_SETUP_REQ(mSGpTR) (mSGpTR)->ittiMsg.m3ap_setup_req
#define M3AP_SETUP_RESP(mSGpTR) (mSGpTR)->ittiMsg.m3ap_setup_resp
#define M3AP_SETUP_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_setup_failure
#define M3AP_MCE_CONFIGURATION_UPDATE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mce_configuration_update
#define M3AP_MCE_CONFIGURATION_UPDATE_ACK(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mce_configuration_update_ack
#define M3AP_MCE_CONFIGURATION_UPDATE_FAILURE(mSGpTR) (mSGpTR)->ittiMsg.m3ap_mce_configuration_update_failure
#define M3AP_MAX_NB_MCE_IP_ADDRESS 2
#define M3AP_MAX_NB_MME_IP_ADDRESS 2
typedef struct m3ap_net_ip_address_s {
unsigned ipv4:1;
unsigned ipv6:1;
char ipv4_address[16];
char ipv6_address[46];
} m3ap_net_ip_address_t;
// eNB application layer -> M3AP messages
/* M3AP UE CONTEXT RELEASE */
//typedef struct m3ap_ue_context_release_s {
// /* used for M3AP->RRC in source and RRC->M3AP in target */
// int rnti;
//
// int source_assoc_id;
//} m3ap_ue_context_release_t;
//typedef enum {
// M3AP_T_RELOC_PREP_TIMEOUT,
// M3AP_TX2_RELOC_OVERALL_TIMEOUT
//} m3ap_handover_cancel_cause_t;
//typedef struct m3ap_handover_cancel_s {
// int rnti;
// m3ap_handover_cancel_cause_t cause;
//} m3ap_handover_cancel_t;
typedef struct m3ap_register_mce_req_s {
/* Unique eNB_id to identify the eNB within EPC.
* For macro eNB ids this field should be 20 bits long.
* For home eNB ids this field should be 28 bits long.
*/
uint32_t MCE_id;
/* The type of the cell */
enum cell_type_e cell_type;
/* Optional name for the cell
* NOTE: the name can be NULL (i.e no name) and will be cropped to 150
* characters.
*/
char *MCE_name;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/*
* CC Params
*/
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
/* To be considered for TDD */
//uint16_t tdd_EARFCN;
//uint16_t tdd_Transmission_Bandwidth;
/* The local eNB IP address to bind */
net_ip_address_t mme_m3_ip_address;
/* Nb of MME to connect to */
uint8_t nb_m3;
/* List of target eNB to connect to for M3*/
net_ip_address_t target_mme_m3_ip_address[M3AP_MAX_NB_MCE_IP_ADDRESS];
/* Number of SCTP streams used for associations */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
/* eNB port for M3C*/
uint32_t mme_port_for_M3C;
/* timers (unit: millisecond) */
int t_reloc_prep;
int tm3_reloc_overall;
/* Nb of MME to connect to */
uint8_t nb_mme;
/* List of MME to connect to */
net_ip_address_t mme_ip_address[M3AP_MAX_NB_MME_IP_ADDRESS];
} m3ap_register_mce_req_t;
typedef struct m3ap_subframe_process_s {
/* nothing, we simply use the module ID in the header */
} m3ap_subframe_process_t;
//-------------------------------------------------------------------------------------------//
// M3AP -> eNB application layer messages
typedef struct m3ap_register_mce_cnf_s {
/* Nb of connected eNBs*/
uint8_t nb_mme;
} m3ap_register_mce_cnf_t;
typedef struct m3ap_deregistered_mce_ind_s {
/* Nb of connected eNBs */
uint8_t nb_mme;
} m3ap_deregistered_mce_ind_t;
//-------------------------------------------------------------------------------------------//
// M3AP <-> RRC
//typedef struct m3ap_gummei_s {
// uint16_t mcc;
// uint16_t mnc;
// uint8_t mnc_len;
// uint8_t mme_code;
// uint16_t mme_group_id;
//} m3ap_gummei_t;
//
//typedef struct m3ap_lastvisitedcell_info_s {
// uint16_t mcc;
// uint16_t mnc;
// uint8_t mnc_len;
// LTE_PhysCellId_t target_physCellId;
// cell_type_t cell_type;
// uint64_t time_UE_StayedInCell;
//}m3ap_lastvisitedcell_info_t;
//
//typedef struct m3ap_handover_req_s {
// /* used for RRC->M3AP in source eNB */
// int rnti;
//
// /* used for M3AP->RRC in target eNB */
// int x2_id;
//
// LTE_PhysCellId_t target_physCellId;
//
// m3ap_gummei_t ue_gummei;
//
// /*UE-ContextInformation */
//
// /* MME UE id */
// uint32_t mme_ue_s1ap_id;
//
// security_capabilities_t security_capabilities;
//
// uint8_t kenb[32]; // keNB or keNB*
//
// /*next_hop_chaining_coun */
// long int kenb_ncc;
//
// /* UE aggregate maximum bitrate */
// ambr_t ue_ambr;
//
// uint8_t nb_e_rabs_tobesetup;
//
// /* list of e_rab setup-ed by RRC layers */
// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB];
//
// /* list of e_rab to be setup by RRC layers */
// e_rab_t e_rab_param[S1AP_MAX_E_RAB];
//
// m3ap_lastvisitedcell_info_t lastvisitedcell_info;
//
// uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
// int rrc_buffer_size;
//
// int target_assoc_id;
//} m3ap_handover_req_t;
//
//typedef struct m3ap_handover_req_ack_s {
// /* used for RRC->M3AP in target and M3AP->RRC in source */
// int rnti;
//
// /* used for RRC->M3AP in target */
// int x2_id_target;
//
// int source_assoc_id;
//
// uint8_t nb_e_rabs_tobesetup;
//
// /* list of e_rab setup-ed by RRC layers */
// e_rab_setup_t e_rabs_tobesetup[S1AP_MAX_E_RAB];
//
// /* list of e_rab to be setup by RRC layers */
// e_rab_t e_rab_param[S1AP_MAX_E_RAB];
//
// uint8_t rrc_buffer[1024 /* arbitrary, big enough */];
// int rrc_buffer_size;
//
// uint32_t mme_ue_s1ap_id;
//} m3ap_handover_req_ack_t;
//
typedef struct m3ap_mme_sctp_req_s {
/* the local mce ip address to bind */
net_ip_address_t mme_m3_ip_address;
/* enb port for m2c*/
uint32_t mme_port_for_M3C;
}m3ap_mme_sctp_req_t;
typedef struct m3ap_session_start_req_s{
}m3ap_session_start_req_t;
typedef struct m3ap_session_start_resp_s{
}m3ap_session_start_resp_t;
typedef struct m3ap_session_start_failure_s{
}m3ap_session_start_failure_t;
typedef struct m3ap_session_stop_req_s{
}m3ap_session_stop_req_t;
typedef struct m3ap_session_stop_resp_s{
}m3ap_session_stop_resp_t;
typedef struct m3ap_session_stop_failure_s{
}m3ap_session_stop_failure_t;
typedef struct m3ap_error_indication_s{
}m3ap_error_indication_t;
typedef struct m3ap_reset_s{
}m3ap_reset_t;
typedef struct m3ap_reset_ack_s{
}m3ap_reset_ack_t;
typedef struct m3ap_mbms_session_update_req_s{
}m3ap_mbms_session_update_req_t;
typedef struct m3ap_mbms_session_update_resp_s{
}m3ap_mbms_session_update_resp_t;
typedef struct m3ap_mbms_session_update_failure_s{
}m3ap_mbms_session_update_failure_t;
typedef struct m3ap_setup_req_s{
/* Connexion id used between SCTP/M3AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Number of SCTP streams used for a mme association */
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint16_t default_sctp_stream_id;
}m3ap_setup_req_t;
typedef struct m3ap_setup_resp_s{
}m3ap_setup_resp_t;
typedef struct m3ap_setup_failure_s{
}m3ap_setup_failure_t;
typedef struct m3ap_mce_configuration_update_s{
}m3ap_mce_configuration_update_t;
typedef struct m3ap_mce_configuration_update_ack_s{
}m3ap_mce_configuration_update_ack_t;
typedef struct m3ap_mce_configuration_update_failure_s{
}m3ap_mce_configuration_update_failure_t;
#endif /* M3AP_MESSAGES_TYPES_H_ */
+3
View File
@@ -45,3 +45,6 @@ MESSAGE_DEF(RRC_MAC_MCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDat
MESSAGE_DEF(RRC_MAC_MCCH_DATA_IND, MESSAGE_PRIORITY_MED_PLUS, RrcMacMcchDataInd, rrc_mac_mcch_data_ind)
MESSAGE_DEF(RRC_MAC_PCCH_DATA_REQ, MESSAGE_PRIORITY_MED_PLUS, RrcMacPcchDataReq, rrc_mac_pcch_data_req)
/* RRC configures DRX context (MAC timers) of a UE */
MESSAGE_DEF(RRC_MAC_DRX_CONFIG_REQ, MESSAGE_PRIORITY_MED, rrc_mac_drx_config_req_t, rrc_mac_drx_config_req)
+14
View File
@@ -29,6 +29,8 @@
#ifndef MAC_MESSAGES_TYPES_H_
#define MAC_MESSAGES_TYPES_H_
#include <LTE_DRX-Config.h>
//-------------------------------------------------------------------------------------------//
// Defines to access message fields.
#define RRC_MAC_IN_SYNC_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_in_sync_ind
@@ -48,6 +50,8 @@
#define RRC_MAC_MCCH_DATA_IND(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_mcch_data_ind
#define RRC_MAC_PCCH_DATA_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_pcch_data_req
#define RRC_MAC_DRX_CONFIG_REQ(mSGpTR) (mSGpTR)->ittiMsg.rrc_mac_drx_config_req
// Some constants from "LAYER2/MAC/defs.h"
#define BCCH_SDU_SIZE (512)
#define BCCH_SDU_MBMS_SIZE (512)
@@ -145,4 +149,14 @@ typedef struct RrcMacPcchDataReq_s {
uint8_t sdu[PCCH_SDU_SIZE];
uint8_t enb_index;
} RrcMacPcchDataReq;
/* RRC configures DRX context (MAC timers) of a UE */
typedef struct rrc_mac_drx_config_req_s {
/* UE RNTI to configure */
rnti_t rnti;
/* DRX configuration from MacMainConfig to configure UE's local timers */
LTE_DRX_Config_t * drx_Configuration;
} rrc_mac_drx_config_req_t;
#endif /* MAC_MESSAGES_TYPES_H_ */
+2
View File
@@ -36,6 +36,8 @@
#include "s1ap_messages_def.h"
#include "f1ap_messages_def.h"
#include "x2ap_messages_def.h"
#include "m2ap_messages_def.h"
#include "m3ap_messages_def.h"
#include "sctp_messages_def.h"
#include "udp_messages_def.h"
#include "gtpv1_u_messages_def.h"
+2 -1
View File
@@ -115,7 +115,8 @@
#define NB_RAB_MAX LTE_maxDRB /* was 8, now 11 */
#define RAB_SHIFT1 9
#define RAB_SHIFT2 3
#define RAB_OFFSET 0x0007
//#define RAB_OFFSET 0x0007
#define RAB_OFFSET 0x000F
#define RAB_OFFSET1 0x7E00
#define RAB_OFFSET2 0x01F8
#define DIR_OFFSET 0x8000
+1
View File
@@ -194,6 +194,7 @@ typedef struct RrcConfigurationReq_s {
int16_t N_RB_DL[MAX_NUM_CCs];// for testing, change later
int nb_antenna_ports[MAX_NUM_CCs];
int eMBMS_configured;
int eMBMS_M2_configured;
int eMTC_configured;
int SL_configured;
+9
View File
@@ -50,6 +50,15 @@ TASK_DEF(TASK_GTPV1_U, TASK_PRIORITY_MED, 1000)
TASK_DEF(TASK_S1AP, TASK_PRIORITY_MED, 200)
TASK_DEF(TASK_CU_F1, TASK_PRIORITY_MED, 200)
TASK_DEF(TASK_DU_F1, TASK_PRIORITY_MED, 200)
/// M3ap task, acts as both source and target
TASK_DEF(TASK_M3AP, TASK_PRIORITY_MED, 200)
/// M3ap task, acts as both source and target
TASK_DEF(TASK_M3AP_MME, TASK_PRIORITY_MED, 200)
/// M3ap task, acts as both source and target
TASK_DEF(TASK_M3AP_MCE, TASK_PRIORITY_MED, 200)
/// M2ap task, acts as both source and target
TASK_DEF(TASK_M2AP_MCE, TASK_PRIORITY_MED, 200)
TASK_DEF(TASK_M2AP_ENB, TASK_PRIORITY_MED, 200)
/// X2ap task, acts as both source and target
TASK_DEF(TASK_X2AP, TASK_PRIORITY_MED, 200)
/// Sctp task (Used by both S1AP and X2AP)
+228
View File
@@ -46,6 +46,8 @@
# include "x2ap_eNB.h"
# include "x2ap_messages_types.h"
# include "m2ap_eNB.h"
# include "m2ap_messages_types.h"
# define X2AP_ENB_REGISTER_RETRY_DELAY 10
#include "openair1/PHY/INIT/phy_init.h"
@@ -56,6 +58,90 @@ extern RAN_CONTEXT_t RC;
# define ENB_REGISTER_RETRY_DELAY 10
#include "targets/RT/USER/lte-softmodem.h"
/*************************** ENB M2AP **************************/
//static uint32_t eNB_app_register_MBMS_STA(ngran_node_t node_type,uint32_t enb_id_start, uint32_t enb_id_end) {
// uint32_t enb_id;
// //MessageDef *msg_p;
// uint32_t register_enb_pending = 0;
//
// for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
// {
//
// //msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
// //RCconfig_S1(msg_p, enb_id);
//
// if (enb_id == 0) RCconfig_gtpu();
//
// //LOG_I(ENB_APP,"default drx %d\n",((S1AP_REGISTER_ENB_REQ(msg_p)).default_drx));
//
// //LOG_I(ENB_APP,"[eNB %d] eNB_app_register via S1AP for instance %d\n", enb_id, ENB_MODULE_ID_TO_INSTANCE(enb_id));
// //itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
//
// register_enb_pending++;
// }
// }
//
// return register_enb_pending;
//}
//*****end M2AP ****/
static uint32_t eNB_app_register_m2(uint32_t enb_id_start, uint32_t enb_id_end) {
uint32_t enb_id;
MessageDef *msg_p;
uint32_t register_enb_m2_pending = 0;
// msg_p = itti_alloc_new_message (TASK_ENB_APP,MESSAGE_TEST );
// itti_send_msg_to_task (TASK_M2AP_MCE, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
LOG_D(ENB_APP,"Register ...\n");
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
{
msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_REGISTER_ENB_REQ);
RCconfig_M2(msg_p, enb_id);
itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
register_enb_m2_pending++;
}
}
return register_enb_m2_pending;
}
/*************************** M2AP ENB handle **********************************/
static uint32_t eNB_app_handle_m2ap_mbms_scheduling_information(instance_t instance){
//uint32_t mce_id=0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SCHEDULING_INFORMATION_RESP);
itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
return 0;
}
static uint32_t eNB_app_handle_m2ap_mbms_session_start_req(instance_t instance){
//uint32_t mce_id=0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_START_RESP);
itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
return 0;
}
static uint32_t eNB_app_handle_m2ap_mbms_session_stop_req(instance_t instance){
//uint32_t mce_id=0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_STOP_RESP);
itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
return 0;
}
static uint32_t eNB_app_handle_m2ap_mbms_session_update_req(instance_t instance){
//uint32_t mce_id=0;
MessageDef *msg_p;
msg_p = itti_alloc_new_message (TASK_ENB_APP, M2AP_MBMS_SESSION_UPDATE_RESP);
itti_send_msg_to_task (TASK_M2AP_ENB, ENB_MODULE_ID_TO_INSTANCE(instance), msg_p);
return 0;
}
//// end M2AP ENB handle **********************************/
/*------------------------------------------------------------------------------*/
@@ -126,6 +212,9 @@ void *eNB_app_task(void *args_p) {
uint32_t x2_register_enb_pending = 0;
uint32_t x2_registered_enb = 0;
long x2_enb_register_retry_timer_id;
uint32_t m2_register_enb_pending = 0;
uint32_t m2_registered_enb = 0;
long m2_enb_register_retry_timer_id;
MessageDef *msg_p = NULL;
instance_t instance;
int result;
@@ -144,6 +233,22 @@ void *eNB_app_task(void *args_p) {
x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
}
/* Try to register each eNB with MCE each other */
if (is_m2ap_eNB_enabled() /*&& !NODE_IS_DU(RC.rrc[0]->node_type)*/) {
//eNB_app_register_MBMS_STA(RC.rrc[0]->node_type, enb_id_start, enb_id_end);
//m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end);
if (timer_setup (5, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
NULL, &m2_enb_register_retry_timer_id) < 0) {
//LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n");
//sleep(ENB_REGISTER_RETRY_DELAY);
/* Restart the registration process */
//registered_enb = 0;
//register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end);
}
}
do {
// Wait for a message
itti_receive_msg (TASK_ENB_APP, &msg_p);
@@ -272,6 +377,12 @@ void *eNB_app_task(void *args_p) {
}
} /* if (EPC_MODE_ENABLED) */
if(TIMER_HAS_EXPIRED (msg_p).timer_id == m2_enb_register_retry_timer_id) {
LOG_I(ENB_APP, " Received %s: timer_id %ld M2 register\n", ITTI_MSG_NAME (msg_p), TIMER_HAS_EXPIRED(msg_p).timer_id);
m2_register_enb_pending = eNB_app_register_m2 (enb_id_start, enb_id_end);
}
break;
case X2AP_DEREGISTERED_ENB_IND:
@@ -316,6 +427,123 @@ void *eNB_app_task(void *args_p) {
break;
case M2AP_DEREGISTERED_ENB_IND:
LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
M2AP_DEREGISTERED_ENB_IND(msg_p).nb_m2);
/* TODO handle recovering of registration */
break;
case M2AP_REGISTER_ENB_CNF:
LOG_W(ENB_APP, "[eNB %d] Received %s: associated eNB %d\n", instance, ITTI_MSG_NAME (msg_p),
M2AP_REGISTER_ENB_CNF(msg_p).nb_m2);
DevAssert(m2_register_enb_pending > 0);
m2_register_enb_pending--;
/* Check if at least eNB is registered with one target eNB */
if (M2AP_REGISTER_ENB_CNF(msg_p).nb_m2 > 0) {
m2_registered_enb++;
}
/* Check if all register eNB requests have been processed */
if (m2_register_enb_pending == 0) {
if (m2_registered_enb == enb_nb) {
/* If all eNB are registered, start RRC HO task */
} else {
uint32_t m2_not_associated = enb_nb - m2_registered_enb;
LOG_W(ENB_APP, " %d eNB %s not associated with the target\n",
m2_not_associated, m2_not_associated > 1 ? "are" : "is");
// timer to retry
/* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
//if (timer_setup (X2AP_ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP,
// INSTANCE_DEFAULT, TIMER_ONE_SHOT, NULL,
// &x2_enb_register_retry_timer_id) < 0) {
// LOG_E(ENB_APP, " Can not start eNB X2AP register: retry timer, use \"sleep\" instead!\n");
// sleep(X2AP_ENB_REGISTER_RETRY_DELAY);
// /* Restart the registration process */
// x2_registered_enb = 0;
// x2_register_enb_pending = eNB_app_register_x2 (enb_id_start, enb_id_end);
//}
}
}
break;
case M2AP_SETUP_RESP:
LOG_I(ENB_APP,"M2AP_SETUP_RESP RESPONSE received\n");
// AssertFatal(NODE_IS_DU(RC.rrc[0]->node_type), "Should not have received F1AP_REGISTER_ENB_CNF in CU/eNB\n");
// LOG_I(ENB_APP, "Received %s: associated ngran_eNB_CU %s with %d cells to activate\n", ITTI_MSG_NAME (msg_p),
// F1AP_SETUP_RESP(msg_p).gNB_CU_name,F1AP_SETUP_RESP(msg_p).num_cells_to_activate);
//
// handle_f1ap_setup_resp(&F1AP_SETUP_RESP(msg_p));
// DevAssert(register_enb_pending > 0);
// register_enb_pending--;
// /* Check if at least eNB is registered with one MME */
// if (F1AP_SETUP_RESP(msg_p).num_cells_to_activate > 0) {
// registered_enb++;
// }
// /* Check if all register eNB requests have been processed */
// if (register_enb_pending == 0) {
// if (registered_enb == enb_nb) {
// /* If all eNB cells are registered, start L2L1 task */
// MessageDef *msg_init_p;
// msg_init_p = itti_alloc_new_message (TASK_ENB_APP, INITIALIZE_MESSAGE);
// itti_send_msg_to_task (TASK_L2L1, INSTANCE_DEFAULT, msg_init_p);
// } else {
// LOG_W(ENB_APP, " %d eNB not associated with a MME, retrying registration in %d seconds ...\n",
// enb_nb - registered_enb, ENB_REGISTER_RETRY_DELAY);
// /* Restart the eNB registration process in ENB_REGISTER_RETRY_DELAY seconds */
// if (timer_setup (ENB_REGISTER_RETRY_DELAY, 0, TASK_ENB_APP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
// NULL, &enb_register_retry_timer_id) < 0) {
// LOG_E(ENB_APP, " Can not start eNB register retry timer, use \"sleep\" instead!\n");
// sleep(ENB_REGISTER_RETRY_DELAY);
// /* Restart the registration process */
// registered_enb = 0;
// register_enb_pending = eNB_app_register (RC.rrc[0]->node_type,enb_id_start, enb_id_end);//, enb_properties_p);
// }
// }
// }
break;
case M2AP_MBMS_SCHEDULING_INFORMATION:
LOG_I(ENB_APP,"M2AP_SCHEDULING_INFORMATION received\n");
eNB_app_handle_m2ap_mbms_scheduling_information(ITTI_MESSAGE_GET_INSTANCE(msg_p));
break;
case M2AP_MBMS_SESSION_START_REQ:
LOG_I(ENB_APP,"M2AP_MBMS_SESSION_START_REQ received\n");
eNB_app_handle_m2ap_mbms_session_start_req(ITTI_MESSAGE_GET_INSTANCE(msg_p));
break;
case M2AP_MBMS_SESSION_STOP_REQ:
LOG_I(ENB_APP,"M2AP_MBMS_SESSION_STOP_REQ received\n");
eNB_app_handle_m2ap_mbms_session_stop_req(ITTI_MESSAGE_GET_INSTANCE(msg_p));
break;
case M2AP_RESET:
LOG_I(ENB_APP,"M2AP_RESET received\n");
break;
case M2AP_ENB_CONFIGURATION_UPDATE_ACK:
LOG_I(ENB_APP,"M2AP_ENB_CONFIGURATION_UPDATE_ACK received\n");
break;
case M2AP_ENB_CONFIGURATION_UPDATE_FAILURE:
LOG_I(ENB_APP,"M2AP_ENB_CONFIGURATION_UPDATE_FAILURE received\n");
break;
case M2AP_ERROR_INDICATION:
LOG_I(ENB_APP,"M2AP_MBMS_SESSION_UPDATE_REQ\n");
eNB_app_handle_m2ap_mbms_session_update_req(ITTI_MESSAGE_GET_INSTANCE(msg_p));
break;
case M2AP_MBMS_SERVICE_COUNTING_REQ:
LOG_I(ENB_APP,"M2AP_MBMS_SERVICE_COUNTING_REQ\n");
break;
case M2AP_MCE_CONFIGURATION_UPDATE:
LOG_I(ENB_APP,"M2AP_MCE_CONFIGURATION_UPDATE\n");
break;
default:
LOG_E(ENB_APP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
break;
+268 -1
View File
@@ -380,7 +380,6 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) {
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
//RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = RRC_INACTIVITY_THRESH; // set to 0 to deactivate
// In the configuration file it is in seconds. For RRC it has to be in milliseconds
RRC_CONFIGURATION_REQ (msg_p).rrc_inactivity_timer_thres = (*ENBParamList.paramarray[i][ENB_RRC_INACTIVITY_THRES_IDX].uptr) * 1000;
RRC_CONFIGURATION_REQ (msg_p).cell_identity = enb_id;
@@ -428,6 +427,14 @@ int RCconfig_RRC(uint32_t i, eNB_RRC_INST *rrc, int macrlc_has_f1) {
else
RRC_CONFIGURATION_REQ (msg_p).enable_x2 = 0;
/* m2 enabled */
if (ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr != NULL &&
*(ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr) != NULL &&
!strcmp(*(ENBParamList.paramarray[i][ENB_ENABLE_ENB_M2].strptr), "yes"))
RRC_CONFIGURATION_REQ (msg_p).eMBMS_M2_configured = 1;
else
RRC_CONFIGURATION_REQ (msg_p).eMBMS_M2_configured = 0;
// Parse optional physical parameters
config_getlist( &CCsParamList,NULL,0,enbpath);
LOG_I(RRC,"num component carriers %d \n",CCsParamList.numelt);
@@ -2044,6 +2051,266 @@ int RCconfig_gtpu(void ) {
return 0;
}
int RCconfig_M2(MessageDef *msg_p, uint32_t i) {
int I, J, j, k, l;
int enb_id;
char *address = NULL;
char *cidr = NULL;
ccparams_lte_t ccparams_lte;
memset((void *)&ccparams_lte,0,sizeof(ccparams_lte_t));
paramdef_t ENBSParams[] = ENBSPARAMS_DESC;
paramdef_t ENBParams[] = ENBPARAMS_DESC;
paramlist_def_t ENBParamList = {ENB_CONFIG_STRING_ENB_LIST,NULL,0};
/* get global parameters, defined outside any section in the config file */
config_get( ENBSParams,sizeof(ENBSParams)/sizeof(paramdef_t),NULL);
checkedparam_t config_check_CCparams[] = CCPARAMS_CHECK;
paramdef_t CCsParams[] = CCPARAMS_DESC(ccparams_lte);
paramlist_def_t CCsParamList = {ENB_CONFIG_STRING_COMPONENT_CARRIERS, NULL, 0};
// ccparams_MCE_t MCEconfig;
// memset((void *)&MCEconfig,0,sizeof(ccparams_MCE_t));
// paramdef_t MCEParams[] = MCEPARAMS_DESC((&MCEconfig));
// checkedparam_t config_check_MCEparams[] = MCEPARAMS_CHECK;
/* map parameter checking array instances to parameter definition array instances */
for (I = 0; I < (sizeof(CCsParams) / sizeof(paramdef_t)); I++) {
CCsParams[I].chkPptr = &(config_check_CCparams[I]);
}
AssertFatal(i < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt,
"Failed to parse config file %s, %uth attribute %s \n",
RC.config_file_name, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
if (ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt > 0) {
// Output a list of all eNBs.
config_getlist( &ENBParamList,ENBParams,sizeof(ENBParams)/sizeof(paramdef_t),NULL);
if (ENBParamList.numelt > 0) {
for (k = 0; k < ENBParamList.numelt; k++) {
if (ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr == NULL) {
// Calculate a default eNB ID
if (EPC_MODE_ENABLED) {
uint32_t hash;
hash = s1ap_generate_eNB_id ();
enb_id = k + (hash & 0xFFFF8);
} else {
enb_id = k;
}
} else {
enb_id = *(ENBParamList.paramarray[k][ENB_ENB_ID_IDX].uptr);
}
// search if in active list
for (j = 0; j < ENBSParams[ENB_ACTIVE_ENBS_IDX].numelt; j++) {
if (strcmp(ENBSParams[ENB_ACTIVE_ENBS_IDX].strlistptr[j], *(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr)) == 0) {
paramdef_t PLMNParams[] = PLMNPARAMS_DESC;
paramlist_def_t PLMNParamList = {ENB_CONFIG_STRING_PLMN_LIST, NULL, 0};
/* map parameter checking array instances to parameter definition array instances */
checkedparam_t config_check_PLMNParams [] = PLMNPARAMS_CHECK;
for (int I = 0; I < sizeof(PLMNParams) / sizeof(paramdef_t); ++I)
PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]);
paramdef_t M2Params[] = M2PARAMS_DESC;
paramlist_def_t M2ParamList = {ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS,NULL,0};
paramdef_t SCTPParams[] = SCTPPARAMS_DESC;
paramdef_t NETParams[] = NETPARAMS_DESC;
paramdef_t MBMSConfigParams[] = MBMS_CONFIG_PARAMS_DESC;
paramdef_t MBMSParams[] = MBMSPARAMS_DESC;
paramlist_def_t MBMSConfigParamList = {ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST,NULL,0};
paramlist_def_t MBMSParamList = {ENB_CONFIG_STRING_MBMS_SERVICE_AREA_LIST,NULL,0};
/* TODO: fix the size - if set lower we have a crash (MAX_OPTNAME_SIZE was 64 when this code was written) */
/* this is most probably a problem with the config module */
char aprefix[MAX_OPTNAME_SIZE*80 + 8];
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
/* Some default/random parameters */
M2AP_REGISTER_ENB_REQ (msg_p).eNB_id = enb_id;
if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_MACRO_ENB") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_MACRO_ENB;
} else if (strcmp(*(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr), "CELL_HOME_ENB") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).cell_type = CELL_HOME_ENB;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
RC.config_file_name, i, *(ENBParamList.paramarray[k][ENB_CELL_TYPE_IDX].strptr));
}
M2AP_REGISTER_ENB_REQ (msg_p).eNB_name = strdup(*(ENBParamList.paramarray[k][ENB_ENB_NAME_IDX].strptr));
M2AP_REGISTER_ENB_REQ (msg_p).tac = *ENBParamList.paramarray[k][ENB_TRACKING_AREA_CODE_IDX].uptr;
config_getlist(&PLMNParamList, PLMNParams, sizeof(PLMNParams)/sizeof(paramdef_t), aprefix);
// char aprefix2[MAX_OPTNAME_SIZE*80 + 8];
// sprintf(aprefix2,"%s.[%i].%s.[0]",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST);
// config_getlist(&MBMSParamList, MBMSParams, sizeof(MBMSParams)/sizeof(paramdef_t), aprefix2);
// if (MBMSParamList.numelt < 1 || MBMSParamList.numelt > 8)
// AssertFatal(0, "The number of MBMS Areas must be in [1,8], but is %d\n",
// MBMSParamList.numelt);
// M2AP_REGISTER_ENB_REQ (msg_p).num_mbms_service_area_list = MBMSParamList.numelt;
// for(J=0; J<MBMSParamList.numelt;J++){
// M2AP_REGISTER_ENB_REQ (msg_p).mbms_service_area_list[J] = *MBMSParamList.paramarray[J][ENB_MBMS_SERVICE_AREA_IDX].uptr;
// }
//
char aprefix2[MAX_OPTNAME_SIZE*80 + 8];
sprintf(aprefix2,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
config_getlist(&MBMSConfigParamList, MBMSConfigParams, sizeof(MBMSConfigParams)/sizeof(paramdef_t), aprefix2);
if (MBMSConfigParamList.numelt < 1 || MBMSConfigParamList.numelt > 8)
AssertFatal(0, "The number of MBMS Config Data must be in [1,8], but is %d\n",
MBMSConfigParamList.numelt);
M2AP_REGISTER_ENB_REQ (msg_p).num_mbms_configuration_data_list = MBMSConfigParamList.numelt;
for(int I=0; I < MBMSConfigParamList.numelt; I++){
sprintf(aprefix2,"%s.[%i].%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST,I);
config_getlist(&MBMSParamList, MBMSParams, sizeof(MBMSParams)/sizeof(paramdef_t), aprefix2);
if (MBMSParamList.numelt < 1 || MBMSParamList.numelt > 8)
AssertFatal(0, "The number of MBMS Areas must be in [1,8], but is %d\n",
MBMSParamList.numelt);
M2AP_REGISTER_ENB_REQ (msg_p).mbms_configuration_data_list[I].num_mbms_service_area_list = MBMSParamList.numelt;
for(J=0; J<MBMSParamList.numelt;J++){
M2AP_REGISTER_ENB_REQ (msg_p).mbms_configuration_data_list[I].mbms_service_area_list[J] = *MBMSParamList.paramarray[J][ENB_MBMS_SERVICE_AREA_IDX].uptr;
}
}
if (PLMNParamList.numelt < 1 || PLMNParamList.numelt > 6)
AssertFatal(0, "The number of PLMN IDs must be in [1,6], but is %d\n",
PLMNParamList.numelt);
if (PLMNParamList.numelt > 1)
LOG_W(M2AP, "M2AP currently handles only one PLMN, ignoring the others!\n");
M2AP_REGISTER_ENB_REQ (msg_p).mcc = *PLMNParamList.paramarray[0][ENB_MOBILE_COUNTRY_CODE_IDX].uptr;
M2AP_REGISTER_ENB_REQ (msg_p).mnc = *PLMNParamList.paramarray[0][ENB_MOBILE_NETWORK_CODE_IDX].uptr;
M2AP_REGISTER_ENB_REQ (msg_p).mnc_digit_length = *PLMNParamList.paramarray[0][ENB_MNC_DIGIT_LENGTH].u8ptr;
AssertFatal(M2AP_REGISTER_ENB_REQ(msg_p).mnc_digit_length == 3
|| M2AP_REGISTER_ENB_REQ(msg_p).mnc < 100,
"MNC %d cannot be encoded in two digits as requested (change mnc_digit_length to 3)\n",
M2AP_REGISTER_ENB_REQ(msg_p).mnc);
/* CC params */
config_getlist(&CCsParamList, NULL, 0, aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).num_cc = CCsParamList.numelt;
if (CCsParamList.numelt > 0) {
//char ccspath[MAX_OPTNAME_SIZE*2 + 16];
for (J = 0; J < CCsParamList.numelt ; J++) {
sprintf(aprefix, "%s.[%i].%s.[%i]", ENB_CONFIG_STRING_ENB_LIST, k, ENB_CONFIG_STRING_COMPONENT_CARRIERS, J);
config_get(CCsParams, sizeof(CCsParams)/sizeof(paramdef_t), aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).eutra_band[J] = ccparams_lte.eutra_band;
M2AP_REGISTER_ENB_REQ (msg_p).downlink_frequency[J] = (uint32_t) ccparams_lte.downlink_frequency;
M2AP_REGISTER_ENB_REQ (msg_p).uplink_frequency_offset[J] = (unsigned int) ccparams_lte.uplink_frequency_offset;
M2AP_REGISTER_ENB_REQ (msg_p).Nid_cell[J]= ccparams_lte.Nid_cell;
if (ccparams_lte.Nid_cell>503) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for Nid_cell choice: 0...503 !\n",
RC.config_file_name, k, ccparams_lte.Nid_cell);
}
M2AP_REGISTER_ENB_REQ (msg_p).N_RB_DL[J]= ccparams_lte.N_RB_DL;
if ((ccparams_lte.N_RB_DL!=6) && (ccparams_lte.N_RB_DL!=15) && (ccparams_lte.N_RB_DL!=25) && (ccparams_lte.N_RB_DL!=50) && (ccparams_lte.N_RB_DL!=75) && (ccparams_lte.N_RB_DL!=100)) {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%d\" for N_RB_DL choice: 6,15,25,50,75,100 !\n",
RC.config_file_name, k, ccparams_lte.N_RB_DL);
}
if (strcmp(ccparams_lte.frame_type, "FDD") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = FDD;
} else if (strcmp(ccparams_lte.frame_type, "TDD") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).frame_type[J] = TDD;
} else {
AssertFatal (0,
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for frame_type choice: FDD or TDD !\n",
RC.config_file_name, k, ccparams_lte.frame_type);
}
M2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_DL[J] = to_earfcn_DL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency, ccparams_lte.N_RB_DL);
M2AP_REGISTER_ENB_REQ (msg_p).fdd_earfcn_UL[J] = to_earfcn_UL(ccparams_lte.eutra_band, ccparams_lte.downlink_frequency + ccparams_lte.uplink_frequency_offset, ccparams_lte.N_RB_DL);
}
}
sprintf(aprefix,"%s.[%i]",ENB_CONFIG_STRING_ENB_LIST,k);
config_getlist( &M2ParamList,M2Params,sizeof(M2Params)/sizeof(paramdef_t),aprefix);
AssertFatal(M2ParamList.numelt <= M2AP_MAX_NB_ENB_IP_ADDRESS,
"value of M2ParamList.numelt %d must be lower than M2AP_MAX_NB_ENB_IP_ADDRESS %d value: reconsider to increase M2AP_MAX_NB_ENB_IP_ADDRESS\n",
M2ParamList.numelt,M2AP_MAX_NB_ENB_IP_ADDRESS);
M2AP_REGISTER_ENB_REQ (msg_p).nb_m2 = 0;
for (l = 0; l < M2ParamList.numelt; l++) {
M2AP_REGISTER_ENB_REQ (msg_p).nb_m2 += 1;
strcpy(M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4_address,*(M2ParamList.paramarray[l][ENB_M2_IPV4_ADDRESS_IDX].strptr));
strcpy(M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6_address,*(M2ParamList.paramarray[l][ENB_M2_IPV6_ADDRESS_IDX].strptr));
if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv4") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 1;
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 0;
} else if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "ipv6") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 0;
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 1;
} else if (strcmp(*(M2ParamList.paramarray[l][ENB_M2_IP_ADDRESS_PREFERENCE_IDX].strptr), "no") == 0) {
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv4 = 1;
M2AP_REGISTER_ENB_REQ (msg_p).target_mce_m2_ip_address[l].ipv6 = 1;
}
}
// timers
//{
// int t_reloc_prep = 0;
// int tx2_reloc_overall = 0;
// paramdef_t p[] = {
// { "t_reloc_prep", "t_reloc_prep", 0, iptr:&t_reloc_prep, defintval:0, TYPE_INT, 0 },
// { "tx2_reloc_overall", "tx2_reloc_overall", 0, iptr:&tx2_reloc_overall, defintval:0, TYPE_INT, 0 }
// };
// config_get(p, sizeof(p)/sizeof(paramdef_t), aprefix);
// if (t_reloc_prep <= 0 || t_reloc_prep > 10000 ||
// tx2_reloc_overall <= 0 || tx2_reloc_overall > 20000) {
// LOG_E(M2AP, "timers in configuration file have wrong values. We must have [0 < t_reloc_prep <= 10000] and [0 < tx2_reloc_overall <= 20000]\n");
// exit(1);
// }
// M2AP_REGISTER_ENB_REQ (msg_p).t_reloc_prep = t_reloc_prep;
// M2AP_REGISTER_ENB_REQ (msg_p).tx2_reloc_overall = tx2_reloc_overall;
//}
// SCTP SETTING
M2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = SCTP_OUT_STREAMS;
M2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = SCTP_IN_STREAMS;
if (EPC_MODE_ENABLED) {
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_SCTP_CONFIG);
config_get( SCTPParams,sizeof(SCTPParams)/sizeof(paramdef_t),aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).sctp_in_streams = (uint16_t)*(SCTPParams[ENB_SCTP_INSTREAMS_IDX].uptr);
M2AP_REGISTER_ENB_REQ (msg_p).sctp_out_streams = (uint16_t)*(SCTPParams[ENB_SCTP_OUTSTREAMS_IDX].uptr);
}
sprintf(aprefix,"%s.[%i].%s",ENB_CONFIG_STRING_ENB_LIST,k,ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
// NETWORK_INTERFACES
config_get( NETParams,sizeof(NETParams)/sizeof(paramdef_t),aprefix);
M2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_M2C = (uint32_t)*(NETParams[ENB_PORT_FOR_M2C_IDX].uptr);
if ((NETParams[ENB_IPV4_ADDR_FOR_M2C_IDX].strptr == NULL) || (M2AP_REGISTER_ENB_REQ (msg_p).enb_port_for_M2C == 0)) {
LOG_E(RRC,"Add eNB IPv4 address and/or port for M2C in the CONF file!\n");
exit(1);
}
cidr = *(NETParams[ENB_IPV4_ADDR_FOR_M2C_IDX].strptr);
address = strtok(cidr, "/");
M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv6 = 0;
M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv4 = 1;
strcpy(M2AP_REGISTER_ENB_REQ (msg_p).enb_m2_ip_address.ipv4_address, address);
}
}
}
}
}
return 0;
}
//-----------------------------------------------------------------------------
/*
* Configure the s1ap_register_enb_req in itti message for future
+1
View File
@@ -116,6 +116,7 @@ int RCconfig_S1(MessageDef *msg_p, uint32_t i);
void read_config_and_init(void);
int RCconfig_X2(MessageDef *msg_p, uint32_t i);
int RCconfig_M2(MessageDef *msg_p, uint32_t i);
void fill_SL_configuration(MessageDef *msg_p, ccparams_sidelink_t *SLconfig,int cell_idx,int cc_idx,char *config_fname);
void fill_eMTC_configuration(MessageDef *msg_p, ccparams_eMTC_t *eMTCconfig, int cell_idx,int cc_idx,char *config_fname,char *brparamspath);
+86 -3
View File
@@ -202,6 +202,8 @@ typedef enum {
#define ENB_CONFIG_STRING_RRC_INACTIVITY_THRESHOLD "rrc_inactivity_threshold"
#define ENB_CONFIG_STRING_MEASUREMENT_REPORTS "enable_measurement_reports"
#define ENB_CONFIG_STRING_X2 "enable_x2"
#define ENB_CONFIG_STRING_ENB_M2 "enable_enb_m2"
#define ENB_CONFIG_STRING_MCE_M2 "enable_mce_m2"
/*-----------------------------------------------------------------------------------------------------------------------------------------*/
/* cell configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -225,7 +227,10 @@ typedef enum {
{ENB_CONFIG_STRING_RRC_INACTIVITY_THRESHOLD, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_MEASUREMENT_REPORTS, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_X2, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_ENB_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
}
#define ENB_ENB_ID_IDX 0
#define ENB_CELL_TYPE_IDX 1
#define ENB_ENB_NAME_IDX 2
@@ -244,6 +249,8 @@ typedef enum {
#define ENB_RRC_INACTIVITY_THRES_IDX 15
#define ENB_ENABLE_MEASUREMENT_REPORTS 16
#define ENB_ENABLE_X2 17
#define ENB_ENABLE_ENB_M2 18
#define ENB_ENABLE_MCE_M2 19
#define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD}
#define ENBPARAMS_CHECK { \
@@ -263,6 +270,8 @@ typedef enum {
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -297,6 +306,32 @@ typedef enum {
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
#define ENB_CONFIG_STRING_MBMS_CONFIGURATION_DATA_LIST "mbms_configuration_data_list"
#define ENB_CONFIG_STRING_MBMS_SYNC_AREA "mbms_sync_area"
#define ENB_MBMS_SYNC_AREA_IDX 0
#define MBMS_CONFIG_PARAMS_DESC { \
/* optname helpstr paramflags XXXptr def val type numelt */ \
{ENB_CONFIG_STRING_MBMS_SYNC_AREA , NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
/*-------------------------------------------------------------------------------------------------------------------------------------------------*/
#define ENB_CONFIG_STRING_MBMS_SERVICE_AREA_LIST "mbms_service_area_list"
#define ENB_CONFIG_STRING_MBMS_SERVICE_AREA "mbms_service_area"
#define ENB_MBMS_SERVICE_AREA_IDX 0
#define MBMSPARAMS_DESC { \
/* optname helpstr paramflags XXXptr def val type numelt */ \
{ENB_CONFIG_STRING_MBMS_SERVICE_AREA, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
/* component carries configuration parameters name */
#define ENB_CONFIG_STRING_NB_ANT_PORTS "nb_antenna_ports"
@@ -909,6 +944,39 @@ typedef struct srb1_params_s {
#define ENB_X2_IPV4_ADDRESS_IDX 0
#define ENB_X2_IPV6_ADDRESS_IDX 1
#define ENB_X2_IP_ADDRESS_PREFERENCE_IDX 2
/*---------------------------------------------------------------------------------------------------------------------------------------*/
/* M2 configuration parameters section name */
#define ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS "target_mce_m2_ip_address"
/* M2 configuration parameters names */
#define ENB_CONFIG_STRING_TARGET_MCE_M2_IPV4_ADDRESS "ipv4"
#define ENB_CONFIG_STRING_TARGET_MCE_M2_IPV6_ADDRESS "ipv6"
#define ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS_PREFERENCE "preference"
/*---------------------------------------------------------------------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------------------------------------------*/
/* M2 configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
/*-------------------------------------------------------------------------------------------------------------------------------------*/
#define M2PARAMS_DESC { \
{ENB_CONFIG_STRING_TARGET_MCE_M2_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_TARGET_MCE_M2_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_TARGET_MCE_M2_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
}
#define ENB_M2_IPV4_ADDRESS_IDX 0
#define ENB_M2_IPV6_ADDRESS_IDX 1
#define ENB_M2_IP_ADDRESS_PREFERENCE_IDX 2
/*---------------------------------------------------------------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------------------------------------*/
/* SCTP configuration parameters section name */
#define ENB_CONFIG_STRING_SCTP_CONFIG "SCTP"
@@ -942,7 +1010,10 @@ typedef struct srb1_params_s {
#define ENB_PORT_FOR_S1U_IDX 4
#define ENB_IPV4_ADDR_FOR_X2C_IDX 5
#define ENB_PORT_FOR_X2C_IDX 6
#define ENB_IPV4_ADDR_FOR_M2C_IDX 7
#define ENB_PORT_FOR_M2C_IDX 8
#define MCE_IPV4_ADDR_FOR_M2C_IDX 9
#define MCE_PORT_FOR_M2C_IDX 10
/* S1 interface configuration parameters names */
#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME"
@@ -955,6 +1026,13 @@ typedef struct srb1_params_s {
#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C "ENB_IPV4_ADDRESS_FOR_X2C"
#define ENB_CONFIG_STRING_ENB_PORT_FOR_X2C "ENB_PORT_FOR_X2C"
/* M2 interface configuration parameters names */
#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_M2C "ENB_IPV4_ADDRESS_FOR_M2C"
#define ENB_CONFIG_STRING_ENB_PORT_FOR_M2C "ENB_PORT_FOR_M2C"
#define ENB_CONFIG_STRING_MCE_IPV4_ADDR_FOR_M2C "MCE_IPV4_ADDRESS_FOR_M2C"
#define ENB_CONFIG_STRING_MCE_PORT_FOR_M2C "MCE_PORT_FOR_M2C"
/*--------------------------------------------------------------------------------------------------------------------------------------------------*/
/* S1/X2 interface configuration parameters */
/* optname helpstr paramflags XXXptr defXXXval type numelt */
@@ -967,7 +1045,12 @@ typedef struct srb1_params_s {
{ENB_CONFIG_STRING_ENB_PORT_FOR_S1U, NULL, 0, uptr:NULL, defintval:2152L, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_X2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_ENB_PORT_FOR_X2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_M2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_ENB_PORT_FOR_M2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \
{ENB_CONFIG_STRING_MCE_IPV4_ADDR_FOR_M2C, NULL, 0, strptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{ENB_CONFIG_STRING_MCE_PORT_FOR_M2C, NULL, 0, uptr:NULL, defintval:0L, TYPE_UINT, 0}, \
}
}
/*--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/* GTPU configuration parameters */
@@ -985,8 +1068,6 @@ typedef struct srb1_params_s {
#define CONFIG_STRING_L1_LIST "L1s"
#define CONFIG_STRING_L1_CONFIG "l1_config"
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------------------------------------------------------------------------------*/
@@ -1142,4 +1223,6 @@ typedef struct srb1_params_s {
#include "enb_paramdef_emtc.h"
#include "enb_paramdef_sidelink.h"
#include "enb_paramdef_mce.h"
#include "enb_paramdef_mme.h"
#endif
+239
View File
@@ -0,0 +1,239 @@
/*
* 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 openair2/ENB_APP/enb_paramdef_mce.h
* \brief definition of configuration parameters for MCE modules
* \author Javier MORGADE
* \date 2019
* \version 0.1
* \company VICOMTECH Spain
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#include "common/config/config_paramdesc.h"
#include "RRC_paramsvalues.h"
/* mce configuration parameters names */
#define MCE_CONFIG_STRING_MCE_ID "MCE_ID"
#define MCE_CONFIG_STRING_MCE_NAME "MCE_name"
#define MCE_CONFIG_STRING_MCE_M2 "enable_mce_m2"
#define MCE_CONFIG_STRING_MCE_M3 "enable_mce_m3"
#define MCE_PARAMS_DESC {\
{MCE_CONFIG_STRING_MCE_ID, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCE_NAME, NULL, 0, strptr:NULL, defstrval:"OAIMCE", TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_MCE_M2, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_MCE_M3, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
}
#define MCE_MCE_ID_IDX 0
#define MCE_MCE_NAME_IDX 1
#define MCE_ENABLE_MCE_M2_IDX 2
#define MCE_ENABLE_MCE_M3_IDX 3
#define MCE_PARAMS_CHECK { \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
#define MCE_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES"
#define MCE2_INTERFACE_NAME_FOR_M2_ENB_IDX 0
#define MCE2_IPV4_ADDR_FOR_M2C_IDX 1
#define MCE2_PORT_FOR_M2C_IDX 2
#define MCE2_INTERFACE_NAME_FOR_M3_MME_IDX 3
#define MCE2_IPV4_ADDR_FOR_M3C_IDX 4
#define MCE2_PORT_FOR_M3C_IDX 5
/* interface configuration parameters names */
/* M2 interface configuration parameters names */
#define MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M2_ENB "ENB_INTERFACE_NAME_FOR_M2_ENB"
#define MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M2C "MCE_IPV4_ADDRESS_FOR_M2C"
#define MCE_CONFIG_STRING_MCE_PORT_FOR_M2C "MCE_PORT_FOR_M2C"
/* M3 interface configuration parameters names */
#define MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M3_MME "MCE_INTERFACE_NAME_FOR_M3_MME"
#define MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M3C "MCE_IPV4_ADDRESS_FOR_M3C"
#define MCE_CONFIG_STRING_MCE_PORT_FOR_M3C "MCE_PORT_FOR_M3C"
#define MCE_NETPARAMS_DESC { \
{MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M2_ENB, NULL, 0, strptr:&mce_interface_name_for_m2_enb, defstrval:"lo", TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M2C, NULL, 0, strptr:&mce_ipv4_address_for_m2c, defstrval:NULL, TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_MCE_PORT_FOR_M2C, NULL, 0, uptr:&mce_port_for_m2c, defintval:36443L, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCE_INTERFACE_NAME_FOR_M3_MME, NULL, 0, strptr:&mce_interface_name_for_m3_mme, defstrval:NULL, TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_MCE_IPV4_ADDRESS_FOR_M3C, NULL, 0, strptr:&mce_ipv4_address_for_m3c, defstrval:NULL, TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_MCE_PORT_FOR_M3C, NULL, 0, uptr:&mce_port_for_m3c, defintval:36444L, TYPE_UINT, 0}, \
}
/*-------------------------------------------------------------------------------------------------------------------------------------*/
/* M3 configuration parameters */
/* M3 configuration parameters section name */
#define MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS "target_mme_m3_ip_address"
/* M3 configuration parameters names */
#define MCE_CONFIG_STRING_TARGET_MME_M3_IPV4_ADDRESS "ipv4"
#define MCE_CONFIG_STRING_TARGET_MME_M3_IPV6_ADDRESS "ipv6"
#define MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS_PREFERENCE "preference"
/* optname helpstr paramflags XXXptr defXXXval type numelt */
#define M3PARAMS_DESC { \
{MCE_CONFIG_STRING_TARGET_MME_M3_IPV4_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_TARGET_MME_M3_IPV6_ADDRESS, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_TARGET_MME_M3_IP_ADDRESS_PREFERENCE, NULL, 0, uptr:NULL, defstrval:NULL, TYPE_STRING, 0}, \
}
#define MCE2_M3_IPV4_ADDRESS_IDX 0
#define MCE2_M3_IPV6_ADDRESS_IDX 1
#define MCE2_M3_IP_ADDRESS_PREFERENCE_IDX 2
/*-----------------------------------------------------------------------------------------------------------------------------------*/
/* MCCH related BCCH Configuration per MBSFN area configuration parameters */
/* MCCH configuration parameters section */
#define MCE_CONFIG_STRING_MCCH_CONFIG_PER_MBSFN_AREA "mcch_config_per_mbsfn_area"
/* M3 configuration parameters names */
#define MCE_CONFIG_STRING_MCCH_MBSFN_AREA "mbsfn_area"
#define MCE_CONFIG_STRING_MCCH_PDCCH_LENGTH "pdcch_length"
#define MCE_CONFIG_STRING_MCCH_REPETITION_PERIOD "repetition_period"
#define MCE_CONFIG_STRING_MCCH_OFFSET "offset"
#define MCE_CONFIG_STRING_MCCH_MODIFICATION_PERIOD "modification_period"
#define MCE_CONFIG_STRING_MCCH_SF_ALLOCATION_INFO "subframe_allocation_info"
#define MCE_CONFIG_STRING_MCCH_MCS "mcs"
/* optname helpstr paramflags XXXptr defXXXval type numelt */
#define MCCH_PARAMS_DESC { \
{MCE_CONFIG_STRING_MCCH_MBSFN_AREA, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCCH_PDCCH_LENGTH, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCCH_REPETITION_PERIOD, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCCH_OFFSET, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCCH_MODIFICATION_PERIOD,NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCCH_SF_ALLOCATION_INFO, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCCH_MCS, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
#define MCCH_MBSFN_AREA_IDX 0
#define MCCH_PDCCH_LENGTH_IDX 1
#define MCCH_REPETITION_PERIOD_IDX 2
#define MCCH_OFFSET_IDX 3
#define MCCH_MODIFICATION_PERIOD_IDX 4
#define MCCH_SF_ALLOCATION_INFO_IDX 5
#define MCCH_MCS_IDX 6
/*-------------------------------------------------------------------------------------------------------------------------------------*/
/* M3 configuration parameters section name */
#define MCE_CONFIG_STRING_PLMN "plnm"
/* M3 configuration parameters names */
#define MCE_CONFIG_STRING_MCC "mcc"
#define MCE_CONFIG_STRING_MNC "mnc"
#define MCE_CONFIG_STRING_MNC_LENGTH "mnc_length"
/* optname helpstr paramflags XXXptr defXXXval type numelt */
#define MCE_PLMN_PARAMS_DESC { \
{MCE_CONFIG_STRING_MCC, NULL, 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MNC, NULL, 0, uptr:NULL, defuintval:1000, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MNC_LENGTH, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
#define MCE_CONFIG_STRING_MCC_IDX 0
#define MCE_CONFIG_STRING_MNC_IDX 1
#define MCE_CONFIG_STRING_MNC_LENGTH_IDX 2
/*-------------------------------------------------------------------------------------------------------------------------------------*/
#define MCE_CONFIG_STRING_MBMS_SCHEDULING_INFO "mbms_sched_info"
#define MCE_CONFIG_STRING_MCCH_UPDATE_TIME "mcch_update_time"
#define MCE_MBMS_SCHEDULING_INFO_PARAMS_DESC { \
{MCE_CONFIG_STRING_MCCH_UPDATE_TIME, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
#define MCE_CONFIG_STRING_MCCH_UPDATE_TIME_IDX 0
///*-------------------------------------------------------------------------------------------------------------------------------------*/
#define MCE_CONFIG_STRING_MBMS_AREA_CONFIGURATION_LIST "mbms_area_config_list"
#define MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD "common_sf_allocation_period"
#define MCE_CONFIG_STRING_MBMS_AREA_ID "mbms_area_id"
#define MCE_MBMS_AREA_CONFIGURATION_LIST_PARAMS_DESC { \
{MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MBMS_AREA_ID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
#define MCE_CONFIG_STRING_COMMON_SF_ALLOCATION_PERIOD_IDX 0
#define MCE_CONFIG_STRING_MBMS_AREA_ID_IDX 1
//
///*-------------------------------------------------------------------------------------------------------------------------------------*/
#define MCE_CONFIG_STRING_PMCH_CONFIGURATION_LIST "pmch_config_list"
#define MCE_CONFIG_STRING_ALLOCATED_SF_END "allocated_sf_end"
#define MCE_CONFIG_STRING_DATA_MCS "data_mcs"
#define MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD "mch_scheduling_period"
#define MCE_MBMS_PMCH_CONFIGURATION_LIST_PARAMS_DESC { \
{MCE_CONFIG_STRING_ALLOCATED_SF_END, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_DATA_MCS, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
#define MCE_CONFIG_STRING_ALLOCATED_SF_END_IDX 0
#define MCE_CONFIG_STRING_DATA_MCS_IDX 1
#define MCE_CONFIG_STRING_MCH_SCHEDULING_PERIOD_IDX 2
/*-------------------------------------------------------------------------------------------------------------------------------------*/
#define MCE_CONFIG_STRING_MBMS_SESSION_LIST "mbms_session_list"
#define MCE_CONFIG_STRING_MBMS_SERVICE_ID "service_id"
#define MCE_CONFIG_STRING_MBMS_LCID_ID "lcid_id"
#define MCE_CONFIG_STRING_MBMS_LCID "lcid"
#define MCE_MBMS_MBMS_SESSION_LIST_DESC { \
{MCE_CONFIG_STRING_MBMS_SERVICE_ID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT32, 0}, \
{MCE_CONFIG_STRING_MBMS_LCID_ID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_MBMS_LCID, NULL, 0, uptr:NULL, defuintval:0, TYPE_UINT, 0}, \
}
#define MCE_CONFIG_STRING_MBMS_SERVICE_ID_IDX 0
#define MCE_CONFIG_STRING_MBMS_LCID_ID_IDX 1
#define MCE_CONFIG_STRING_MBMS_LCID_IDX 2
/*-------------------------------------------------------------------------------------------------------------------------------------*/
#define MCE_CONFIG_STRING_MBMS_SF_CONFIGURATION_LIST "mbms_sf_config_list"
#define MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD "radioframe_allocation_period"
#define MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET "radioframe_alloocation_offset"
#define MCE_CONFIG_STRING_NUM_FRAME "num_frame"
#define MCE_CONFIG_STRING_SUBFRAME_ALLOCATION "subframe_allocation"
#define MCE_MBMS_MBMS_SF_CONFIGURATION_LIST_PARAMS_DESC { \
{MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{MCE_CONFIG_STRING_NUM_FRAME, NULL, 0, strptr:NULL, defstrval:"oneFrame", TYPE_STRING, 0}, \
{MCE_CONFIG_STRING_SUBFRAME_ALLOCATION, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
}
#define MCE_CONFIG_STRING_RADIOFRAME_ALLOCATION_PERIOD_IDX 0
#define MCE_CONFIG_STRING_RADIOFRAME_ALLOOCATION_OFFSET_IDX 1
#define MCE_CONFIG_STRING_NUM_FRAME_IDX 2
#define MCE_CONFIG_STRING_SUBFRAME_ALLOCATION_IDX 3
+82
View File
@@ -0,0 +1,82 @@
/*
* 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 openair2/ENB_APP/enb_paramdef_mme.h
* \brief definition of configuration parameters for MME modules
* \author Javier MORGADE
* \date 2019
* \version 0.1
* \company VICOMTECH Spain
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#include "common/config/config_paramdesc.h"
#include "RRC_paramsvalues.h"
/* mme configuration parameters names */
#define MME_CONFIG_STRING_MME_ID "MME_ID"
#define MME_CONFIG_STRING_MME_NAME "MME_name"
#define MME_CONFIG_STRING_MME_M3 "enable_mme_m3"
#define MMEPARAMS_DESC {\
{MME_CONFIG_STRING_MME_ID, NULL, 0, uptr:NULL, defintval:0, TYPE_UINT, 0}, \
{MME_CONFIG_STRING_MME_NAME, NULL, 0, strptr:NULL, defstrval:"OAIMME", TYPE_STRING, 0}, \
{MME_CONFIG_STRING_MME_M3, NULL, 0, strptr:NULL, defstrval:"no", TYPE_STRING, 0}, \
}
#define MME_MME_ID_IDX 0
#define MME_MME_NAME_IDX 1
#define MME_ENABLE_MME_M3_IDX 2
#define MMEPARAMS_CHECK { \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
{ .s5 = { NULL } }, \
}
#define MME_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES"
#define MME_INTERFACE_NAME_FOR_M3_MME_IDX 0
#define MME_IPV4_ADDRESS_FOR_M3C_IDX 1
#define MME_PORT_FOR_M3C_IDX 2
/* interface configuration parameters names */
/* M3 interface configuration parameters names */
#define MME_CONFIG_STRING_MME_INTERFACE_NAME_FOR_M3_MCE "MME_INTERFACE_NAME_FOR_M3_MCE"
#define MME_CONFIG_STRING_MME_IPV4_ADDRESS_FOR_M3C "MME_IPV4_ADDRESS_FOR_M3C"
#define MME_CONFIG_STRING_MME_PORT_FOR_M3C "MME_PORT_FOR_M3C"
#define MME_NETPARAMS_DESC { \
{MME_CONFIG_STRING_MME_INTERFACE_NAME_FOR_M3_MCE, NULL, 0, strptr:&mme_interface_name_for_m3_mce, defstrval:"lo", TYPE_STRING, 0}, \
{MME_CONFIG_STRING_MME_IPV4_ADDRESS_FOR_M3C, NULL, 0, strptr:&mme_ipv4_address_for_m3c, defstrval:"127.0.0.18/24", TYPE_STRING, 0}, \
{MME_CONFIG_STRING_MME_PORT_FOR_M3C, NULL, 0, uptr:&mme_port_for_m3c, defintval:36444L, TYPE_UINT, 0}, \
}
+17 -17
View File
@@ -3496,7 +3496,6 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps)
(*caps)[1] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP;
(*caps)[2] = PROTOCOL__FLEX_BS_CAPABILITY__RRC;
break;
case ngran_eNB_DU:
case ngran_gNB_DU:
n_caps = 5;
@@ -3509,7 +3508,6 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps)
(*caps)[3] = PROTOCOL__FLEX_BS_CAPABILITY__HIMAC;
(*caps)[4] = PROTOCOL__FLEX_BS_CAPABILITY__RLC;
break;
case ngran_eNB:
case ngran_ng_eNB:
case ngran_gNB:
@@ -3526,6 +3524,8 @@ size_t flexran_get_capabilities(mid_t mod_id, Protocol__FlexBsCapability **caps)
(*caps)[6] = PROTOCOL__FLEX_BS_CAPABILITY__SDAP;
(*caps)[7] = PROTOCOL__FLEX_BS_CAPABILITY__RRC;
break;
case ngran_eNB_MBMS_STA:
break;
}
return n_caps;
@@ -3541,31 +3541,31 @@ uint16_t flexran_get_capabilities_mask(mid_t mod_id) {
case ngran_ng_eNB_CU:
case ngran_gNB_CU:
mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC);
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC);
break;
case ngran_eNB_DU:
case ngran_gNB_DU:
mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC);
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC);
break;
case ngran_eNB:
case ngran_ng_eNB:
case ngran_gNB:
mask = (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOPHY)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC);
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIPHY)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__LOMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__HIMAC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RLC)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__PDCP)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__SDAP)
| (1 << PROTOCOL__FLEX_BS_CAPABILITY__RRC);
break;
case ngran_eNB_MBMS_STA:
break;
}
return mask;
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -175,7 +175,7 @@ void *F1AP_DU_task(void *arg) {
&received_msg->ittiMsg.sctp_data_ind);
break;
case F1AP_UL_RRC_MESSAGE: // from rrc
case F1AP_UL_RRC_MESSAGE: // to rrc
LOG_I(F1AP, "DU Task Received F1AP_UL_RRC_MESSAGE\n");
DU_send_UL_RRC_MESSAGE_TRANSFER(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&F1AP_UL_RRC_MESSAGE(received_msg));
+169 -47
View File
@@ -49,6 +49,7 @@
#include "LTE_MBSFN-AreaInfoList-r9.h"
#include "LTE_MBSFN-AreaInfo-r9.h"
#include "LTE_MBSFN-SubframeConfigList.h"
#include "LTE_MBSFN-SubframeConfig.h"
#include "LTE_PMCH-InfoList-r9.h"
@@ -610,6 +611,123 @@ config_sib2(int Mod_idP,
}
}
void
config_sib2_mbsfn_part( int Mod_idP,
int CC_idP,
struct LTE_MBSFN_SubframeConfigList *mbsfn_SubframeConfigListP) {
//LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_idP][CC_idP]->frame_parms;
//int i;
//if(mbsfn_SubframeConfigListP != NULL) {
// fp->num_MBSFN_config = mbsfn_SubframeConfigListP->list.count;
// for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) {
// fp->MBSFN_config[i].radioframeAllocationPeriod = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod;
// fp->MBSFN_config[i].radioframeAllocationOffset = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset;
// if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
// fp->MBSFN_config[i].fourFrames_flag = 0;
// fp->MBSFN_config[i].mbsfn_SubframeConfig = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
// LOG_I (PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, fp->MBSFN_config[i].mbsfn_SubframeConfig);
// } else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
// fp->MBSFN_config[i].fourFrames_flag = 1;
// fp->MBSFN_config[i].mbsfn_SubframeConfig =
// mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
// (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
// (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
// LOG_I(PHY, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i,
// fp->MBSFN_config[i].mbsfn_SubframeConfig);
// }
// }
//} else
// fp->num_MBSFN_config = 0;
PHY_Config_t phycfg;
phycfg.Mod_id = Mod_idP;
phycfg.CC_id = CC_idP;
phycfg.cfg = &RC.mac[Mod_idP]->config[CC_idP];
int i;
if(mbsfn_SubframeConfigListP != NULL) {
phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = mbsfn_SubframeConfigListP->list.count;
for(i = 0; i < mbsfn_SubframeConfigListP->list.count; i++) {
phycfg.cfg->embms_mbsfn_config.radioframe_allocation_period[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationPeriod;
phycfg.cfg->embms_mbsfn_config.radioframe_allocation_offset[i] = mbsfn_SubframeConfigListP->list.array[i]->radioframeAllocationOffset;
if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) {
phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 0;
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] = mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]; // 6-bit subframe configuration
LOG_I (MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %d\n", i, phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]);
} else if (mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.present == LTE_MBSFN_SubframeConfig__subframeAllocation_PR_fourFrames) { // 24-bit subframe configuration
phycfg.cfg->embms_mbsfn_config.fourframes_flag[i] = 1;
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i] =
mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[2]|
(mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[1]<<8)|
(mbsfn_SubframeConfigListP->list.array[i]->subframeAllocation.choice.oneFrame.buf[0]<<16);
LOG_I(MAC, "[CONFIG] MBSFN_SubframeConfig[%d] pattern is %x\n", i,
phycfg.cfg->embms_mbsfn_config.mbsfn_subframeconfig[i]);
}
}
phycfg.cfg->num_tlv++;
} else{
phycfg.cfg->embms_mbsfn_config.num_mbsfn_config = 0;
phycfg.cfg->num_tlv++;
}
phycfg.cfg->embms_mbsfn_config.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_TAG;
if (RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req) RC.mac[Mod_idP]->if_inst->PHY_config_update_sib2_req(&phycfg);
}
void
config_sib13( int Mod_id,
int CC_id,
int mbsfn_Area_idx,
long mbsfn_AreaId_r9){
//nfapi_config_request_t *cfg = &RC.mac[Mod_id]->config[CC_id];
//work around until PHY_config_re "update" mechanisms get defined
// LTE_DL_FRAME_PARMS *fp = &RC.eNB[Mod_id][CC_id]->frame_parms;
// LOG_I (MAC, "[eNB%d] Applying MBSFN_Area_id %ld for index %d\n", Mod_id, mbsfn_AreaId_r9, mbsfn_Area_idx);
//
// AssertFatal(mbsfn_Area_idx == 0, "Fix me: only called when mbsfn_Area_idx == 0\n");
// if (mbsfn_Area_idx == 0) {
// fp->Nid_cell_mbsfn = (uint16_t)mbsfn_AreaId_r9;
// LOG_I(MAC,"Fix me: only called when mbsfn_Area_idx == 0)\n");
// }
// lte_gold_mbsfn (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_table, fp->Nid_cell_mbsfn);
//
//#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
// lte_gold_mbsfn_khz_1dot25 (fp, RC.eNB[Mod_id][CC_id]->lte_gold_mbsfn_khz_1dot25_table, fp->Nid_cell_mbsfn);
//#endif
//
PHY_Config_t phycfg;
phycfg.Mod_id = Mod_id;
phycfg.CC_id = CC_id;
phycfg.cfg = &RC.mac[Mod_id]->config[CC_id];
phycfg.cfg->embms_sib13_config.mbsfn_area_idx.value = (uint8_t)mbsfn_Area_idx;
phycfg.cfg->embms_sib13_config.mbsfn_area_idx.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDX_TAG;
phycfg.cfg->num_tlv++;
phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.value = (uint32_t)mbsfn_AreaId_r9;
phycfg.cfg->embms_sib13_config.mbsfn_area_id_r9.tl.tag = NFAPI_EMBMS_MBSFN_CONFIG_AREA_IDR9_TAG;
phycfg.cfg->num_tlv++;
if (RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req) RC.mac[Mod_id]->if_inst->PHY_config_update_sib13_req(&phycfg);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG, VCD_FUNCTION_OUT);
}
void
config_dedicated(int Mod_idP,
int CC_idP,
@@ -820,6 +938,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
}
RC.mac[Mod_idP]->common_channels[0].MBMS_flag = MBMS_Flag;
config_sib2_mbsfn_part(Mod_idP,0,mbsfn_SubframeConfigList);
}
if (nonMBSFN_SubframeConfig != NULL) {
@@ -856,6 +975,7 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
LOG_I(MAC,"[eNB %d][CONFIG] MBSFN_AreaInfo[%d]: MCCH Repetition Period = %ld\n", Mod_idP,i,
RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
// config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
config_sib13(Mod_idP,0,i,RC.mac[Mod_idP]->common_channels[0].mbsfn_AreaInfo[i]->mbsfn_AreaId_r9);
}
}
@@ -885,6 +1005,10 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
LOG_I(MAC, "PMCH[%d] Number of session (MTCH) is: %d\n", i,
RC.mac[Mod_idP]->common_channels[0].
mbms_SessionList[i]->list.count);
for(int ii=0; ii < RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i]->list.count;ii++){
LOG_I(MAC, "PMCH[%d] MBMS Session[%d] is: %lu\n", i,ii,
RC.mac[Mod_idP]->common_channels[0].mbms_SessionList[i]->list.array[ii]->logicalChannelIdentity_r9);
}
}
}
@@ -920,55 +1044,53 @@ int rrc_mac_config_req_eNB(module_id_t Mod_idP,
//-----------------------------------------------------------------------------
/*
* Configure local DRX timers and thresholds following the drx_configuration input
* Configure local CDRX timers and thresholds following the drx_configuration input
*/
void eNB_Config_Local_DRX(
module_id_t Mod_id,
rnti_t rnti,
LTE_DRX_Config_t *const drx_Configuration
)
void eNB_Config_Local_DRX(instance_t Mod_id,
rrc_mac_drx_config_req_t *rrc_mac_drx_config_req)
//-----------------------------------------------------------------------------
{
UE_list_t *UE_list_mac = NULL;
int UE_id = -1;
UE_sched_ctrl_t *UE_scheduling_control = NULL;
int UE_id = -1;
rnti_t rnti = rrc_mac_drx_config_req->rnti;
LTE_DRX_Config_t *const drx_Configuration = rrc_mac_drx_config_req->drx_Configuration;
UE_list_mac = &(RC.mac[Mod_id]->UE_list);
UE_id = find_UE_id(Mod_id, rnti);
/* Check UE_id */
if (UE_id == -1) {
LOG_E(MAC, "%s:%d:%s: ERROR, UE_id == -1\n",
__FILE__,
__LINE__,
__FUNCTION__);
LOG_E(MAC, "[eNB_Config_Local_DRX] UE_id == -1\n");
return;
}
/* Get struct to modify */
UE_scheduling_control = &(UE_list_mac->UE_sched_ctrl[UE_id]);
UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when no error
/* Check drx_Configuration */
if (drx_Configuration == NULL) {
LOG_I(MAC, "drx_Configuration parameter is NULL, cannot configure local UE parameters\n");
UE_scheduling_control->cdrx_configured = FALSE;
LOG_W(MAC, "[eNB_Config_Local_DRX] drx_Configuration parameter is NULL, cannot configure local UE parameters for CDRX\n");
return;
}
/* Check if drx config present */
if (drx_Configuration->present != LTE_DRX_Config_PR_setup) {
LOG_I(MAC, "No drx_Configuration present, don't configure local UE parameters\n");
UE_scheduling_control->cdrx_configured = FALSE;
LOG_I(MAC, "[eNB_Config_Local_DRX] No drx_Configuration present, don't configure local UE parameters for CDRX\n");
return;
}
/* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */
UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when ACK is received
UE_scheduling_control->cdrx_waiting_ack = TRUE; // set to true first, waiting for the UE to configure CDRX on its side
/* Modify scheduling control structure according to DRX configuration: doesn't support every configurations! */
UE_scheduling_control->cdrx_configured = FALSE; // will be set to true when receiving RRC Reconfiguration Complete
UE_scheduling_control->cdrx_waiting_ack = TRUE; // waiting for RRC Reconfiguration Complete message
UE_scheduling_control->in_active_time = FALSE;
UE_scheduling_control->dci0_ongoing_timer = 0;
UE_scheduling_control->on_duration_timer = 0;
struct LTE_DRX_Config__setup *choiceSetup = &drx_Configuration->choice.setup;
switch (drx_Configuration->choice.setup.onDurationTimer) {
switch (choiceSetup->onDurationTimer) {
case 0:
UE_scheduling_control->on_duration_timer_thres = 1;
break;
@@ -1034,13 +1156,13 @@ void eNB_Config_Local_DRX(
break;
default:
LOG_E(MAC, "Error in local DRX configuration, the on duration timer value specified is unknown\n");
LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the on duration timer value specified is unknown\n");
break;
}
UE_scheduling_control->drx_inactivity_timer = 0;
switch (drx_Configuration->choice.setup.drx_InactivityTimer) {
switch (choiceSetup->drx_InactivityTimer) {
case 0:
UE_scheduling_control->drx_inactivity_timer_thres = 1;
break;
@@ -1134,11 +1256,11 @@ void eNB_Config_Local_DRX(
break;
default:
LOG_E(MAC, "Error in local DRX configuration, the drx inactivity timer value specified is unknown\n");
LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx inactivity timer value specified is unknown\n");
break;
}
if (drx_Configuration->choice.setup.shortDRX == NULL) {
if (choiceSetup->shortDRX == NULL) {
UE_scheduling_control->in_short_drx_cycle = FALSE;
UE_scheduling_control->drx_shortCycle_timer_value = 0;
UE_scheduling_control->short_drx_cycle_duration = 0;
@@ -1146,9 +1268,9 @@ void eNB_Config_Local_DRX(
UE_scheduling_control->drx_shortCycle_timer_thres = -1;
} else {
UE_scheduling_control->in_short_drx_cycle = FALSE;
UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) drx_Configuration->choice.setup.shortDRX->drxShortCycleTimer;
UE_scheduling_control->drx_shortCycle_timer_value = (uint8_t) choiceSetup->shortDRX->drxShortCycleTimer;
switch (drx_Configuration->choice.setup.shortDRX->shortDRX_Cycle) {
switch (choiceSetup->shortDRX->shortDRX_Cycle) {
case 0:
UE_scheduling_control->short_drx_cycle_duration = 2;
break;
@@ -1214,7 +1336,7 @@ void eNB_Config_Local_DRX(
break;
default:
LOG_E(MAC, "Error in local DRX configuration, the short drx timer value specified is unknown\n");
LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the short drx timer value specified is unknown\n");
break;
}
@@ -1225,95 +1347,95 @@ void eNB_Config_Local_DRX(
UE_scheduling_control->in_long_drx_cycle = FALSE;
UE_scheduling_control->drx_longCycle_timer = 0;
switch (drx_Configuration->choice.setup.longDRX_CycleStartOffset.present) {
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10:
switch (choiceSetup->longDRX_CycleStartOffset.present) {
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf10:
UE_scheduling_control->drx_longCycle_timer_thres = 10;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf10;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf10;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf20:
UE_scheduling_control->drx_longCycle_timer_thres = 20;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf20;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf20;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf32:
UE_scheduling_control->drx_longCycle_timer_thres = 32;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf32;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf32;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf40:
UE_scheduling_control->drx_longCycle_timer_thres = 40;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf40;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf40;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf64:
UE_scheduling_control->drx_longCycle_timer_thres = 64;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf64;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf64;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf80:
UE_scheduling_control->drx_longCycle_timer_thres = 80;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf80;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf80;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf128:
UE_scheduling_control->drx_longCycle_timer_thres = 128;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf128;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf128;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf160:
UE_scheduling_control->drx_longCycle_timer_thres = 160;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf160;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf160;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf256:
UE_scheduling_control->drx_longCycle_timer_thres = 256;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf256;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf256;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf320:
UE_scheduling_control->drx_longCycle_timer_thres = 320;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf320;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf320;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf512:
UE_scheduling_control->drx_longCycle_timer_thres = 512;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf512;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf512;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf640:
UE_scheduling_control->drx_longCycle_timer_thres = 640;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf640;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf640;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1024:
UE_scheduling_control->drx_longCycle_timer_thres = 1024;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1024;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1024;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf1280:
UE_scheduling_control->drx_longCycle_timer_thres = 1280;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf1280;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf1280;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2048:
UE_scheduling_control->drx_longCycle_timer_thres = 2048;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2048;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2048;
break;
case LTE_DRX_Config__setup__longDRX_CycleStartOffset_PR_sf2560:
UE_scheduling_control->drx_longCycle_timer_thres = 2560;
UE_scheduling_control->drx_start_offset = (uint16_t) drx_Configuration->choice.setup.longDRX_CycleStartOffset.choice.sf2560;
UE_scheduling_control->drx_start_offset = (uint16_t) choiceSetup->longDRX_CycleStartOffset.choice.sf2560;
break;
default:
LOG_E(MAC, "Invalid long_DRX value in DRX local configuration\n");
LOG_E(MAC, "[eNB_Config_Local_DRX] Invalid long_DRX value in DRX local configuration\n");
break;
}
memset(UE_scheduling_control->drx_retransmission_timer, 0, sizeof(UE_scheduling_control->drx_retransmission_timer));
switch (drx_Configuration->choice.setup.drx_RetransmissionTimer) {
switch (choiceSetup->drx_RetransmissionTimer) {
case 0:
memset(UE_scheduling_control->drx_retransmission_timer_thres, 1, sizeof(UE_scheduling_control->drx_retransmission_timer_thres));
break;
@@ -1347,7 +1469,7 @@ void eNB_Config_Local_DRX(
break;
default:
LOG_E(MAC, "Error in local DRX configuration, the drx retransmission timer value specified is unknown\n");
LOG_E(MAC, "[eNB_Config_Local_DRX] Error in local DRX configuration, the drx retransmission timer value specified is unknown\n");
break;
}
}
+4 -1
View File
@@ -140,7 +140,7 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
phy_config_sib2_ue(Mod_idP, 0, eNB_index,
radioResourceConfigCommon, ul_CarrierFreq,
ul_Bandwidth, additionalSpectrumEmission,
mbsfn_SubframeConfigList);
NULL/*mbsfn_SubframeConfigList*/);
}
// SRB2_lchan_config->choice.explicitValue.ul_SpecificParameters->logicalChannelGroup
@@ -469,6 +469,9 @@ rrc_mac_config_req_ue(module_id_t Mod_idP,
}
if (mbsfn_SubframeConfigList != NULL) {
phy_config_mbsfn_list_ue(Mod_idP, 0,
mbsfn_SubframeConfigList);
LOG_I(MAC,
"[UE %d][CONFIG] Received %d subframe allocation pattern for MBSFN\n",
Mod_idP, mbsfn_SubframeConfigList->list.count);
+1 -1
View File
@@ -320,7 +320,7 @@ typedef struct {
/*!\brief DTCH DRB1 logical channel */
#define DTCH 3 // LCID
/*!\brief MCCH logical channel */
#define MCCH 4
#define MCCH 11
/*!\brief MTCH logical channel */
#define MTCH 1
// DLSCH LCHAN ID
+2 -1
View File
@@ -64,7 +64,8 @@
#define DTCH 3 // LCID
/*!\brief MCCH logical channel */
//#define MCCH 4
#define MCCH 62
//#define MCCH 62
#define MCCH 11
/*!\brief MTCH logical channel */
#define MTCH 1
// DLSCH LCHAN ID
+6 -1
View File
@@ -899,13 +899,18 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP,
#if (!defined(PRE_SCD_THREAD))
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP, module_idP);
pdcp_run(&ctxt);
pdcp_mbms_run(&ctxt);
rrc_rx_tx(&ctxt, CC_id);
#endif
for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
if (cc[CC_id].MBMS_flag > 0) {
start_meas(&RC.mac[module_idP]->schedule_mch);
mbsfn_status[CC_id] = schedule_MBMS(module_idP, CC_id, frameP, subframeP);
int(*schedule_mch)(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframe) = NULL;
schedule_mch = schedule_MBMS_NFAPI;
if(schedule_mch){
mbsfn_status[CC_id] = schedule_mch(module_idP, CC_id, frameP, subframeP);
}
stop_meas(&RC.mac[module_idP]->schedule_mch);
}
}
@@ -507,6 +507,13 @@ schedule_ue_spec(module_id_t module_idP,
rrc_eNB_ue_context_t *ue_contextP = NULL;
int nb_mac_CC = RC.nb_mac_CC[module_idP];
long dl_Bandwidth;
if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){
//LOG_E(MAC,"Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP);
return ;
}
start_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,
VCD_FUNCTION_IN);
@@ -854,6 +854,12 @@ schedule_ue_spec_fairRR(module_id_t module_idP,
#ifdef DEBUG_eNB_SCHEDULER
int k;
#endif
if(is_pmch_subframe(frameP,subframeP,&RC.eNB[module_idP][0]->frame_parms)){
//LOG_E(MAC,"fairRR Frame[%d] SF:%d This SF should not be allocated\n",frameP,subframeP);
return;
}
start_meas(&eNB->schedule_dlsch);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
File diff suppressed because it is too large Load Diff
@@ -1586,6 +1586,39 @@ fill_nfapi_uci_acknak(module_id_t module_idP,
return (((ackNAK_absSF / 10) << 4) + (ackNAK_absSF % 10));
}
//------------------------------------------------------------------------------
void
fill_nfapi_mch_config(nfapi_dl_config_request_body_t *dl_req,
uint16_t length,
uint16_t pdu_index,
uint16_t rnti,
uint8_t resource_allocation_type,
uint16_t resource_block_coding,
uint8_t modulation,
uint16_t transmission_power,
uint8_t mbsfn_area_id){
nfapi_dl_config_request_pdu_t *dl_config_pdu =
&dl_req->dl_config_pdu_list[dl_req->number_pdu];
memset((void *) dl_config_pdu, 0,
sizeof(nfapi_dl_config_request_pdu_t));
dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_MCH_PDU_TYPE;
dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_mch_pdu));
dl_config_pdu->mch_pdu.mch_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_MCH_PDU_REL8_TAG;
dl_config_pdu->mch_pdu.mch_pdu_rel8.length = length;
dl_config_pdu->mch_pdu.mch_pdu_rel8.pdu_index = pdu_index;
dl_config_pdu->mch_pdu.mch_pdu_rel8.rnti = rnti;
dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_allocation_type = resource_allocation_type;
dl_config_pdu->mch_pdu.mch_pdu_rel8.resource_block_coding = resource_block_coding;
dl_config_pdu->mch_pdu.mch_pdu_rel8.modulation = modulation;
dl_config_pdu->mch_pdu.mch_pdu_rel8.transmission_power = transmission_power;
dl_config_pdu->mch_pdu.mch_pdu_rel8.mbsfn_area_id = mbsfn_area_id;
dl_req->number_pdu++;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
+4 -2
View File
@@ -411,8 +411,9 @@ typedef struct {
#define BCCH_SIB1_BR 6 // SIB1_BR
/*!\brief Values of BCCH SIB_BR logical channel (fake) */
#define BCCH_SI_BR 7 // SI-BR
/*!\brief Values of BCCH SIB1_BR logical channel (fake) */
/*!\brief Values of BCCH SIB1_MBMS logical channel (fake) */
#define BCCH_SIB1_MBMS 60 // SIB1_MBMS //TODO better armonize index
/*!\brief Values of BCCH SI_MBMS logical channel (fake) */
#define BCCH_SI_MBMS 61 // SIB_MBMS //TODO better armonize index
/*!\brief Value of CCCH / SRB0 logical channel */
#define CCCH 0 // srb0
@@ -424,7 +425,8 @@ typedef struct {
#define DTCH 3 // LCID
/*!\brief MCCH logical channel */
//#define MCCH 4
#define MCCH 62
//#define MCCH 62
#define MCCH 11
/*!\brief MTCH logical channel */
#define MTCH 1
// DLSCH LCHAN ID
+24 -1
View File
@@ -31,6 +31,7 @@
#include "LAYER2/MAC/mac.h"
#include "PHY/defs_common.h" // for PRACH_RESOURCES_t and lte_subframe_t
#include "openair2/COMMON/mac_messages_types.h"
/** \addtogroup _mac
@@ -85,6 +86,14 @@ void schedule_SI_MBMS(module_id_t module_idP, frame_t frameP,
int schedule_MBMS(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
sub_frame_t subframe);
/** \brief MBMS scheduling: Checking the position for MBSFN subframes. Create MSI, transfer MCCH from RRC to MAC, transfer MTCHs from RLC to MAC. Multiplexing MSI,MCCH&MTCHs. Return 1 if there are MBSFN data being allocated, otherwise return 0;
@param Mod_id Instance ID of eNB
@param frame Frame index
@param subframe Subframe number on which to act
*/
int schedule_MBMS_NFAPI(module_id_t module_idP, uint8_t CC_id, frame_t frameP, sub_frame_t subframe);
/** \brief check the mapping between sf allocation and sync area, Currently only supports 1:1 mapping
@param Mod_id Instance ID of eNB
@param mbsfn_sync_area index of mbsfn sync area
@@ -1192,6 +1201,16 @@ void fill_nfapi_dlsch_config(eNB_MAC_INST *eNB,
uint8_t num_bf_prb_per_subband,
uint8_t num_bf_vector);
void fill_nfapi_mch_config(nfapi_dl_config_request_body_t *dl_req,
uint16_t length,
uint16_t pdu_index,
uint16_t rnti,
uint8_t resource_allocation_type,
uint16_t resource_block_coding,
uint8_t modulation,
uint16_t transmission_power,
uint8_t mbsfn_area_id);
void fill_nfapi_harq_information(module_id_t module_idP,
int CC_idP,
uint16_t rntiP,
@@ -1265,9 +1284,13 @@ int ue_ul_slice_membership(module_id_t mod_id, int UE_id, int slice_idx);
/* DRX Configuration */
/* Configure local DRX timers and thresholds in UE context, following the drx_configuration input */
void eNB_Config_Local_DRX(module_id_t Mod_id, rnti_t rnti, LTE_DRX_Config_t *drx_Configuration);
void eNB_Config_Local_DRX(instance_t Mod_id, rrc_mac_drx_config_req_t *rrc_mac_drx_config_req);
/* from here: prototypes to get rid of compilation warnings: doc to be written by function author */
uint8_t ul_subframe2_k_phich(COMMON_channels_t *cc, sub_frame_t ul_subframe);
#endif
/** @}*/
/* MAC ITTI messaging related functions */
/* Main loop of MAC itti message handling */
void *mac_enb_task(void *arg);
+45 -4
View File
@@ -34,15 +34,12 @@
#include "mac_proto.h"
#include "mac_extern.h"
#include "assertions.h"
//#include "PHY_INTERFACE/phy_extern.h"
//#include "PHY/defs_eNB.h"
//#include "SCHED/sched_eNB.h"
#include "LAYER2/PDCP_v10.1.0/pdcp.h"
#include "RRC/LTE/rrc_defs.h"
#include "common/utils/LOG/log.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
#include "common/ran_context.h"
#include "intertask_interface.h"
extern RAN_CONTEXT_t RC;
@@ -223,3 +220,47 @@ int l2_init_eNB(void)
return (1);
}
//-----------------------------------------------------------------------------
/*
* Main loop of MAC itti message handling
*/
void *mac_enb_task(void *arg)
//-----------------------------------------------------------------------------
{
MessageDef *received_msg = NULL;
int result;
itti_mark_task_ready(TASK_MAC_ENB); // void function 10/2019
LOG_I(MAC,"Starting main loop of MAC message task\n");
while (1) {
itti_receive_msg(TASK_MAC_ENB, &received_msg);
switch (ITTI_MSG_ID(received_msg)) {
case RRC_MAC_DRX_CONFIG_REQ:
LOG_I(MAC, "MAC Task Received RRC_MAC_DRX_CONFIG_REQ\n");
/* Set timers and thresholds values in local MAC context of UE */
eNB_Config_Local_DRX(ITTI_MESSAGE_GET_INSTANCE(received_msg), &received_msg->ittiMsg.rrc_mac_drx_config_req);
break;
case TERMINATE_MESSAGE:
LOG_W(MAC, " *** Exiting MAC thread\n");
itti_exit_task();
break;
default:
LOG_E(MAC, "MAC instance received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg),
ITTI_MSG_NAME(received_msg));
break;
} // end switch
result = itti_free(ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
received_msg = NULL;
} // end while
return NULL;
}
+28 -10
View File
@@ -74,6 +74,8 @@ extern UL_IND_t *UL_INFO;
extern int next_ra_frame;
extern module_id_t next_Mod_id;
int mbms_rab_id = 2047;
/*
*
#ifndef USER_MODE
@@ -792,6 +794,9 @@ ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP,
if (j<28 && UE_mac_inst[module_idP].msi_status_v[j]==1) {
LOG_D(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes), j=%d\n", module_idP, frameP, sync_area, eNB_index, rx_lengths[i], j);
//This sucks I know ... workaround !
mbms_rab_id = rx_lcids[i];
//end sucks :-(
mac_rlc_data_ind(
module_idP,
UE_mac_inst[module_idP].crnti,
@@ -1096,6 +1101,7 @@ int ue_query_p_mch(module_id_t module_idP, uint32_t frameP, uint32_t subframe, i
int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active) {
int i = 0, j = 0, ii = 0, jj = 0, msi_pos = 0, mcch_mcs = -1, mtch_mcs = -1;
int l =0;
int mcch_flag = 0, mtch_flag = 0, msi_flag = 0;
long mch_scheduling_period = -1;
uint8_t mch_lcid = 0;
@@ -1347,28 +1353,40 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
// Acount for sf_allocable in CSA
int num_sf_alloc = 0;
for (i = 0; i < 8; i++) {
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i] == NULL)
for (l = 0; l < 8; l++) {
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l] == NULL)
continue;
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
if (UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.present != LTE_MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame)
continue;
uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[i]->subframeAllocation.choice.oneFrame.buf[0];
uint32_t common_mbsfn_SubframeConfig = UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[l]->subframeAllocation.choice.oneFrame.buf[0];
for (j = 0; j < 6; j++)
num_sf_alloc += ((common_mbsfn_SubframeConfig & (0x80 >> j)) == (0x80 >> j));
//num_sf_alloc=1;
}
for (i = 0; i < 28; i++) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[i] >= num_sf_alloc) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[i] != 2047) {
if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL)
for (l = 0; l < 28; l++) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[l] >= 1/*num_sf_alloc*/) {
if (UE_mac_inst[module_idP].pmch_stop_mtch[l] != 2047) {
if (UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch] != NULL){
mtch_mcs = UE_mac_inst[module_idP].pmch_Config[UE_mac_inst[module_idP].msi_pmch]->dataMCS_r9;
long common_mbsfn_period = 1 << UE_mac_inst[module_idP].commonSF_Alloc_r9_mbsfn_SubframeConfig[0]->radioframeAllocationPeriod;
long commonSF_AllocPeriod = 4 << UE_mac_inst[module_idP].commonSF_AllocPeriod_r9;
if(UE_mac_inst[module_idP].common_num_sf_alloc >= UE_mac_inst[module_idP].pmch_stop_mtch[l]){
//LOG_E(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc);
mtch_mcs = -1;
}/*else
LOG_W(MAC,"Attemp to UE_mac_inst[module_idP].common_num_sf_alloc %d\n",UE_mac_inst[module_idP].common_num_sf_alloc);*/
UE_mac_inst[module_idP].common_num_sf_alloc++;
UE_mac_inst[module_idP].common_num_sf_alloc = UE_mac_inst[module_idP].common_num_sf_alloc % (num_sf_alloc * commonSF_AllocPeriod / common_mbsfn_period);
}
else
mtch_mcs = -1;
mch_lcid = (uint8_t)i;
mch_lcid = (uint8_t)l;
break;
}
}
@@ -1377,7 +1395,7 @@ int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_
// sf allocation is non-overlapping
if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag);
module_idP, frameP, subframe,l,j,msi_flag,mcch_flag,mtch_flag);
*sync_area=i;
break;
}
+152 -11
View File
@@ -959,15 +959,15 @@ pdcp_data_ind(
#ifdef MBMS_MULTICAST_OUT
if ((MBMS_flagP != 0) && (mbms_socket != -1)) {
struct iphdr *ip_header = (struct iphdr *)&sdu_buffer_pP->data[payload_offset];
struct udphdr *udp_header = (struct udphdr *)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)];
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = udp_header->dest;
dest_addr.sin_addr.s_addr = ip_header->daddr;
// struct iphdr *ip_header = (struct iphdr *)&sdu_buffer_pP->data[payload_offset];
// struct udphdr *udp_header = (struct udphdr *)&sdu_buffer_pP->data[payload_offset + sizeof(struct iphdr)];
// struct sockaddr_in dest_addr;
// dest_addr.sin_family = AF_INET;
// dest_addr.sin_port = udp_header->dest;
// dest_addr.sin_addr.s_addr = ip_header->daddr;
sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
//packet_forwarded = TRUE;
// sendto(mbms_socket, &sdu_buffer_pP->data[payload_offset], sdu_buffer_sizeP - payload_offset, MSG_DONTWAIT, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
// //packet_forwarded = TRUE;
}
@@ -1251,6 +1251,132 @@ pdcp_run (
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT);
}
//-----------------------------------------------------------------------------
void
pdcp_mbms_run (
const protocol_ctxt_t *const ctxt_pP
)
//-----------------------------------------------------------------------------
{
// if (ctxt_pP->enb_flag) {
// start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// } else {
// start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// }
// pdcp_enb[ctxt_pP->module_id].sfn++; // range: 0 to 18,446,744,073,709,551,615
// pdcp_enb[ctxt_pP->module_id].frame=ctxt_pP->frame; // 1023
// pdcp_enb[ctxt_pP->module_id].subframe= ctxt_pP->subframe;
// pdcp_update_stats(ctxt_pP);
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_IN);
// MessageDef *msg_p;
//int result;
//protocol_ctxt_t ctxt;
// do {
// // Checks if a message has been sent to PDCP sub-task
// itti_poll_msg (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p);
//
// if (msg_p != NULL) {
// switch (ITTI_MSG_ID(msg_p)) {
// case RRC_DCCH_DATA_REQ:
// PROTOCOL_CTXT_SET_BY_MODULE_ID(
// &ctxt,
// RRC_DCCH_DATA_REQ (msg_p).module_id,
// RRC_DCCH_DATA_REQ (msg_p).enb_flag,
// RRC_DCCH_DATA_REQ (msg_p).rnti,
// RRC_DCCH_DATA_REQ (msg_p).frame,
// 0,
// RRC_DCCH_DATA_REQ (msg_p).eNB_index);
// LOG_D(PDCP, PROTOCOL_CTXT_FMT"Received %s from %s: instance %d, rb_id %d, muiP %d, confirmP %d, mode %d\n",
// PROTOCOL_CTXT_ARGS(&ctxt),
// ITTI_MSG_NAME (msg_p),
// ITTI_MSG_ORIGIN_NAME(msg_p),
// ITTI_MSG_INSTANCE (msg_p),
// RRC_DCCH_DATA_REQ (msg_p).rb_id,
// RRC_DCCH_DATA_REQ (msg_p).muip,
// RRC_DCCH_DATA_REQ (msg_p).confirmp,
// RRC_DCCH_DATA_REQ (msg_p).mode);
// LOG_D(PDCP, "Before calling pdcp_data_req from pdcp_run! RRC_DCCH_DATA_REQ (msg_p).rb_id: %d \n", RRC_DCCH_DATA_REQ (msg_p).rb_id);
// result = pdcp_data_req (&ctxt,
// SRB_FLAG_YES,
// RRC_DCCH_DATA_REQ (msg_p).rb_id,
// RRC_DCCH_DATA_REQ (msg_p).muip,
// RRC_DCCH_DATA_REQ (msg_p).confirmp,
// RRC_DCCH_DATA_REQ (msg_p).sdu_size,
// RRC_DCCH_DATA_REQ (msg_p).sdu_p,
// RRC_DCCH_DATA_REQ (msg_p).mode,
// NULL, NULL
// );
//
// if (result != TRUE)
// LOG_E(PDCP, "PDCP data request failed!\n");
//
// // Message buffer has been processed, free it now.
// result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ (msg_p).sdu_p);
// AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
// break;
//
// case RRC_PCCH_DATA_REQ: {
// sdu_size_t sdu_buffer_sizeP;
// sdu_buffer_sizeP = RRC_PCCH_DATA_REQ(msg_p).sdu_size;
// uint8_t CC_id = RRC_PCCH_DATA_REQ(msg_p).CC_id;
// uint8_t ue_index = RRC_PCCH_DATA_REQ(msg_p).ue_index;
// RC.rrc[ctxt_pP->module_id]->carrier[CC_id].sizeof_paging[ue_index] = sdu_buffer_sizeP;
//
// if (sdu_buffer_sizeP > 0) {
// memcpy(RC.rrc[ctxt_pP->module_id]->carrier[CC_id].paging[ue_index], RRC_PCCH_DATA_REQ(msg_p).sdu_p, sdu_buffer_sizeP);
// }
//
// //paging pdcp log
// LOG_D(PDCP, "PDCP Received RRC_PCCH_DATA_REQ CC_id %d length %d \n", CC_id, sdu_buffer_sizeP);
// }
// break;
//
// default:
// LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME (msg_p));
// break;
// }
//
// result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
// AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
// }
// } while(msg_p != NULL);
//
// IP/NAS -> PDCP traffic : TX, read the pkt from the upper layer buffer
// if (LINK_ENB_PDCP_TO_GTPV1U && ctxt_pP->enb_flag == ENB_FLAG_NO) {
//if (EPC_MODE_ENABLED || ctxt_pP->enb_flag == ENB_FLAG_NO ) {
pdcp_fifo_read_input_mbms_sdus_fromtun(ctxt_pP);
//}
// PDCP -> NAS/IP traffic: RX
// if (ctxt_pP->enb_flag) {
// start_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// } else {
// start_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// }
//
//pdcp_fifo_flush_mbms_sdus(ctxt_pP);
// if (ctxt_pP->enb_flag) {
// stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// } else {
// stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_ip);
// }
//
// if (ctxt_pP->enb_flag) {
// stop_meas(&eNB_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// } else {
// stop_meas(&UE_pdcp_stats[ctxt_pP->module_id].pdcp_run);
// }
//
// VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN, VCD_FUNCTION_OUT);
}
void pdcp_init_stats_UE(module_id_t mod, uint16_t uid) {
Pdcp_stats_tx_window_ms[mod][uid] = 100;
Pdcp_stats_rx_window_ms[mod][uid] = 100;
@@ -1695,7 +1821,7 @@ rrc_pdcp_config_asn1_req (
for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) {
MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j];
if (MBMS_SessionInfo_p->sessionId_r9)
if (0/*MBMS_SessionInfo_p->sessionId_r9*/)
lc_id = MBMS_SessionInfo_p->sessionId_r9->buf[0];
else
lc_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9;
@@ -1722,7 +1848,7 @@ rrc_pdcp_config_asn1_req (
}
}
LOG_D(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n",
LOG_I(PDCP, "lc_id (%02ld) mch_id(%02x,%02x,%02x) drb_id(%ld) action(%d)\n",
lc_id,
MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[0],
MBMS_SessionInfo_p->tmgi_r9.serviceId_r9.buf[1],
@@ -2174,16 +2300,31 @@ uint64_t pdcp_module_init( uint64_t pdcp_optmask ) {
//Add --nr-ip-over-lte option check for next line
if (IS_SOFTMODEM_NOS1)
nas_config(1, 1, 2, "ue");
netlink_init_mbms_tun("uem",num_if);
nas_config_mbms(1, 2, 2, "uem");
LOG_I(PDCP, "UE pdcp will use tun interface\n");
} else if(ENB_NAS_USE_TUN) {
netlink_init_tun("enb",1);
nas_config(1, 1, 1, "enb");
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
netlink_init_mbms_tun("enm",1);
nas_config_mbms(1, 2, 1, "enm");
LOG_I(PDCP, "ENB pdcp will use mbms tun interface\n");
}
LOG_I(PDCP, "ENB pdcp will use tun interface\n");
} else {
LOG_I(PDCP, "pdcp will use kernel modules\n");
netlink_init();
}
}
}else{
if(pdcp_optmask & ENB_NAS_USE_TUN_W_MBMS_BIT){
LOG_W(PDCP, "ENB pdcp will use tun interface for MBMS\n");
netlink_init_mbms_tun("enm",1);
nas_config_mbms_s1(1, 2, 1, "enm");
}else
LOG_E(PDCP, "ENB pdcp will not use tun interface\n");
}
return pdcp_params.optmask ;
}
+15
View File
@@ -61,6 +61,7 @@ typedef boolean_t (*pdcp_data_ind_func_t)( const protocol_ctxt_t *, const srb_fl
/* UEs beyond that will be multiplexed on the same tun */
#define MAX_NUMBER_NETIF 16
#define ENB_NAS_USE_TUN_W_MBMS_BIT (1<< 10)
#define PDCP_USE_NETLINK_BIT (1<< 11)
#define LINK_ENB_PDCP_TO_IP_DRIVER_BIT (1<< 13)
#define LINK_ENB_PDCP_TO_GTPV1U_BIT (1<< 14)
@@ -388,6 +389,17 @@ boolean_t pdcp_remove_UE(
*/
//void rrc_pdcp_config_release ( const protocol_ctxt_t* const ctxt_pP, rb_id_t);
/*! \fn void pdcp_mbms_run(const protocol_ctxt_t* const ctxt_pP)
* \brief Runs PDCP entity to let it handle incoming/outgoing SDUs
* \param[in] ctxt_pP Running context.
* \return none
* \note None
* @ingroup _pdcp
*/
void pdcp_mbms_run (
const protocol_ctxt_t *const ctxt_pP);
/*! \fn void pdcp_run(const protocol_ctxt_t* const ctxt_pP)
* \brief Runs PDCP entity to let it handle incoming/outgoing SDUs
* \param[in] ctxt_pP Running context.
@@ -413,6 +425,9 @@ void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req);
void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind);
pdcp_data_ind_func_t get_pdcp_data_ind_func(void);
//-----------------------------------------------------------------------------
int pdcp_fifo_flush_mbms_sdus ( const protocol_ctxt_t *const ctxt_pP);
int pdcp_fifo_read_input_mbms_sdus_fromtun ( const protocol_ctxt_t *const ctxt_pP);
/*
* Following two types are utilized between NAS driver and PDCP
+155 -1
View File
@@ -77,6 +77,11 @@ extern struct iovec nas_iov_rx;
extern int nas_sock_fd[MAX_MOBILES_PER_ENB];
extern int nas_sock_mbms_fd[8];
extern int mbms_rab_id;
extern struct msghdr nas_msg_tx;
extern struct msghdr nas_msg_rx;
@@ -125,7 +130,16 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) );
} else if (UE_NAS_USE_TUN) {
ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
//ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
if(rb_id == mbms_rab_id){
ret = write(nas_sock_mbms_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
else
{
ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
}
} else if (ENB_NAS_USE_TUN) {
ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
} else if (PDCP_USE_NETLINK) {
@@ -150,6 +164,47 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) {
return pdcp_nb_sdu_sent;
}
int pdcp_fifo_flush_mbms_sdus(const protocol_ctxt_t *const ctxt_pP) {
mem_block_t *sdu_p;
int pdcp_nb_sdu_sent = 0;
//int ret=0;
while ((sdu_p = list_get_head (&pdcp_sdu_list)) != NULL && ((pdcp_data_ind_header_t *)(sdu_p->data))->inst == ctxt_pP->module_id) {
((pdcp_data_ind_header_t *)(sdu_p->data))->inst = 0;
//int rb_id = ((pdcp_data_ind_header_t *)(sdu_p->data))->rb_id;
//int sizeToWrite= sizeof (pdcp_data_ind_header_t) +
//((pdcp_data_ind_header_t *) sdu_p->data)->data_size;
//if (rb_id == 10) { //hardcoded for PC5-Signaling
// if( LOG_DEBUGFLAG(DEBUG_PDCP) ) {
// debug_pdcp_pc5s_sdu((sidelink_pc5s_element *)&(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
// "pdcp_fifo_flush_sdus sends a aPC5S message");
// }
// ret = sendto(pdcp_pc5_sockfd, &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),
// sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) );
//} else if (UE_NAS_USE_TUN) {
// ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
// LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n",ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite);
//} else if (ENB_NAS_USE_TUN) {
// ret = write(nas_sock_fd[0], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite );
//} else if (PDCP_USE_NETLINK) {
// memcpy(NLMSG_DATA(nas_nlh_tx), (uint8_t *) sdu_p->data, sizeToWrite);
// nas_nlh_tx->nlmsg_len = sizeToWrite;
// ret = sendmsg(nas_sock_fd[0],&nas_msg_tx,0);
//} // PDCP_USE_NETLINK
//AssertFatal(ret >= 0,"[PDCP_FIFOS] pdcp_fifo_flush_sdus (errno: %d %s)\n", errno, strerror(errno));
list_remove_head (&pdcp_sdu_list);
free_mem_block (sdu_p, __func__);
pdcp_nb_sdu_sent ++;
}
return pdcp_nb_sdu_sent;
}
int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
protocol_ctxt_t ctxt = *ctxt_pP;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
@@ -203,6 +258,105 @@ int pdcp_fifo_read_input_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
return len;
}
int pdcp_fifo_read_input_mbms_sdus_fromtun (const protocol_ctxt_t *const ctxt_pP) {
protocol_ctxt_t ctxt = *ctxt_pP;
hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
hashtable_rc_t h_rc = HASH_TABLE_OK;
//pdcp_t *pdcp_p = NULL;
int len;
rb_id_t rab_id = mbms_rab_id;//DEFAULT_RAB_ID;
if(mbms_rab_id > 9 || mbms_rab_id < 4)
h_rc = 2;
if(UE_NAS_USE_TUN)
return 0;
do {
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, 1 );
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 1 );
len = read(UE_NAS_USE_TUN?nas_sock_mbms_fd[0]:nas_sock_mbms_fd[0], &nl_rx_buf, NL_MAX_PAYLOAD);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ_BUFFER, 0 );
if (len<=0) continue;
if (UE_NAS_USE_TUN) {
//key = PDCP_COLL_KEY_DEFAULT_DRB_VALUE(ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
//h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
} else { // => ENB_NAS_USE_TUN
//ctxt.rnti=pdcp_eNB_UE_instance_to_rnti[0];
// ctxt.enb_flag=ENB_FLAG_YES;
// ctxt.module_id=0;
// key = PDCP_COLL_KEY_VALUE(ctxt.module_id, /*ctxt.rnti*/0, ctxt.enb_flag, /*mbms_rab_id*/8, SRB_FLAG_YES);
// h_rc = hashtable_get(pdcp_coll_p, key, (void **)&pdcp_p);
// LOG_W(PDCP,"h_rc %d %d\n",h_rc,rab_id);
}
LOG_D(PDCP, "PDCP_COLL_KEY_DEFAULT_DRB_VALUE(module_id=%d, rnti=%x, enb_flag=%d)\n",
ctxt.module_id, ctxt.rnti, ctxt.enb_flag);
if (h_rc == HASH_TABLE_OK) {
LOG_I(PDCP, "[FRAME %5u][UE][NETLINK][IP->PDCP] INST %d: Received socket with length %d on Rab %d \n",
ctxt.frame, ctxt.instance, len, rab_id);
LOG_D(PDCP, "[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes --->][PDCP][MOD %u][UE %04x][RB %u]\n",
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
ctxt.rnti, rab_id);
MSC_LOG_RX_MESSAGE((ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
NULL, 0,
MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ctxt.instance, rab_id, rab_id, len);
pdcp_data_req(
&ctxt,
SRB_FLAG_NO,
//DEFAULT_RAB_ID,
rab_id,
RLC_MUI_UNDEFINED,
RLC_SDU_CONFIRM_NO,
len,
(unsigned char *)nl_rx_buf,
PDCP_TRANSMISSION_MODE_TRANSPARENT
, NULL, NULL
);
//pdcp_data_req(&ctxt, SRB_FLAG_NO, rab_id, RLC_MUI_UNDEFINED,
// RLC_SDU_CONFIRM_NO, len, (unsigned char *)nl_rx_buf,
// PDCP_TRANSMISSION_MODE_DATA
// , NULL, NULL
// );
} else {
MSC_LOG_RX_DISCARDED_MESSAGE(
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_PDCP_ENB:MSC_PDCP_UE,
(ctxt_pP->enb_flag == ENB_FLAG_YES) ? MSC_IP_ENB:MSC_IP_UE,
NULL,
0,
MSC_AS_TIME_FMT" DATA-REQ inst %u rb %u rab %u size %u",
MSC_AS_TIME_ARGS(ctxt_pP),
ctxt.instance, rab_id, rab_id, len);
LOG_D(PDCP,
"[FRAME %5u][UE][IP][INSTANCE %u][RB %u][--- PDCP_DATA_REQ / %d Bytes ---X][PDCP][MOD %u][UE %04x][RB %u] NON INSTANCIATED INSTANCE key 0x%"PRIx64", DROPPED\n",
ctxt.frame, ctxt.instance, rab_id, len, ctxt.module_id,
ctxt.rnti, rab_id, key);
//if (!UE_NAS_USE_TUN) {
// pdcp_data_req(
// &ctxt,
// SRB_FLAG_NO,
// DEFAULT_RAB_ID,
// RLC_MUI_UNDEFINED,
// RLC_SDU_CONFIRM_NO,
// len,
// (unsigned char *)nl_rx_buf,
// PDCP_TRANSMISSION_MODE_TRANSPARENT
// , NULL, NULL
// );
//}
}
} while (len > 0);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_MBMS_FIFO_READ, 0 );
return len;
}
int pdcp_fifo_read_input_sdus_fromnetlinksock (const protocol_ctxt_t *const ctxt_pP) {
int len = 1;
int rlc_data_req_flag = 3;
+9 -9
View File
@@ -339,7 +339,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP
for (j=0; j<mbms_SessionInfoList_r9_p->list.count; j++) {
MBMS_SessionInfo_p = mbms_SessionInfoList_r9_p->list.array[j];
if (MBMS_SessionInfo_p->sessionId_r9)
if (0/*MBMS_SessionInfo_p->sessionId_r9*/)
mbms_session_id = MBMS_SessionInfo_p->sessionId_r9->buf[0];
else
mbms_session_id = MBMS_SessionInfo_p->logicalChannelIdentity_r9;
@@ -379,7 +379,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t *const ctxt_pP
}
}
LOG_D(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %ld SESSION ID %u SERVICE ID %u\n",
LOG_I(RLC, PROTOCOL_CTXT_FMT" CONFIG REQ MBMS ASN1 LC ID %u RB ID %u SESSION ID %u SERVICE ID %u\n",
PROTOCOL_CTXT_ARGS(ctxt_pP),
lc_id,
rb_id,
@@ -611,14 +611,14 @@ rlc_union_t *rrc_rlc_add_rlc (
}
key = RLC_COLL_KEY_MBMS_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, mbms_id_p->service_id, mbms_id_p->session_id);
}
if ((sourceL2Id > 0) && (destinationL2Id > 0) ) {
key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, sourceL2Id, destinationL2Id, srb_flagP);
key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, sourceL2Id, destinationL2Id, srb_flagP);
} else {
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
key_lcid = RLC_COLL_KEY_LCID_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, srb_flagP);
if ((sourceL2Id > 0) && (destinationL2Id > 0) ) {
key = RLC_COLL_KEY_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, sourceL2Id, destinationL2Id, srb_flagP);
key_lcid = RLC_COLL_KEY_LCID_SOURCE_DEST_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, sourceL2Id, destinationL2Id, srb_flagP);
} else {
key = RLC_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, rb_idP, srb_flagP);
key_lcid = RLC_COLL_KEY_LCID_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, chan_idP, srb_flagP);
}
}
h_rc = hashtable_get(rlc_coll_p, key, (void **)&rlc_union_p);
File diff suppressed because it is too large Load Diff
+697
View File
@@ -0,0 +1,697 @@
import re, os, sys, string
import datetime
import getopt
import getpass
version = "1.0.2"
lines = ""
iesDefs = {}
ieofielist = {}
outdir = './'
filenames = []
verbosity = 0
prefix = ""
FAIL = '\033[91m'
WARN = '\033[93m'
ENDC = '\033[0m'
fileprefix = ""
fileprefix_first_upper = ""
def printFail(string):
sys.stderr.write(FAIL + string + ENDC + "\n")
def printWarning(string):
print WARN + string + ENDC
def printDebug(string):
if verbosity > 0:
print string
def outputHeaderToFile(f, filename):
now = datetime.datetime.now()
f.write("""/*
* 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
*/
""")
f.write("/*******************************************************************************\n")
f.write(" * This file had been created by asn1tostruct.py script v%s\n" % (version))
f.write(" * Please do not modify this file but regenerate it via script.\n")
f.write(" * Created on: %s by %s\n * from %s\n" % (str(now), getpass.getuser(), filenames))
f.write(" ******************************************************************************/\n")
def lowerFirstCamelWord(word):
""" puts the first word in a CamelCase Word in lowercase.
I.e. CustomerID becomes customerID, XMLInfoTest becomes xmlInfoTest
"""
newstr = ''
swapped = word.swapcase()
idx = 0
# if it's all-caps, return an all-lowered version
lowered = word.lower()
if swapped == lowered:
return lowered
for c in swapped:
if c in string.lowercase:
newstr += c
idx += 1
else:
break
if idx < 2:
newstr += word[idx:]
else:
newstr = newstr[:-1]+ word[idx-1:]
return newstr
def usage():
print "Python parser for asn1 v%s" % (version)
print "Usage: python asn1tostruct.py [options]"
print "Available options:"
print "-d Enable script debug"
print "-f [file] Input file to parse"
print "-o [dir] Output files to given directory"
print "-h Print this help and return"
try:
opts, args = getopt.getopt(sys.argv[1:], "df:ho:", ["debug", "file", "help", "outdir"])
except getopt.GetoptError as err:
# print help information and exit:
usage()
sys.exit(2)
for o, a in opts:
if o in ("-f", "--file"):
filenames.append(a)
if o in ("-d", "--debug"):
verbosity = 1
if o in ("-o", "--outdir"):
outdir = a
if outdir.rfind('/') != len(outdir):
outdir += '/'
if o in ("-h", "--help"):
usage()
sys.exit(2)
for filename in filenames:
file = open(filename, 'r')
for line in file:
# Removing any comment
if line.find('--') >= 0:
line = line[:line.find('--')]
# Removing any carriage return
lines += re.sub('\r', '', line)
for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+SEQUENCE\s+\(\s*SIZE\s*\(\s*\d+\s*\.\.\s*[0-9a-zA-Z-]+\s*\)\s*\)\s*OF\s+[a-zA-Z-]+\s*\{\s*\{\s*([0-9a-zA-Z-]+)\s*\}\s*\}', lines, re.MULTILINE):
ieofielist[m[0]] = m[1]
for m in re.findall(r'([a-zA-Z0-9-]+)\s*::=\s+E-RAB-IE-ContainerList\s*\{\s*\{\s*([a-zA-Z0-9-]+)\s*\}\s*\}', lines, re.MULTILINE):
ieofielist[m[0]] = m[1]
for i in re.findall(r'([a-zA-Z0-9-]+)\s+([A-Z0-9-]+)\s*::=\s*\{\s+([\,\|\{\}\t\n\.{3}\ \-a-zA-Z0-9]+)\s+}\n', lines, re.MULTILINE):
ies = []
maxLength = 0
# TODO: handle extensions
if i[1].find('EXTENSION') >= 0:
continue
if fileprefix == "":
fileprefix = i[1][:i[1].find('-')].lower()
for j in re.findall(r'\s*\{\s*([a-zA-Z0-9-\ \t]+)\s*\}\s*[\|,]*', i[2], re.MULTILINE):
for k in re.findall(r'ID\s*([a-zA-Z0-9\-]+)\s*CRITICALITY\s*([a-zA-Z0-9\-]+)\s+[A-Z]+\s+([a-zA-Z0-9\-]+)\s*PRESENCE\s*([a-zA-Z0-9\-]+)', j, re.MULTILINE):
printDebug("Got new ie for message " + i[0] + ": " + str(k))
if len(k[2]) > maxLength:
maxLength = len(k[2])
ies.append(k)
if len(ies) > 0:
iesDefs[i[0]] = { "length": maxLength, "ies": ies }
else:
printWarning("Didn't find any information element for message: " + i[0])
if len(iesDefs) == 0:
printFail("No Information Element parsed, exiting")
sys.exit(0)
fileprefix_first_upper = fileprefix[0].upper() + fileprefix[1:]
f = open(outdir + fileprefix + '_ies_defs.h', 'w')
outputHeaderToFile(f, filename)
f.write("#include \"%s_common.h\"\n\n" % (fileprefix))
f.write("#ifndef %s_IES_DEFS_H_\n#define %s_IES_DEFS_H_\n\n" % (fileprefix.upper(), fileprefix.upper()))
f.write("/* Define the version of script used to generate this file */\n")
f.write("#define %s_SCRIPT_VERSION (%s)\n\n" % (fileprefix.upper(), re.sub('\.', '', version)))
for key in iesDefs:
if key not in ieofielist.values():
continue
for (i, j) in ieofielist.items():
if j == key:
break
f.write("typedef struct %sIEs_s {\n" % (re.sub('-', '_', i)))
f.write(" A_SEQUENCE_OF(struct %s_s) %s;\n" % (re.sub('IEs', '', re.sub('-', '_', ieofielist[i])), lowerFirstCamelWord(re.sub('IEs', '', re.sub('-', '_', ieofielist[i])))))
f.write("} %sIEs_t;\n\n" % (re.sub('-', '_', i)))
for key in iesDefs:
keyupperunderscore = re.sub('-', '_', key.upper())
keylowerunderscore = re.sub('-', '_', key.lower())
shift = 0
if len(iesDefs[key]["ies"]) == 0:
continue
# Presence mask
for ie in iesDefs[key]["ies"]:
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
if ie[3] == "optional" or ie[3] == "conditional":
f.write("#define {0:<{pad}} {1}\n".format("%s_%s_PRESENT" % (keyupperunderscore, ieupperunderscore), "(1 << %d)" % shift,
pad=iesDefs[key]["length"] + len(keyupperunderscore) + 9))
shift += 1
if (shift > 0):
f.write("\n")
f.write("typedef struct %s_s {\n" % (re.sub('-', '_', key)))
if (shift > 0):
f.write(" {0:<{pad}} {1};\n".format("uint16_t", "presenceMask", pad=iesDefs[key]["length"] + 2))
for ie in iesDefs[key]["ies"]:
ieunderscore = re.sub('-', '_', ie[2])
iename = re.sub('id-', '', ie[0])
ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
if ie[2] in ieofielist:
f.write(" %sIEs_t %s;" % (re.sub('-', '_', ie[2]), ienameunderscore))
else:
f.write(" {0:<{pad}} {1};".format("%s_t" % ieunderscore, ienameunderscore, pad=iesDefs[key]["length"] + 2))
if ie[3] == "optional":
f.write(" ///< Optional field")
elif ie[3] == "conditional":
f.write(" ///< Conditional field")
f.write("\n")
f.write("} %s_t;\n\n" % (re.sub('-', '_', key)))
f.write("typedef struct %s_message_s {\n" % (fileprefix))
f.write(" %s_ProcedureCode_t procedureCode;\n" % (fileprefix_first_upper))
f.write(" %s_Criticality_t criticality;\n" % (fileprefix_first_upper))
f.write(" uint8_t direction;\n")
f.write(" union {\n")
messageList = iesDefs.keys()
messageList.sort()
for message in messageList:
if message in ieofielist.values():
continue
if len(iesDefs[message]["ies"]) == 0:
continue
f.write(" %s_t %s;\n" % (re.sub('-', '_', message), lowerFirstCamelWord(re.sub('-', '_', message))))
f.write(" } msg;\n")
f.write("} %s_message;\n\n" % (fileprefix))
for key in iesDefs:
if key in ieofielist.values():
continue
structName = re.sub('ies', '', key)
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
keylowerunderscore = re.sub('-', '_', key.lower())
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
f.write("/** \\brief Decode function for %s ies.\n" % (key))
if len(iesDefs[key]["ies"]) != 0:
f.write(" * \\param %s Pointer to ASN1 structure in which data will be stored\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
f.write(" **/\n")
f.write("int %s_decode_%s(\n" % (fileprefix, keylowerunderscore))
if len(iesDefs[key]["ies"]) != 0:
f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" ANY_t *any_p);\n\n")
if len(iesDefs[key]["ies"]) == 0:
continue
f.write("/** \\brief Encode function for %s ies.\n" % (key))
f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" **/\n")
f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
f.write(" %s_t *%s);\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
for key in iesDefs:
if key not in ieofielist.values():
continue
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
f.write("/** \\brief Encode function for %s ies.\n" % (key))
f.write(" * \\param %s Pointer to the ASN1 structure.\n" % (firstlower))
f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" **/\n")
f.write("int %s_encode_%s(\n" % (fileprefix, firstlower.lower()))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstlower))
f.write(" %sIEs_t *%sIEs);\n\n" % (asn1cStruct, firstlower))
f.write("/** \\brief Decode function for %s ies.\n" % (key))
f.write(" * \\param any_p Pointer to the ANY value to decode.\n")
f.write(" * \\param callback Callback function called when any_p is successfully decoded.\n")
f.write(" **/\n")
f.write("int %s_decode_%s(\n" % (fileprefix, firstlower.lower()))
f.write(" %sIEs_t *%sIEs,\n" % (asn1cStruct, firstlower))
f.write(" %s_t *%s);\n\n" % (asn1cStruct, lowerFirstCamelWord(asn1cStruct)))
for key in iesDefs:
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
if key in ieofielist.values():
f.write("/** \\brief Display %s encapsulated IE using XER encoding.\n" % (asn1cStruct))
f.write(" * \\param %s Pointer to the IES structure.\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" * \\param file File descriptor to write output.\n")
f.write(" **/\n")
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('item', 'list', firstlower.lower())))
f.write(" asn_app_consume_bytes_f *cb,\n")
f.write(" void *app_key,\n")
f.write(" %sIEs_t *%sIEs);\n\n" % (re.sub('item', 'list', asn1cStruct), firstlower))
else:
f.write("/** \\brief Display %s message using XER encoding.\n" % (asn1cStruct))
f.write(" * \\param message_p Pointer to root message.\n")
f.write(" * \\param file File descriptor to write output.\n")
f.write(" **/\n")
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, firstlower.lower()))
f.write(" asn_app_consume_bytes_f *cb,\n")
f.write(" void *app_key,\n")
f.write(" %s_message *message_p);\n\n" % (fileprefix))
f.write("int %s_xer__print2sp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
f.write("int %s_xer__print2fp(const void *buffer, size_t size, void *app_key);\n\n" % (fileprefix.lower()))
f.write("extern size_t %s_string_total_size;\n\n" % (fileprefix.lower()))
f.write("#endif /* %s_IES_DEFS_H_ */\n\n" % (fileprefix.upper()))
#Generate Decode functions
f = open(outdir + fileprefix + '_decoder.c', 'w')
outputHeaderToFile(f, filename)
f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
for key in iesDefs:
if key in ieofielist.values():
continue
structName = re.sub('ies', '', key)
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
asn1cStruct = asn1cStruct[:-1]
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
ielistname = re.sub('UE', 'ue', asn1cStruct)
ielistnamefirstlower = ielistname[:1].lower() + ielistname[1:]
asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
keyName = re.sub('-', '_', key)
keyupperunderscore = keyName.upper()
firstlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
iesaccess = ""
if key not in ieofielist.values():
iesaccess = "%s_ies." % (firstlower)
f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
if len(iesDefs[key]["ies"]) != 0:
f.write(" %s_t *%s,\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" ANY_t *any_p) {\n\n")
f.write(" %s_t %s;\n %s_t *%s_p = &%s;\n" % (asn1cStruct, asn1cStructfirstlower, asn1cStruct, asn1cStructfirstlower, asn1cStructfirstlower))
f.write(" int i, decoded = 0;\n")
if len(iesDefs[key]["ies"]) != 0:
f.write(" int tempDecoded = 0;\n")
f.write(" assert(any_p != NULL);\n")
if len(iesDefs[key]["ies"]) != 0:
f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" %s_DEBUG(\"Decoding message %s (%%s:%%d)\\n\", __FILE__, __LINE__);\n\n" % (fileprefix.upper(), re.sub('-', '_', keyName)))
f.write(" ANY_to_type_aper(any_p, &asn_DEF_%s, (void**)&%s_p);\n\n" % (asn1cStruct, asn1cStructfirstlower))
f.write(" for (i = 0; i < %s_p->%slist.count; i++) {\n" % (asn1cStructfirstlower, iesaccess))
f.write(" %s_IE_t *ie_p;\n" % (fileprefix[0].upper() + fileprefix[1:]))
f.write(" ie_p = %s_p->%slist.array[i];\n" % (asn1cStructfirstlower, iesaccess))
f.write(" switch(ie_p->id) {\n")
for ie in iesDefs[key]["ies"]:
iename = re.sub('id-', '', ie[0])
ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
ienameunderscorefirstlower = lowerFirstCamelWord(ienameunderscore)
ietypesubst = re.sub('-', '', ie[2])
ietypeunderscore = re.sub('-', '_', ie[2])
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
if ie[3] == "optional":
f.write(" /* Optional field */\n")
elif ie[3] == "conditional":
f.write(" /* Conditional field */\n")
f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" {\n")
f.write(" %s_t *%s_p = NULL;\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
if ie[3] != "mandatory":
f.write(" %s->presenceMask |= %s_%s_PRESENT;\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(ietypesubst)))
f.write(" %s_ERROR(\"Decoding of IE %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore))
f.write(" if (%s_p)\n" % (lowerFirstCamelWord(ietypesubst)))
f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" decoded += tempDecoded;\n")
f.write(" if (asn1_xer_print)\n")
f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
if ie[2] in ieofielist.keys():
f.write(" if (%s_decode_%s(&%s->%s, %s_p) < 0) {\n" % (fileprefix, ietypeunderscore.lower(), lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" %s_ERROR(\"Decoding of encapsulated IE %s failed\\n\");\n" % (fileprefix.upper(), lowerFirstCamelWord(ietypesubst)))
f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" }\n")
else:
f.write(" memcpy(&%s->%s, %s_p, sizeof(%s_t));\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienameunderscore, lowerFirstCamelWord(ietypesubst), ietypeunderscore))
#f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (ietypeunderscore, lowerFirstCamelWord(ietypesubst)))
f.write(" } break;\n")
f.write(" default:\n")
f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" }\n")
f.write(" return decoded;\n")
f.write("}\n\n")
for key in iesDefs:
if key not in ieofielist.values():
continue
keyname = re.sub('IEs', '', re.sub('Item', 'List', key))
f.write("int %s_decode_%s(\n" % (fileprefix, re.sub('-', '_', keyname).lower()))
f.write(" %sIEs_t *%sIEs,\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', keyname), lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" int i, decoded = 0;\n")
f.write(" int tempDecoded = 0;\n\n")
f.write(" assert(%s != NULL);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))));
f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))));
f.write(" for (i = 0; i < %s->list.count; i++) {\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" %s_IE_t *ie_p = %s->list.array[i];\n" % (fileprefix[0].upper() + fileprefix[1:], lowerFirstCamelWord(re.sub('-', '_', keyname))))
f.write(" switch (ie_p->id) {\n")
for ie in iesDefs[key]["ies"]:
iename = re.sub('id-', '', ie[0])
ienameunderscore = lowerFirstCamelWord(re.sub('-', '_', iename))
f.write(" case %s_ProtocolIE_ID_%s:\n" % (fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" {\n")
f.write(" %s_t *%s_p = NULL;\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" tempDecoded = ANY_to_type_aper(&ie_p->value, &asn_DEF_%s, (void**)&%s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" if (tempDecoded < 0 || %s_p == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" %s_ERROR(\"Decoding of IE %s for message %s failed\\n\");\n" % (fileprefix.upper(), ienameunderscore, re.sub('-', '_', keyname)))
f.write(" if (%s_p)\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
#f.write(" free(%s_p);\n" % (lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" ASN_STRUCT_FREE(asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" decoded += tempDecoded;\n")
f.write(" if (asn1_xer_print)\n")
f.write(" xer_fprint(stdout, &asn_DEF_%s, %s_p);\n" % (re.sub('-', '_', ie[2]), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" ASN_SEQUENCE_ADD(&%sIEs->%s, %s_p);\n" % (lowerFirstCamelWord(re.sub('-', '_', keyname)),
re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key))), lowerFirstCamelWord(re.sub('-', '', ie[2]))))
f.write(" } break;\n")
f.write(" default:\n")
f.write(" %s_ERROR(\"Unknown protocol IE id (%%d) for message %s\\n\", (int)ie_p->id);\n" % (fileprefix.upper(), re.sub('-', '_', structName.lower())))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" }\n")
f.write(" return decoded;\n")
f.write("}\n\n")
#Generate IES Encode functions
f = open(outdir + fileprefix + '_encoder.c', 'w')
outputHeaderToFile(f,filename)
f.write("#include \"%s_common.h\"\n" % (fileprefix))
f.write("#include \"%s_ies_defs.h\"\n\n" % (fileprefix))
for key in iesDefs:
if key in ieofielist.values():
continue
structName = re.sub('ies', '', key)
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', key))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
if asn1cStruct.rfind('_') == len(asn1cStruct) - 1:
asn1cStruct = asn1cStruct[:-1]
asn1cStructfirstlower = asn1cStruct[:1].lower() + asn1cStruct[1:]
firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
iesaccess = ""
if key not in ieofielist.values():
iesaccess = "%s_ies." % (firstwordlower)
keyName = re.sub('-', '_', key)
keyupperunderscore = keyName.upper()
# No IE to encode...
if len(iesDefs[key]["ies"]) == 0:
continue
f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', structName.lower())))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
f.write(" %s_t *%s) {\n\n" % (re.sub('-', '_', key), lowerFirstCamelWord(re.sub('-', '_', key))))
f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
f.write(" assert(%s != NULL);\n" % (firstwordlower));
f.write(" assert(%s != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', key))));
for ie in iesDefs[key]["ies"]:
iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
ienameunderscore = re.sub('-', '_', iename)
ienamefirstwordlower = lowerFirstCamelWord(iename)
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
ietypeunderscore = re.sub('-', '_', ie[2])
if ie[3] != "mandatory":
if ie[3] == "optional":
f.write(" /* Optional field */\n")
elif ie[3] == "conditional":
f.write(" /* Conditional field */\n")
f.write(" if (%s->presenceMask & %s_%s_PRESENT) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), keyupperunderscore, ieupperunderscore))
#f.write(" == %s_%s_PRESENT) {\n" % (keyupperunderscore, ieupperunderscore))
f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n" % (firstwordlower, iesaccess))
f.write(" }\n\n")
else:
if ie[2] in ieofielist.keys():
f.write(" %s_t %s;\n\n" % (ietypeunderscore, ienamefirstwordlower))
f.write(" memset(&%s, 0, sizeof(%s_t));\n" % (ienamefirstwordlower, ietypeunderscore))
f.write("\n")
f.write(" if (%s_encode_%s(&%s, &%s->%s) < 0) return -1;\n" % (fileprefix, ietypeunderscore.lower(), ienamefirstwordlower, lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
if ie[2] in ieofielist.keys():
f.write(" &%s)) == NULL) {\n" % (ienamefirstwordlower))
else:
f.write(" &%s->%s)) == NULL) {\n" % (lowerFirstCamelWord(re.sub('-', '_', key)), ienamefirstwordlower))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" ASN_SEQUENCE_ADD(&%s->%slist, ie);\n\n" % (firstwordlower, iesaccess))
if ie[2] in ieofielist.keys():
f.write(" /* Free any dynamic allocation that is no more used */\n")
f.write(" ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_%s, &%s);\n\n" % (ietypeunderscore, ienamefirstwordlower))
f.write(" return 0;\n")
f.write("}\n\n")
for (key, value) in iesDefs.items():
if key not in ieofielist.values():
continue
ie = value["ies"][0]
ietypeunderscore = re.sub('-', '_', ie[2])
asn1cStruct = re.sub('-', '_', re.sub('IEs', '', re.sub('-IEs', '', key)))
asn1cStruct = re.sub('Item', 'List', asn1cStruct)
firstwordlower = re.sub('Item', 'List', re.sub('enb', 'eNB', lowerFirstCamelWord(asn1cStruct)))
for (i, j) in ieofielist.items():
if j == key:
break
f.write("int %s_encode_%s(\n" % (fileprefix, re.sub('-', '_', i).lower()))
f.write(" %s_t *%s,\n" % (asn1cStruct, firstwordlower))
f.write(" %sIEs_t *%sIEs) {\n\n" % (re.sub('-', '_', i), lowerFirstCamelWord(re.sub('-', '_', i))))
f.write(" int i;\n")
f.write(" %s_IE_t *ie;\n\n" % (fileprefix_first_upper))
f.write(" assert(%s != NULL);\n" % (firstwordlower));
f.write(" assert(%sIEs != NULL);\n\n" % (lowerFirstCamelWord(re.sub('-', '_', i))));
f.write(" for (i = 0; i < %sIEs->%s.count; i++) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" if ((ie = %s_new_ie(%s_ProtocolIE_ID_%s,\n" % (fileprefix, fileprefix_first_upper, re.sub('-', '_', ie[0])))
f.write(" %s_Criticality_%s,\n" % (fileprefix_first_upper, ie[1]))
f.write(" &asn_DEF_%s,\n" % (ietypeunderscore))
f.write(" %sIEs->%s.array[i])) == NULL) {\n" % (firstwordlower, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" return -1;\n")
f.write(" }\n")
f.write(" ASN_SEQUENCE_ADD(&%s->list, ie);\n" % (firstwordlower))
f.write(" }\n")
f.write(" return 0;\n")
f.write("}\n\n")
#Generate xer print functions
f = open(outdir + fileprefix + '_xer_print.c', 'w')
outputHeaderToFile(f, filename)
f.write("#include <stdlib.h>\n")
f.write("#include <stdio.h>\n\n")
f.write("#include <asn_application.h>\n#include <asn_internal.h>\n\n")
f.write("#include \"%s_common.h\"\n#include \"%s_ies_defs.h\"\n\n" % (fileprefix, fileprefix))
f.write("size_t %s_string_total_size = 0;\n\n" % (fileprefix.lower()))
f.write("""int
%s_xer__print2fp(const void *buffer, size_t size, void *app_key) {
FILE *stream = (FILE *)app_key;
if(fwrite(buffer, 1, size, stream) != size)
return -1;
return 0;
}
""" % (fileprefix.lower()))
f.write("""int %s_xer__print2sp(const void *buffer, size_t size, void *app_key) {
char *string = (char *)app_key;
/* Copy buffer to the formatted string */
memcpy(&string[%s_string_total_size], buffer, size);
%s_string_total_size += size;
return 0;
}
""" % (fileprefix.lower(), fileprefix.lower(), fileprefix.lower()))
f.write("""static asn_enc_rval_t
xer_encode_local(asn_TYPE_descriptor_t *td, void *sptr,
asn_app_consume_bytes_f *cb, void *app_key, int indent) {
asn_enc_rval_t er, tmper;
const char *mname;
size_t mlen;
int xcan = 2;
if(!td || !sptr) goto cb_failed;
mname = td->xml_tag;
mlen = strlen(mname);
_i_ASN_TEXT_INDENT(0, indent);
_ASN_CALLBACK3("<", 1, mname, mlen, ">", 1);
tmper = td->xer_encoder(td, sptr, indent + 1, XER_F_BASIC, cb, app_key);
if(tmper.encoded == -1) return tmper;
_ASN_CALLBACK3("</", 2, mname, mlen, ">\\n", xcan);
er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
_ASN_ENCODED_OK(er);
cb_failed:
_ASN_ENCODE_FAILED;
}
""")
for (key, value) in iesDefs.items():
keyName = re.sub('-', '_', key)
keyupperunderscore = keyName.upper()
iesStructName = lowerFirstCamelWord(re.sub('-', '_', key))
ie = value["ies"][0]
ietypeunderscore = re.sub('-', '_', ie[2])
if key in ieofielist.values():
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('item', 'list', re.sub('-', '_', key).lower()))))
else:
f.write("asn_enc_rval_t %s_xer_print_%s(\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', key).lower())))
#f.write(" FILE *file,\n")
f.write(" asn_app_consume_bytes_f *cb,\n")
f.write(" void *app_key,\n")
if key in ieofielist.values():
iesStructName = lowerFirstCamelWord(re.sub('Item', 'List', re.sub('-', '_', key)))
f.write(" %sIEs_t *%s) {\n\n" % (re.sub('IEs', '', re.sub('Item', 'List', re.sub('-', '_', key))), iesStructName))
f.write(" int i;\n")
f.write(" asn_enc_rval_t er;\n")
else:
f.write(" %s_message *message_p)\n{\n" % (fileprefix))
f.write(" %s_t *%s;\n" % (re.sub('-', '_', key), iesStructName))
f.write(" asn_enc_rval_t er;\n")
#f.write(" void *app_key = (void *)file;\n")
#f.write(" asn_app_consume_bytes_f *cb = %s_xer__print2fp;\n\n" % (fileprefix.lower()))
f.write(" %s = &message_p->msg.%s;\n\n" % (iesStructName, iesStructName))
if key in ieofielist.values():
# Increase indentation level
f.write(" for (i = 0; i < %s->%s.count; i++) {\n" % (iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
#f.write(" xer_fprint(file, &asn_DEF_%s, %s->%s.array[i]);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" er = xer_encode(&asn_DEF_%s, %s->%s.array[i], XER_F_BASIC, cb, app_key);\n" % (ietypeunderscore, iesStructName, re.sub('IEs', '', lowerFirstCamelWord(re.sub('-', '_', key)))))
f.write(" }\n")
else:
f.write(" cb(\"<%s-PDU>\\n\", %d, app_key);\n" % (key, len("<%s-PDU>\n" % (key))))
f.write(" xer_encode_local(&asn_DEF_%s_Criticality, &message_p->criticality, cb, app_key, 1);\n" % fileprefix_first_upper)
f.write(" xer_encode_local(&asn_DEF_%s_ProcedureCode, &message_p->procedureCode, cb, app_key, 1);\n" % fileprefix_first_upper)
f.write(" cb(\" <%s>\\n\", %d, app_key);\n" % (key, len(" <%s>\n" % (key))))
for ie in iesDefs[key]["ies"]:
iename = re.sub('-', '_', re.sub('id-', '', ie[0]))
ienameunderscore = re.sub('-', '_', iename)
ienamefirstwordlower = lowerFirstCamelWord(iename)
ietypeunderscore = re.sub('-', '_', ie[2])
ieupperunderscore = re.sub('-', '_', re.sub('id-', '', ie[0])).upper()
if ie[3] != "mandatory":
if ie[3] == "optional":
f.write(" /* Optional field */\n")
elif ie[3] == "conditional":
f.write(" /* Conditional field */\n")
f.write(" if (%s->presenceMask & %s_%s_PRESENT)\n " % (iesStructName, keyupperunderscore, ieupperunderscore))
# Is it an encapsulated IE ?
if ie[2] in ieofielist.keys():
f.write(" %s_xer_print_%s(cb, app_key, &%s->%s);\n" % (fileprefix, re.sub('ies', '', re.sub('-', '_', ie[2]).lower()), iesStructName, ienamefirstwordlower))
else:
f.write(" xer_encode_local(&asn_DEF_%s, &%s->%s, cb, app_key, 2);\n" % (ietypeunderscore, iesStructName, ienamefirstwordlower))
f.write(" cb(\" </%s>\\n\", %d, app_key);\n" % (key, len(" </%s>\n" % (key))))
f.write(" cb(\"</%s-PDU>\\n\", %d, app_key);\n" % (key, len("</%s-PDU>\n" % (key))))
f.write(" _ASN_ENCODED_OK(er);\n")
#if key not in ieofielist.values():
#f.write("cb_failed:\n")
#f.write(" return er;\n")
f.write("}\n\n")
+733
View File
@@ -0,0 +1,733 @@
/*
* 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 m2ap_MCE.c
* \brief m2ap tasks for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "intertask_interface.h"
#include "m2ap_MCE.h"
#include "m2ap_MCE_defs.h"
#include "m2ap_MCE_management_procedures.h"
#include "m2ap_MCE_handler.h"
#include "m2ap_MCE_generate_messages.h"
#include "m2ap_common.h"
#include "m2ap_MCE_interface_management.h"
#include "m2ap_ids.h"
#include "m2ap_timers.h"
#include "queue.h"
#include "assertions.h"
#include "conversions.h"
struct m2ap_mce_map;
struct m2ap_MCE_data_s;
m2ap_setup_req_t *m2ap_mce_data_from_enb;
RB_PROTOTYPE(m2ap_mce_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
static
void m2ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
static
void m2ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
static
void m2ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
static
void m2ap_MCE_handle_register_MCE(instance_t instance,
m2ap_register_mce_req_t *m2ap_register_MCE);
static
void m2ap_MCE_register_MCE(m2ap_MCE_instance_t *instance_p,
net_ip_address_t *target_MCE_ip_addr,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t mce_port_for_M2C,
int multi_sd);
//static
//void m2ap_MCE_handle_handover_req(instance_t instance,
// m2ap_handover_req_t *m2ap_handover_req);
//
//static
//void m2ap_MCE_handle_handover_req_ack(instance_t instance,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//static
//void m2ap_MCE_ue_context_release(instance_t instance,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
static
void m2ap_MCE_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
int result;
DevAssert(sctp_data_ind != NULL);
m2ap_MCE_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
static
void m2ap_MCE_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
DevAssert(sctp_new_association_resp != NULL);
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
LOG_W(M2AP, "Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
sctp_new_association_resp->sctp_state,
instance,
sctp_new_association_resp->ulp_cnx_id);
if (sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN)
//proto_agent_stop(instance);
//f1ap_handle_setup_message(instance, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
return; // exit -1 for debugging
}
// go to an init func
m2ap_mce_data_from_enb = (m2ap_setup_req_t *)calloc(1, sizeof(m2ap_setup_req_t));
// save the assoc id
m2ap_mce_data_from_enb->assoc_id = sctp_new_association_resp->assoc_id;
m2ap_mce_data_from_enb->sctp_in_streams = sctp_new_association_resp->in_streams;
m2ap_mce_data_from_enb->sctp_out_streams = sctp_new_association_resp->out_streams;
// m2ap_MCE_instance_t *instance_p;
// m2ap_MCE_data_t *m2ap_mce_data_p;
// DevAssert(sctp_new_association_resp != NULL);
// printf("m2ap_MCE_handle_sctp_association_resp at 1\n");
// dump_mce_trees_m2();
// instance_p = instance;//m2ap_MCE_get_instance(instance);
// DevAssert(instance_p != NULL);
// /* if the assoc_id is already known, it is certainly because an IND was received
// * before. In this case, just update streams and return
// */
// if (sctp_new_association_resp->assoc_id != -1) {
// m2ap_mce_data_p = m2ap_get_MCE(instance_p, sctp_new_association_resp->assoc_id,
// sctp_new_association_resp->ulp_cnx_id);
// if (m2ap_mce_data_p != NULL) {
// /* some sanity check - to be refined at some point */
// if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
// M2AP_ERROR("m2ap_mce_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
// abort();
// }
// m2ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams;
// m2ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams;
// return;
// }
// }
// m2ap_mce_data_p = m2ap_get_MCE(instance_p, -1,
// sctp_new_association_resp->ulp_cnx_id);
// DevAssert(m2ap_mce_data_p != NULL);
// printf("m2ap_MCE_handle_sctp_association_resp at 2\n");
// dump_mce_trees_m2();
// if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
// M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
// sctp_new_association_resp->sctp_state,
// instance,
// sctp_new_association_resp->ulp_cnx_id);
// //m2ap_eNB_handle_m2_setup_message(instance_p, m2ap_mce_data_p,
// //sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
// return;
// }
// printf("m2ap_MCE_handle_sctp_association_resp at 3\n");
// dump_mce_trees_m2();
// /* Update parameters */
// m2ap_mce_data_p->assoc_id = sctp_new_association_resp->assoc_id;
// m2ap_mce_data_p->in_streams = sctp_new_association_resp->in_streams;
// m2ap_mce_data_p->out_streams = sctp_new_association_resp->out_streams;
// printf("m2ap_MCE_handle_sctp_association_resp at 4\n");
// dump_mce_trees_m2();
// /* Prepare new m2 Setup Request */
// //m2ap_MCE_generate_m2_setup_request(instance_p, m2ap_mce_data_p);
}
static
void m2ap_MCE_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
//m2ap_MCE_instance_t *instance_p;
//m2ap_MCE_data_t *m2ap_mce_data_p;
//printf("m2ap_MCE_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
///dump_mce_trees_m2();
///DevAssert(sctp_new_association_ind != NULL);
///instance_p = instance;//m2ap_MCE_get_instance(instance);
///DevAssert(instance_p != NULL);
///m2ap_mce_data_p = m2ap_get_MCE(instance_p, sctp_new_association_ind->assoc_id, -1);
///if (m2ap_mce_data_p != NULL) abort();
///// DevAssert(m2ap_enb_data_p != NULL);
///if (m2ap_mce_data_p == NULL) {
/// /* Create new MCE descriptor */
/// m2ap_mce_data_p = calloc(1, sizeof(*m2ap_mce_data_p));
/// DevAssert(m2ap_mce_data_p != NULL);
/// m2ap_mce_data_p->cnx_id = m2ap_MCE_fetch_add_global_cnx_id();
/// m2ap_mce_data_p->m2ap_MCE_instance = instance_p;
/// /* Insert the new descriptor in list of known MCE
/// * but not yet associated.
/// */
/// RB_INSERT(m2ap_mce_map, &instance_p->m2ap_mce_head, m2ap_mce_data_p);
/// m2ap_mce_data_p->state = M2AP_MCE_STATE_CONNECTED;
/// instance_p->m2_target_mce_nb++;
/// if (instance_p->m2_target_mce_pending_nb > 0) {
/// instance_p->m2_target_mce_pending_nb--;
/// }
///} else {
/// M2AP_WARN("m2ap_mce_data_p already exists\n");
///}
///printf("m2ap_MCE_handle_sctp_association_ind at 2\n");
///dump_mce_trees_m2();
////* Update parameters */
///m2ap_mce_data_p->assoc_id = sctp_new_association_ind->assoc_id;
///m2ap_mce_data_p->in_streams = sctp_new_association_ind->in_streams;
///m2ap_mce_data_p->out_streams = sctp_new_association_ind->out_streams;
///printf("m2ap_MCE_handle_sctp_association_ind at 3\n");
///dump_mce_trees_m2();
}
int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t mce_port_for_M2C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = mce_port_for_M2C;
sctp_init->ppid = M2AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
static void m2ap_MCE_register_MCE(m2ap_MCE_instance_t *instance_p,
net_ip_address_t *target_MCE_ip_address,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t mce_port_for_M2C,
int multi_sd) {
MessageDef *message = NULL;
sctp_new_association_req_multi_t *sctp_new_association_req = NULL;
m2ap_MCE_data_t *m2ap_mce_data = NULL;
DevAssert(instance_p != NULL);
DevAssert(target_MCE_ip_address != NULL);
message = itti_alloc_new_message(TASK_M2AP_MCE, SCTP_NEW_ASSOCIATION_REQ_MULTI);
sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
sctp_new_association_req->port = mce_port_for_M2C;
sctp_new_association_req->ppid = M2AP_SCTP_PPID;
sctp_new_association_req->in_streams = in_streams;
sctp_new_association_req->out_streams = out_streams;
sctp_new_association_req->multi_sd = multi_sd;
memcpy(&sctp_new_association_req->remote_address,
target_MCE_ip_address,
sizeof(*target_MCE_ip_address));
memcpy(&sctp_new_association_req->local_address,
local_ip_addr,
sizeof(*local_ip_addr));
/* Create new MCE descriptor */
m2ap_mce_data = calloc(1, sizeof(*m2ap_mce_data));
DevAssert(m2ap_mce_data != NULL);
m2ap_mce_data->cnx_id = m2ap_MCE_fetch_add_global_cnx_id();
sctp_new_association_req->ulp_cnx_id = m2ap_mce_data->cnx_id;
m2ap_mce_data->assoc_id = -1;
m2ap_mce_data->m2ap_MCE_instance = instance_p;
/* Insert the new descriptor in list of known MCE
* but not yet associated.
*/
RB_INSERT(m2ap_mce_map, &instance_p->m2ap_mce_head, m2ap_mce_data);
m2ap_mce_data->state = M2AP_MCE_STATE_WAITING;
instance_p->m2_target_mce_nb ++;
instance_p->m2_target_mce_pending_nb ++;
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message);
}
static
void m2ap_MCE_handle_register_MCE(instance_t instance,
m2ap_register_mce_req_t *m2ap_register_MCE) {
m2ap_MCE_instance_t *new_instance;
DevAssert(m2ap_register_MCE != NULL);
/* Look if the provided instance already exists */
new_instance = m2ap_MCE_get_instance(instance);
if (new_instance != NULL) {
/* Checks if it is a retry on the same MCE */
DevCheck(new_instance->MCE_id == m2ap_register_MCE->MCE_id, new_instance->MCE_id, m2ap_register_MCE->MCE_id, 0);
DevCheck(new_instance->cell_type == m2ap_register_MCE->cell_type, new_instance->cell_type, m2ap_register_MCE->cell_type, 0);
DevCheck(new_instance->tac == m2ap_register_MCE->tac, new_instance->tac, m2ap_register_MCE->tac, 0);
DevCheck(new_instance->mcc == m2ap_register_MCE->mcc, new_instance->mcc, m2ap_register_MCE->mcc, 0);
DevCheck(new_instance->mnc == m2ap_register_MCE->mnc, new_instance->mnc, m2ap_register_MCE->mnc, 0);
M2AP_WARN("MCE[%d] already registered\n", instance);
} else {
new_instance = calloc(1, sizeof(m2ap_MCE_instance_t));
DevAssert(new_instance != NULL);
RB_INIT(&new_instance->m2ap_mce_head);
/* Copy usefull parameters */
new_instance->instance = instance;
new_instance->MCE_name = m2ap_register_MCE->MCE_name;
new_instance->MCE_id = m2ap_register_MCE->MCE_id;
new_instance->cell_type = m2ap_register_MCE->cell_type;
new_instance->tac = m2ap_register_MCE->tac;
new_instance->mcc = m2ap_register_MCE->mcc;
new_instance->mnc = m2ap_register_MCE->mnc;
new_instance->mnc_digit_length = m2ap_register_MCE->mnc_digit_length;
new_instance->num_cc = m2ap_register_MCE->num_cc;
m2ap_id_manager_init(&new_instance->id_manager);
m2ap_timers_init(&new_instance->timers,
m2ap_register_MCE->t_reloc_prep,
m2ap_register_MCE->tm2_reloc_overall);
for (int i = 0; i< m2ap_register_MCE->num_cc; i++) {
new_instance->eutra_band[i] = m2ap_register_MCE->eutra_band[i];
new_instance->downlink_frequency[i] = m2ap_register_MCE->downlink_frequency[i];
new_instance->uplink_frequency_offset[i] = m2ap_register_MCE->uplink_frequency_offset[i];
new_instance->Nid_cell[i] = m2ap_register_MCE->Nid_cell[i];
new_instance->N_RB_DL[i] = m2ap_register_MCE->N_RB_DL[i];
new_instance->frame_type[i] = m2ap_register_MCE->frame_type[i];
new_instance->fdd_earfcn_DL[i] = m2ap_register_MCE->fdd_earfcn_DL[i];
new_instance->fdd_earfcn_UL[i] = m2ap_register_MCE->fdd_earfcn_UL[i];
}
DevCheck(m2ap_register_MCE->nb_m2 <= M2AP_MAX_NB_MCE_IP_ADDRESS,
M2AP_MAX_NB_MCE_IP_ADDRESS, m2ap_register_MCE->nb_m2, 0);
memcpy(new_instance->target_mce_m2_ip_address,
m2ap_register_MCE->target_mce_m2_ip_address,
m2ap_register_MCE->nb_m2 * sizeof(net_ip_address_t));
new_instance->nb_m2 = m2ap_register_MCE->nb_m2;
new_instance->mce_m2_ip_address = m2ap_register_MCE->mce_m2_ip_address;
new_instance->sctp_in_streams = m2ap_register_MCE->sctp_in_streams;
new_instance->sctp_out_streams = m2ap_register_MCE->sctp_out_streams;
new_instance->mce_port_for_M2C = m2ap_register_MCE->mce_port_for_M2C;
/* Add the new instance to the list of MCE (meaningfull in virtual mode) */
m2ap_MCE_insert_new_instance(new_instance);
M2AP_INFO("Registered new MCE[%d] and %s MCE id %u\n",
instance,
m2ap_register_MCE->cell_type == CELL_MACRO_ENB ? "macro" : "home",
m2ap_register_MCE->MCE_id);
/* initiate the SCTP listener */
if (m2ap_MCE_init_sctp(new_instance,&m2ap_register_MCE->mce_m2_ip_address,m2ap_register_MCE->mce_port_for_M2C) < 0 ) {
M2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
return;
}
M2AP_INFO("MCE[%d] MCE id %u acting as a listner (server)\n",
instance, m2ap_register_MCE->MCE_id);
}
}
static
void m2ap_MCE_handle_sctp_init_msg_multi_cnf(
instance_t instance_id,
sctp_init_msg_multi_cnf_t *m) {
m2ap_MCE_instance_t *instance;
int index;
DevAssert(m != NULL);
instance = m2ap_MCE_get_instance(instance_id);
DevAssert(instance != NULL);
instance->multi_sd = m->multi_sd;
/* Exit if CNF message reports failure.
* Failure means multi_sd < 0.
*/
if (instance->multi_sd < 0) {
M2AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n");
DevAssert(instance->multi_sd >= 0);
}
/* Trying to connect to the provided list of MCE ip address */
for (index = 0; index < instance->nb_m2; index++) {
M2AP_INFO("MCE[%d] MCE id %u acting as an initiator (client)\n",
instance_id, instance->MCE_id);
m2ap_MCE_register_MCE(instance,
&instance->target_mce_m2_ip_address[index],
&instance->mce_m2_ip_address,
instance->sctp_in_streams,
instance->sctp_out_streams,
instance->mce_port_for_M2C,
instance->multi_sd);
}
}
//static
//void m2ap_MCE_handle_handover_req(instance_t instance,
// m2ap_handover_req_t *m2ap_handover_req)
//{
// m2ap_MCE_instance_t *instance_p;
// m2ap_MCE_data_t *target;
// m2ap_id_manager *id_manager;
// int ue_id;
//
// int target_pci = m2ap_handover_req->target_physCellId;
//
// instance_p = m2ap_MCE_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m2ap_is_MCE_pci_in_list(target_pci);
// DevAssert(target != NULL);
//
// /* allocate m2ap ID */
// id_manager = &instance_p->id_manager;
// ue_id = m2ap_allocate_new_id(id_manager);
// if (ue_id == -1) {
// M2AP_ERROR("could not allocate a new M2AP UE ID\n");
// /* TODO: cancel handover: send (to be defined) message to RRC */
// exit(1);
// }
// /* id_source is ue_id, id_target is unknown yet */
// m2ap_set_ids(id_manager, ue_id, m2ap_handover_req->rnti, ue_id, -1);
// m2ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE);
// m2ap_set_reloc_prep_timer(id_manager, ue_id,
// m2ap_timer_get_tti(&instance_p->timers));
// m2ap_id_set_target(id_manager, ue_id, target);
//
// m2ap_MCE_generate_m2_handover_request(instance_p, target, m2ap_handover_req, ue_id);
//}
//static
//void m2ap_MCE_handle_handover_req_ack(instance_t instance,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack)
//{
// /* TODO: remove this hack (the goal is to find the correct
// * eNodeB structure for the other end) - we need a proper way for RRC
// * and M2AP to identify eNodeBs
// * RRC knows about mod_id and M2AP knows about MCE_id (MCE_ID in
// * the configuration file)
// * as far as I understand.. CROUX
// */
// m2ap_MCE_instance_t *instance_p;
// m2ap_MCE_data_t *target;
// int source_assoc_id = m2ap_handover_req_ack->source_assoc_id;
// int ue_id;
// int id_source;
// int id_target;
//
// instance_p = m2ap_MCE_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m2ap_get_MCE(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// /* rnti is a new information, save it */
// ue_id = m2ap_handover_req_ack->m2_id_target;
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
// m2ap_set_ids(&instance_p->id_manager, ue_id, m2ap_handover_req_ack->rnti, id_source, id_target);
//
// m2ap_MCE_generate_m2_handover_request_ack(instance_p, target, m2ap_handover_req_ack);
//}
//
//static
//void m2ap_MCE_ue_context_release(instance_t instance,
// m2ap_ue_context_release_t *m2ap_ue_context_release)
//{
// m2ap_MCE_instance_t *instance_p;
// m2ap_MCE_data_t *target;
// int source_assoc_id = m2ap_ue_context_release->source_assoc_id;
// int ue_id;
// instance_p = m2ap_MCE_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m2ap_get_MCE(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// m2ap_MCE_generate_m2_ue_context_release(instance_p, target, m2ap_ue_context_release);
//
// /* free the M2AP UE ID */
// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
// exit(1);
// }
// m2ap_release_id(&instance_p->id_manager, ue_id);
//}
void MCE_task_send_sctp_init_req(instance_t enb_id, m2ap_mce_sctp_req_t * m2ap_mce_sctp_req) {
// 1. get the itti msg, and retrive the enb_id from the message
// 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
// 3. creat an itti message to init
LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n");
MessageDef *message_p = NULL;
message_p = itti_alloc_new_message (TASK_M2AP_MCE, SCTP_INIT_MSG);
// if( m2ap_mce_sctp_req == NULL ){
// message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER;
// message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
// message_p->ittiMsg.sctp_init.ipv4 = 1;
// message_p->ittiMsg.sctp_init.ipv6 = 0;
// message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
// //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
// message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7");
// /*
// * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
// * * * * Disable it for now.
// */
// message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
// message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
// }else{
message_p->ittiMsg.sctp_init.port = m2ap_mce_sctp_req->mce_port_for_M2C;
message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
message_p->ittiMsg.sctp_init.ipv4 = 1;
message_p->ittiMsg.sctp_init.ipv6 = 0;
message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
//message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(m2ap_mce_sctp_req->mce_m2_ip_address.ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
// }
itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
}
void *m2ap_MCE_task(void *arg) {
MessageDef *received_msg = NULL;
int result;
M2AP_DEBUG("Starting M2AP layer\n");
m2ap_MCE_prepare_internal_data();
itti_mark_task_ready(TASK_M2AP_MCE);
//MCE_task_send_sctp_init_req(0,NULL);
while (1) {
itti_receive_msg(TASK_M2AP_MCE, &received_msg);
switch (ITTI_MSG_ID(received_msg)) {
case MESSAGE_TEST:
LOG_W(M2AP,"MCE Received MESSAGE_TEST Message\n");
//MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_MCE, MESSAGE_TEST);
//itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p);
break;
case TERMINATE_MESSAGE:
M2AP_WARN(" *** Exiting M2AP thread\n");
itti_exit_task();
break;
case M2AP_MCE_SCTP_REQ:
MCE_task_send_sctp_init_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MCE_SCTP_REQ(received_msg));
break;
case M2AP_SUBFRAME_PROCESS:
m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
break;
case M2AP_REGISTER_MCE_REQ:
LOG_I(M2AP,"MCE Received M2AP_REGISTER_MCE_REQ Message\n");
m2ap_MCE_handle_register_MCE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_REGISTER_MCE_REQ(received_msg));
break;
case M2AP_SETUP_RESP:
LOG_I(M2AP,"MCE Received M2AP_SETUP_RESP Message\n");
MCE_send_M2_SETUP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_SETUP_RESP(received_msg));
break;
case M2AP_SETUP_FAILURE:
LOG_I(M2AP,"MCE Received M2AP_SETUP_FAILURE Message\n");
MCE_send_M2_SETUP_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_SETUP_FAILURE(received_msg));
break;
case M2AP_MBMS_SCHEDULING_INFORMATION:
LOG_I(M2AP,"MCE Received M2AP_MBMS_SCHEDULING_INFORMATION Message\n");
MCE_send_MBMS_SCHEDULING_INFORMATION(0,
&M2AP_MBMS_SCHEDULING_INFORMATION(received_msg));
break;
case M2AP_MBMS_SESSION_START_REQ:
LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_START_REQ Message\n");
MCE_send_MBMS_SESSION_START_REQUEST(0,
&M2AP_MBMS_SESSION_START_REQ(received_msg));
break;
case M2AP_MBMS_SESSION_STOP_REQ:
LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_STOP_REQ Message\n");
MCE_send_MBMS_SESSION_STOP_REQUEST(0,
&M2AP_MBMS_SESSION_STOP_REQ(received_msg));
break;
case M2AP_MBMS_SESSION_UPDATE_REQ:
LOG_I(M2AP,"MCE Received M2AP_MBMS_SESSION_UPDATE_REQ Message\n");
MCE_send_MBMS_SESSION_UPDATE_REQUEST(0,
&M2AP_MBMS_SESSION_UPDATE_REQ(received_msg));
break;
case M2AP_RESET:
LOG_I(M2AP,"MCE Received M2AP_RESET Message\n");
MCE_send_RESET(0,
&M2AP_RESET(received_msg));
break;
case M2AP_ENB_CONFIGURATION_UPDATE_ACK:
LOG_I(M2AP,"MCE Received M2AP_ENB_CONFIGURATION_UPDATE_ACK Message\n");
MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(0,
&M2AP_ENB_CONFIGURATION_UPDATE_ACK(received_msg));
break;
case M2AP_ENB_CONFIGURATION_UPDATE_FAILURE:
LOG_I(M2AP,"MCE Received M2AP_ENB_CONFIGURATION_UPDATE_FAILURE Message\n");
MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(0,
&M2AP_ENB_CONFIGURATION_UPDATE_FAILURE(received_msg));
break;
case M2AP_MCE_CONFIGURATION_UPDATE:
LOG_I(M2AP,"MCE Received M2AP_MCE_CONFIGURATION_UPDATE Message\n");
//MCE_send_MCE_CONFIGURATION_UPDATE(0,
//&M2AP_MCE_CONFIGURATION_UPDATE(received_msg));
break;
// case M2AP_HANDOVER_REQ:
// m2ap_MCE_handle_handover_req(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M2AP_HANDOVER_REQ(received_msg));
// break;
//
// case M2AP_HANDOVER_REQ_ACK:
// m2ap_MCE_handle_handover_req_ack(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M2AP_HANDOVER_REQ_ACK(received_msg));
// break;
//
// case M2AP_UE_CONTEXT_RELEASE:
// m2ap_MCE_ue_context_release(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M2AP_UE_CONTEXT_RELEASE(received_msg));
// break;
//
case SCTP_INIT_MSG_MULTI_CNF:
LOG_D(M2AP,"MCE Received SCTP_INIT_MSG_MULTI_CNF Message\n");
m2ap_MCE_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
break;
case SCTP_NEW_ASSOCIATION_RESP:
LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION_RESP Message\n");
m2ap_MCE_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp);
break;
case SCTP_NEW_ASSOCIATION_IND:
LOG_D(M2AP,"MCE Received SCTP_NEW_ASSOCIATION Message\n");
m2ap_MCE_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_ind);
break;
case SCTP_DATA_IND:
LOG_D(M2AP,"MCE Received SCTP_DATA_IND Message\n");
m2ap_MCE_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_data_ind);
break;
default:
M2AP_ERROR("MCE Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
received_msg = NULL;
}
return NULL;
}
#include "common/config/config_userapi.h"
int is_m2ap_MCE_enabled(void)
{
static volatile int config_loaded = 0;
static volatile int enabled = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if (pthread_mutex_lock(&mutex)) goto mutex_error;
if (config_loaded) {
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
}
char *enable_m2 = NULL;
paramdef_t p[] = {
{ "enable_mce_m2", "yes/no", 0, strptr:&enable_m2, defstrval:"", TYPE_STRING, 0 }
};
/* TODO: do it per module - we check only first MCE */
config_get(p, sizeof(p)/sizeof(paramdef_t), "MCEs.[0]");
if (enable_m2 != NULL && strcmp(enable_m2, "yes") == 0)
enabled = 1;
config_loaded = 1;
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
mutex_error:
LOG_E(M2AP, "mutex error\n");
exit(1);
}
+55
View File
@@ -0,0 +1,55 @@
/*
* 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 m2ap_MCE.h
* \brief m2ap tasks for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include <stdint.h>
/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M2AP_MCE_H_
#define M2AP_MCE_H_
#include "m2ap_MCE_defs.h"
int m2ap_MCE_init_sctp (m2ap_MCE_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M2C);
void *m2ap_MCE_task(void *arg);
int is_m2ap_MCE_enabled(void);
#endif /* M2AP_MCE_H_ */
/**
* @}
*/
+210
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.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 m2ap_MCE_defs.h
* \brief m2ap struct definitions for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "queue.h"
#include "tree.h"
#include "sctp_eNB_defs.h"
#include "m2ap_ids.h" //looks X2AP specific for HO
#include "m2ap_timers.h"
#ifndef M2AP_MCE_DEFS_H_
#define M2AP_MCE_DEFS_H_
#define M2AP_MCE_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
M2AP_MCE_STATE_DISCONNECTED = 0x0,
/* State waiting for m2 Setup response message if the target MCE accepts or
* M2 Setup failure if rejects the MCE.
*/
M2AP_MCE_STATE_WAITING = 0x1,
/* The MCE is successfully connected to another MCE. */
M2AP_MCE_STATE_CONNECTED = 0x2,
/* M2AP is ready, and the MCE is successfully connected to another MCE. */
M2AP_MCE_STATE_READY = 0x3,
M2AP_MCE_STATE_OVERLOAD = 0x4,
M2AP_MCE_STATE_RESETTING = 0x5,
/* Max number of states available */
M2AP_MCE_STATE_MAX,
} m2ap_MCE_state_t;
/* Served PLMN identity element */
/*struct plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
STAILQ_ENTRY(plmn_identity_s) next;
};*/
/* Served group id element */
/*struct served_group_id_s {
uint16_t mce_group_id;
STAILQ_ENTRY(served_group_id_s) next;
};*/
/* Served enn code for a particular MCE */
/*struct mce_code_s {
uint8_t mce_code;
STAILQ_ENTRY(mce_code_s) next;
};*/
struct m2ap_MCE_instance_s;
/* This structure describes association of a MCE to another MCE */
typedef struct m2ap_MCE_data_s {
/* MCE descriptors tree, ordered by sctp assoc id */
RB_ENTRY(m2ap_MCE_data_s) entry;
/* This is the optional name provided by the MME */
char *MCE_name;
/* target MCE ID */
uint32_t MCE_id;
/* Current MCE load information (if any). */
//m2ap_load_state_t overload_state;
/* Current MCE->MCE M2AP association state */
m2ap_MCE_state_t state;
/* Next usable stream for UE signalling */
int32_t nextstream;
/* Number of input/ouput streams */
uint16_t in_streams;
uint16_t out_streams;
/* Connexion id used between SCTP/M2AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Nid cells */
uint32_t Nid_cell[MAX_NUM_CCs];
int num_cc;
/* Only meaningfull in virtual mode */
struct m2ap_MCE_instance_s *m2ap_MCE_instance;
} m2ap_MCE_data_t;
typedef struct m2ap_MCE_instance_s {
/* used in simulation to store multiple MCE instances*/
STAILQ_ENTRY(m2ap_MCE_instance_s) m2ap_MCE_entries;
/* Number of target MCEs requested by MCE (tree size) */
uint32_t m2_target_mce_nb;
/* Number of target MCEs for which association is pending */
uint32_t m2_target_mce_pending_nb;
/* Number of target MCE successfully associated to MCE */
uint32_t m2_target_mce_associated_nb;
/* Tree of M2AP MCE associations ordered by association ID */
RB_HEAD(m2ap_mce_map, m2ap_MCE_data_s) m2ap_mce_head;
/* Tree of UE ordered by MCE_ue_m2ap_id's */
// RB_HEAD(m2ap_ue_map, m2ap_MCE_ue_context_s) m2ap_ue_head;
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
instance_t instance;
/* Displayable name of MCE */
char *MCE_name;
/* Unique MCE_id to identify the MCE within EPC.
* In our case the MCE is a macro MCE so the id will be 20 bits long.
* For Home MCE id, this field should be 28 bits long.
*/
uint32_t MCE_id;
/* The type of the cell */
cell_type_t cell_type;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* CC params */
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_MCE_IP_ADDRESS];
uint8_t nb_m2;
net_ip_address_t mce_m2_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t mce_port_for_M2C;
int multi_sd;
m2ap_id_manager id_manager;
m2ap_timers_t timers;
} m2ap_MCE_instance_t;
typedef struct {
/* List of served MCEs
* Only used for virtual mode
*/
STAILQ_HEAD(m2ap_MCE_instances_head_s, m2ap_MCE_instance_s) m2ap_MCE_instances_head;
/* Nb of registered MCEs */
uint8_t nb_registered_MCEs;
/* Generate a unique connexion id used between M2AP and SCTP */
uint16_t global_cnx_id;
} m2ap_MCE_internal_data_t;
int m2ap_MCE_compare_assoc_id(struct m2ap_MCE_data_s *p1, struct m2ap_MCE_data_s *p2);
/* Generate the tree management functions */
struct m2ap_MCE_map;
struct m2ap_MCE_data_s;
RB_PROTOTYPE(m2ap_MCE_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
#endif /* M2AP_MCE_DEFS_H_ */
+804
View File
@@ -0,0 +1,804 @@
/*
* 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 m2ap_MCE_generate_messages.c
* \brief m2ap procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include "intertask_interface.h"
//#include "M2AP_LastVisitedCell-Item.h"
#include "m2ap_common.h"
#include "m2ap_MCE.h"
#include "m2ap_MCE_generate_messages.h"
#include "m2ap_encoder.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
#include "m2ap_itti_messaging.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
int m2ap_MCE_generate_m2_setup_request(
m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p)
{
M2AP_M2AP_PDU_t pdu;
M2AP_M2SetupRequest_t *out;
M2AP_M2SetupRequest_Ies_t *ie;
//M2AP_PLMN_Identity_t *plmn;
//ServedCells__Member *servedCellMember;
//M2AP_GU_Group_ID_t *gu;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(m2ap_MCE_data_p != NULL);
m2ap_MCE_data_p->state = M2AP_MCE_STATE_WAITING;
/* Prepare the M2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup;
pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest;
out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest;
/* mandatory */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GlobalMCE_ID;
//MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GlobalMCE_ID.pLMN_Identity);
//ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID;
//MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id,
// &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID);
//M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id,
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_ServedCells;
//{
// for (int i = 0; i<instance_p->num_cc; i++){
// servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
// {
// servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0,
// &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
// INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
// plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
// ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
// }
// if (instance_p->frame_type[i] == FDD) {
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
// switch (instance_p->N_RB_DL[i]) {
// case 6:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// break;
// case 15:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// break;
// case 25:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// break;
// case 50:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// break;
// case 75:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// break;
// case 100:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// break;
// default:
// AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
// break;
// }
// }
// else {
// AssertFatal(0,"M2Setuprequest not supported for TDD!");
// }
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
// }
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupRequest_IEs__value_PR_GUGroupIDList;
//{
// gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &gu->pLMN_Identity);
// //@TODO: consider to update this value
// INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
M2AP_ERROR("Failed to encode M2 setup request\n");
return -1;
}
//MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0);
return ret;
}
int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p)
{
M2AP_M2AP_PDU_t pdu;
M2AP_M2SetupResponse_t *out;
M2AP_M2SetupResponse_Ies_t *ie;
//M2AP_PLMN_Identity_t *plmn;
//ServedCells__Member *servedCellMember;
//M2AP_GU_Group_ID_t *gu;
uint8_t *buffer;
uint32_t len;
int ret = 0;
DevAssert(instance_p != NULL);
DevAssert(m2ap_MCE_data_p != NULL);
/* Prepare the M2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse;
out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse;
/* mandatory */
ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GlobalMCE_ID;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalMCE_ID;
//MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GlobalMCE_ID.pLMN_Identity);
//ie->value.choice.GlobalMCE_ID.MCE_ID.present = M2AP_MCE_ID_PR_macro_MCE_ID;
//MACRO_MCE_ID_TO_BIT_STRING(instance_p->MCE_id,
// &ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID);
//M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->MCE_id,
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[0],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[1],
// ie->value.choice.GlobalMCE_ID.MCE_ID.choice.macro_MCE_ID.buf[2]);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells;
//{
// for (int i = 0; i<instance_p->num_cc; i++){
// servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
// {
// servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(instance_p->MCE_id,0,
// &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
// INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
// plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
// ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
// }
// if (instance_p->frame_type[i] == FDD) {
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
// switch (instance_p->N_RB_DL[i]) {
// case 6:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// break;
// case 15:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// break;
// case 25:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// break;
// case 50:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// break;
// case 75:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// break;
// case 100:
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// break;
// default:
// AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
// break;
// }
// }
// else {
// AssertFatal(0,"M2Setupresponse not supported for TDD!");
// }
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
// }
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* mandatory */
ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
//ie->criticality = M2AP_Criticality_reject;
//ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList;
//{
// gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &gu->pLMN_Identity);
// //@TODO: consider to update this value
// INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
M2AP_ERROR("Failed to encode M2 setup response\n");
return -1;
}
m2ap_MCE_data_p->state = M2AP_MCE_STATE_READY;
//MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id);
m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 0);
return ret;
}
int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
uint32_t assoc_id,
M2AP_Cause_PR cause_type,
long cause_value,
long time_to_wait)
{
M2AP_M2AP_PDU_t pdu;
M2AP_M2SetupFailure_t *out;
M2AP_M2SetupFailure_Ies_t *ie;
uint8_t *buffer;
uint32_t len;
int ret = 0;
/* Prepare the M2AP message to encode */
memset(&pdu, 0, sizeof(pdu));
pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject;
pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure;
out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
/* mandatory */
ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_Cause;
//ie->criticality = M2AP_Criticality_ignore;
//ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause;
//m2ap_MCE_set_cause (&ie->value.choice.Cause, cause_type, cause_value);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* optional: consider to handle this later */
ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
//ie->id = M2AP_ProtocolIE_ID_id_TimeToWait;
//ie->criticality = M2AP_Criticality_ignore;
//ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait;
//if (time_to_wait > -1) {
// ie->value.choice.TimeToWait = time_to_wait;
//}
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
M2AP_ERROR("Failed to encode M2 setup failure\n");
return -1;
}
//MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE,
// MSC_M2AP_TARGET_MCE, NULL, 0,
// "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u",
// assoc_id, cause_type, cause_value);
m2ap_MCE_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0);
return ret;
}
int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value)
{
DevAssert (cause_p != NULL);
cause_p->present = cause_type;
switch (cause_type) {
case M2AP_Cause_PR_radioNetwork:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_transport:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_protocol:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_misc:
cause_p->choice.misc = cause_value;
break;
default:
return -1;
}
return 0;
}
//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequest_t *out;
// M2AP_HandoverRequest_IEs_t *ie;
// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs;
// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest;
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause;
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.ECGI.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(m2ap_MCE_data_p->MCE_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity);
// //@TODO: consider to update these values
// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID);
// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation;
// //@TODO: consider to update this value
// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id;
//
// KMCE_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
//
// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc;
// }
// else {
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
// }
//
// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
//
// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
//
// //@TODO: update with proper UEAMPR
// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
// {
// for (int i=0;i<m2ap_handover_req->nb_e_rabs_tobesetup;i++) {
// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t));
// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item;
// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item;
// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item;
// {
// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length/8);
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.length%8;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf =
// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
// m2ap_handover_req->e_rabs_tobesetup[i].MCE_addr.buffer,
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs);
// }
// }
//
// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
// //@TODO: consider to update this value
// {
// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t));
// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
// MACRO_MCE_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small;
// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2;
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover request\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequestAcknowledge_t *out;
// M2AP_HandoverRequestAcknowledge_IEs_t *ie;
// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs;
// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// ue_id = m2ap_handover_req_ack->m2_id_target;
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List;
//
// {
// for (int i=0;i<m2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) {
// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t));
// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item;
// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item;
// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
// {
// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
// }
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargetMCEtoSource_MCETransparentContainer;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargetMCEtoSource_MCETransparentContainer;
//
// OCTET_STRING_fromBuf(&ie->value.choice.TargetMCEtoSource_MCETransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover response\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_UEContextRelease_t *out;
// M2AP_UEContextRelease_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
// exit(1);
// }
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP ue context relase message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease;
// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease;
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 UE Context Release\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverCancel_t *out;
// M2AP_HandoverCancel_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_MCE_data_p != NULL);
//
// ue_id = m2_ue_id;
// id_source = ue_id;
// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id);
//
// /* Prepare the M2AP handover cancel message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel;
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional */
// if (id_target != -1) {
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_MCE_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
// }
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause;
// switch (cause) {
// case M2AP_T_RELOC_PREP_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_trelocprep_expiry;
// break;
// case M2AP_TX2_RELOC_OVERALL_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_tx2relocoverall_expiry;
// break;
// default:
// /* we can't come here */
// M2AP_ERROR("unhandled cancel cause\n");
// exit(1);
// }
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_MCE_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 Handover Cancel\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_MCE, MSC_M2AP_TARGET_MCE, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_MCE_data_p->assoc_id);
//
// m2ap_MCE_itti_send_sctp_data_req(instance_p->instance, m2ap_MCE_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
@@ -0,0 +1,63 @@
/*
* 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 m2ap_MCE_generate_messages.h
* \brief m2ap procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_GENERATE_MESSAGES_H_
#define M2AP_MCE_GENERATE_MESSAGES_H_
#include "m2ap_MCE_defs.h"
#include "m2ap_common.h"
int m2ap_MCE_generate_m2_setup_request(m2ap_MCE_instance_t *instance_p,
m2ap_MCE_data_t *m2ap_MCE_data_p);
int m2ap_MCE_generate_m2_setup_response(m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p);
int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
uint32_t assoc_id,
M2AP_Cause_PR cause_type,
long cause_value,
long time_to_wait);
int m2ap_MCE_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value);
//int m2ap_MCE_generate_m2_handover_request (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id);
//
//int m2ap_MCE_generate_m2_handover_request_ack (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//int m2ap_MCE_generate_m2_ue_context_release (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
//int m2ap_MCE_generate_m2_handover_cancel (m2ap_MCE_instance_t *instance_p, m2ap_MCE_data_t *m2ap_MCE_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause);
#endif /* M2AP_MCE_GENERATE_MESSAGES_H_ */
+123
View File
@@ -0,0 +1,123 @@
/*
* 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 m2ap_MCE_handler.c
* \brief m2ap handler procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "m2ap_common.h"
#include "m2ap_MCE_defs.h"
#include "m2ap_MCE_handler.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
//#include "m2ap_MCE_management_procedures.h"
#include "m2ap_MCE_generate_messages.h"
#include "m2ap_MCE_interface_management.h"
//#include "m2ap_eNB_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m2ap_message_decoded_callback m2ap_MCE_messages_callback[][3] = {
{ 0, MCE_handle_MBMS_SESSION_START_RESPONSE, 0 }, /* MBMSSessionStart */
{ 0, MCE_handle_MBMS_SESSION_STOP_RESPONSE, 0 }, /* MBMSSessionStop */
{ 0, MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE, 0 }, /* MBMSSchedulingInformation */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ MCE_handle_M2_SETUP_REQUEST, 0, 0 }, /* M2 Setup */
{ 0, 0, 0 }, /* eNBConfigurationUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ 0, 0, 0 }, /* privateMessage */
{ 0, 0, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MBMSServiceCounting */
{ 0, 0, 0 }, /* MBMSServiceCountingResultReport */
{ 0, 0, 0 } /* MBMSOverloadNotification */
};
static char *m2ap_direction2String(int m2ap_dir) {
static char *m2ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m2ap_direction_String[m2ap_dir]);
}
int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M2AP_M2AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (m2ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M2AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_MCE_messages_callback) / (3 * sizeof(
m2ap_MCE_message_decoded_callback))
|| (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m2ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M2AP, "Calling handler with instance %d\n",instance);
ret = (*m2ap_MCE_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return ret;
}
+43
View File
@@ -0,0 +1,43 @@
/*
* 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 m2ap_handler.h
* \brief m2ap handler procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_HANDLERS_H_
#define M2AP_MCE_HANDLERS_H_
#include "m2ap_MCE_defs.h"
//void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
int m2ap_MCE_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
//int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
//const uint8_t * const data, const uint32_t data_length);
#endif /* M2AP_MCE_HANDLERS_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,196 @@
/*
* 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 m2ap_MCE_interface_management.h
* \brief m2ap interface management for MCE
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M2AP_MCE_INTERFACE_MANAGEMENT_H_
#define M2AP_MCE_INTERFACE_MANAGEMENT_H_
/*
* MBMS Session start
*/
int MCE_send_MBMS_SESSION_START_REQUEST(instance_t instance/*,
uint32_t assoc_id*/,m2ap_session_start_req_t* m2ap_session_start_req);
int MCE_handle_MBMS_SESSION_START_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MBMS_SESSION_START_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* MBMS Session stop
*/
int MCE_send_MBMS_SESSION_STOP_REQUEST(instance_t instance,
m2ap_session_stop_req_t* m2ap_session_stop_req);
int MCE_handle_MBMS_SESSION_STOP_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* MBMS Scheduling Information
*/
int MCE_send_MBMS_SCHEDULING_INFORMATION(instance_t instance,
/*uint32_t assoc_id,*/ m2ap_mbms_scheduling_information_t * m2ap_mbms_scheduling_information );
int MCE_handle_MBMS_SCHEDULING_INFORMATION_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Reset
*/
int MCE_send_RESET(instance_t instance, m2ap_reset_t * m2ap_reset);
int MCE_handle_RESET_ACKKNOWLEDGE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_RESET(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_RESET_ACKNOWLEDGE(instance_t instance, M2AP_ResetAcknowledge_t *ResetAcknowledge);
/*
* M2AP Setup
*/
int MCE_handle_M2_SETUP_REQUEST(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_M2_SETUP_RESPONSE(instance_t instance,/*uint32_t assoc_id,*/ m2ap_setup_resp_t *m2ap_setup_resp);
int MCE_send_M2_SETUP_FAILURE(instance_t instance, /*uint32_t assoc_id*/ m2ap_setup_failure_t * m2ap_setup_failure);
/*
* MCE Configuration Update
*/
int MCE_send_MCE_CONFIGURATION_UPDATE(instance_t instance, module_id_t du_mod_idP);
int MCE_handle_MCE_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* ENB Configuration Update
*/
int MCE_handle_ENB_CONFIGURATION_UPDATE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_ENB_CONFIGURATION_UPDATE_FAILURE(instance_t instance,
m2ap_enb_configuration_update_failure_t *m2ap_enb_configuration_update_failure);
int MCE_send_ENB_CONFIGURATION_UPDATE_ACKNOWLEDGE(instance_t instance,
m2ap_enb_configuration_update_ack_t *m2ap_enb_configuration_update_ack);
/*
* Error Indication
*/
int MCE_handle_ERROR_INDICATION(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_send_ERROR_INDICATION(instance_t instance, M2AP_ErrorIndication_t *ErrorIndication);
/*
* Session Update Request
*/
int MCE_send_MBMS_SESSION_UPDATE_REQUEST(instance_t instance, m2ap_mbms_session_update_req_t * m2ap_mbms_session_update_req);
int MCE_handle_MBMS_SESSION_UPDATE_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MBMS_SESSION_UPDATE_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Service Counting Request
*/
int MCE_send_MBMS_SERVICE_COUNTING_REQUEST(instance_t instance, module_id_t du_mod_idP);
int MCE_handle_MBMS_SERVICE_COUNTING_RESPONSE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
int MCE_handle_MBMS_SESSION_COUNTING_FAILURE(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Service Counting Results Report
*/
int MCE_handle_MBMS_SESSION_COUNTING_RESULTS_REPORT(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/*
* Overload Notification
*/
int MCE_handle_MBMS_OVERLOAD_NOTIFICATION(instance_t instance,
uint32_t assoc_id,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
#endif /* M2AP_MCE_INTERFACE_MANAGEMENT_H_ */
@@ -0,0 +1,257 @@
/*
* 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 m2ap_MCE_management_procedures.c
* \brief m2ap tasks for MCE
* \author Javier Morgade <javier.morade@ieee.org>
* \date 2018
* \version 1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "intertask_interface.h"
#include "assertions.h"
#include "conversions.h"
#include "m2ap_common.h"
#include "m2ap_MCE_defs.h"
#include "m2ap_MCE.h"
#define M2AP_DEBUG_LIST
#ifdef M2AP_DEBUG_LIST
# define M2AP_MCE_LIST_OUT(x, args...) M2AP_DEBUG("[MCE]%*s"x"\n", 4*indent, "", ##args)
#else
# define M2AP_MCE_LIST_OUT(x, args...)
#endif
static int indent = 0;
m2ap_MCE_internal_data_t m2ap_MCE_internal_data;
RB_GENERATE(m2ap_mce_map, m2ap_MCE_data_s, entry, m2ap_MCE_compare_assoc_id);
int m2ap_MCE_compare_assoc_id(
struct m2ap_MCE_data_s *p1, struct m2ap_MCE_data_s *p2)
{
if (p1->assoc_id == -1) {
if (p1->cnx_id < p2->cnx_id) {
return -1;
}
if (p1->cnx_id > p2->cnx_id) {
return 1;
}
} else {
if (p1->assoc_id < p2->assoc_id) {
return -1;
}
if (p1->assoc_id > p2->assoc_id) {
return 1;
}
}
/* Matching reference */
return 0;
}
uint16_t m2ap_MCE_fetch_add_global_cnx_id(void)
{
return ++m2ap_MCE_internal_data.global_cnx_id;
}
void m2ap_MCE_prepare_internal_data(void)
{
memset(&m2ap_MCE_internal_data, 0, sizeof(m2ap_MCE_internal_data));
STAILQ_INIT(&m2ap_MCE_internal_data.m2ap_MCE_instances_head);
}
void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p)
{
DevAssert(new_instance_p != NULL);
STAILQ_INSERT_TAIL(&m2ap_MCE_internal_data.m2ap_MCE_instances_head,
new_instance_p, m2ap_MCE_entries);
}
void dump_mce_tree_m2(m2ap_MCE_data_t *t)
{
if (t == NULL) return;
printf("-----------------------\n");
printf("MCE id %d %s\n", t->MCE_id, t->MCE_name);
printf("state %d\n", t->state);
printf("nextstream %d\n", t->nextstream);
printf("in_streams %d out_streams %d\n", t->in_streams, t->out_streams);
printf("cnx_id %d assoc_id %d\n", t->cnx_id, t->assoc_id);
dump_mce_tree_m2(t->entry.rbe_left);
dump_mce_tree_m2(t->entry.rbe_right);
}
void dump_mce_trees_m2(void)
{
m2ap_MCE_instance_t *zz;
STAILQ_FOREACH(zz, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
m2ap_MCE_entries) {
//printf("here comes the tree (instance %d):\n---------------------------------------------\n", zz->instance);
dump_mce_tree_m2(zz->m2ap_mce_head.rbh_root);
//printf("---------------------------------------------\n");
}
}
struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id)
{
struct m2ap_MCE_data_s temp;
struct m2ap_MCE_data_s *found;
//printf("m2ap_get_MCE at 1 (looking for assoc_id %d cnx_id %d)\n", assoc_id, cnx_id);
//dump_mce_trees_m2();
memset(&temp, 0, sizeof(struct m2ap_MCE_data_s));
temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id;
if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
m2ap_MCE_entries) {
found = RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp);
if (found != NULL) {
return found;
}
}
} else {
return RB_FIND(m2ap_mce_map, &instance_p->m2ap_mce_head, &temp);
}
return NULL;
}
m2ap_MCE_instance_t *m2ap_MCE_get_instance(instance_t instance)
{
m2ap_MCE_instance_t *temp = NULL;
STAILQ_FOREACH(temp, &m2ap_MCE_internal_data.m2ap_MCE_instances_head,
m2ap_MCE_entries) {
if (temp->instance == instance) {
/* Matching occurence */
return temp;
}
}
return NULL;
}
/// utility functions
void m2ap_dump_MCE (m2ap_MCE_data_t * MCE_ref);
void
m2ap_dump_MCE_list (void) {
m2ap_MCE_instance_t *inst = NULL;
struct m2ap_MCE_data_s *found = NULL;
struct m2ap_MCE_data_s temp;
memset(&temp, 0, sizeof(struct m2ap_MCE_data_s));
STAILQ_FOREACH (inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
found = RB_FIND(m2ap_mce_map, &inst->m2ap_mce_head, &temp);
m2ap_dump_MCE (found);
}
}
void m2ap_dump_MCE (m2ap_MCE_data_t * MCE_ref) {
if (MCE_ref == NULL) {
return;
}
M2AP_MCE_LIST_OUT ("");
M2AP_MCE_LIST_OUT ("MCE name: %s", MCE_ref->MCE_name == NULL ? "not present" : MCE_ref->MCE_name);
M2AP_MCE_LIST_OUT ("MCE STATE: %07x", MCE_ref->state);
M2AP_MCE_LIST_OUT ("MCE ID: %07x", MCE_ref->MCE_id);
indent++;
M2AP_MCE_LIST_OUT ("SCTP cnx id: %d", MCE_ref->cnx_id);
M2AP_MCE_LIST_OUT ("SCTP assoc id: %d", MCE_ref->assoc_id);
M2AP_MCE_LIST_OUT ("SCTP instreams: %d", MCE_ref->in_streams);
M2AP_MCE_LIST_OUT ("SCTP outstreams: %d", MCE_ref->out_streams);
indent--;
}
m2ap_MCE_data_t * m2ap_is_MCE_pci_in_list (const uint32_t pci)
{
m2ap_MCE_instance_t *inst;
struct m2ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) {
for (int i = 0; i<elm->num_cc; i++) {
if (elm->Nid_cell[i] == pci) {
return elm;
}
}
}
}
return NULL;
}
m2ap_MCE_data_t * m2ap_is_MCE_id_in_list (const uint32_t MCE_id)
{
m2ap_MCE_instance_t *inst;
struct m2ap_MCE_data_s *elm;
STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
RB_FOREACH(elm, m2ap_mce_map, &inst->m2ap_mce_head) {
if (elm->MCE_id == MCE_id)
return elm;
}
}
return NULL;
}
m2ap_MCE_data_t * m2ap_is_MCE_assoc_id_in_list (const uint32_t sctp_assoc_id)
{
m2ap_MCE_instance_t *inst;
struct m2ap_MCE_data_s *found;
struct m2ap_MCE_data_s temp;
temp.assoc_id = sctp_assoc_id;
temp.cnx_id = -1;
STAILQ_FOREACH(inst, &m2ap_MCE_internal_data.m2ap_MCE_instances_head, m2ap_MCE_entries) {
found = RB_FIND(m2ap_mce_map, &inst->m2ap_mce_head, &temp);
if (found != NULL){
if (found->assoc_id == sctp_assoc_id) {
return found;
}
}
}
return NULL;
}
@@ -0,0 +1,54 @@
/*
* 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 m2ap_eNB_management_procedures.h
* \brief m2ap tasks for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_MCE_MANAGEMENT_PROCEDURES_H_
#define M2AP_MCE_MANAGEMENT_PROCEDURES_H
void m2ap_MCE_prepare_internal_data(void);
void dump_trees_m2(void);
void m2ap_MCE_insert_new_instance(m2ap_MCE_instance_t *new_instance_p);
m2ap_MCE_instance_t *m2ap_MCE_get_instance(uint8_t mod_id);
uint16_t m2ap_MCE_fetch_add_global_cnx_id(void);
void m2ap_MCE_prepare_internal_data(void);
m2ap_MCE_data_t* m2ap_is_MCE_id_in_list(uint32_t MCE_id);
m2ap_MCE_data_t* m2ap_is_MCE_assoc_id_in_list(uint32_t sctp_assoc_id);
m2ap_MCE_data_t* m2ap_is_MCE_pci_in_list (const uint32_t pci);
struct m2ap_MCE_data_s *m2ap_get_MCE(m2ap_MCE_instance_t *instance_p,
int32_t assoc_id,
uint16_t cnx_id);
#endif /* M2AP_MCE_MANAGEMENT_PROCEDURES_H_ */
+124
View File
@@ -0,0 +1,124 @@
/*
* 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 m2ap_common.c
* \brief m2ap procedures for both eNB and MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "m2ap_common.h"
#include "M2AP_M2AP-PDU.h"
int asn_debug = 0;
int asn1_xer_print = 0;
#if defined(EMIT_ASN_DEBUG_EXTERN)
inline void ASN_DEBUG(const char *fmt, ...)
{
if (asn_debug) {
int adi = asn_debug_indent;
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "[ASN1]");
while(adi--) fprintf(stderr, " ");
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
va_end(ap);
}
}
#endif
ssize_t m2ap_generate_initiating_message(
uint8_t **buffer,
uint32_t *length,
M2AP_ProcedureCode_t procedureCode,
M2AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr)
{
M2AP_M2AP_PDU_t pdu;
ssize_t encoded;
memset(&pdu, 0, sizeof(M2AP_M2AP_PDU_t));
pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
pdu.choice.initiatingMessage.procedureCode = procedureCode;
pdu.choice.initiatingMessage.criticality = criticality;
ANY_fromType_aper((ANY_t *)&pdu.choice.initiatingMessage.value, td, sptr);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, (void *)&pdu);
}
/* We can safely free list of IE from sptr */
ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr);
if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M2AP_M2AP_PDU, 0, &pdu,
(void **)buffer)) < 0) {
return -1;
}
*length = encoded;
return encoded;
}
ssize_t m2ap_generate_unsuccessfull_outcome(
uint8_t **buffer,
uint32_t *length,
M2AP_ProcedureCode_t procedureCode,
M2AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr)
{
M2AP_M2AP_PDU_t pdu;
ssize_t encoded;
memset(&pdu, 0, sizeof(M2AP_M2AP_PDU_t));
pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
pdu.choice.successfulOutcome.procedureCode = procedureCode;
pdu.choice.successfulOutcome.criticality = criticality;
ANY_fromType_aper((ANY_t *)&pdu.choice.successfulOutcome.value, td, sptr);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, (void *)&pdu);
}
/* We can safely free list of IE from sptr */
ASN_STRUCT_FREE_CONTENTS_ONLY(*td, sptr);
if ((encoded = aper_encode_to_new_buffer(&asn_DEF_M2AP_M2AP_PDU, 0, &pdu,
(void **)buffer)) < 0) {
return -1;
}
*length = encoded;
return encoded;
}
void m2ap_handle_criticality(M2AP_Criticality_t criticality)
{
}
+173
View File
@@ -0,0 +1,173 @@
/*
* 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
*/
#if HAVE_CONFIG_H_
# include "config.h"
#endif
#include "M2AP_ProtocolIE-Field.h"
#include "M2AP_M2AP-PDU.h"
#include "M2AP_InitiatingMessage.h"
#include "M2AP_SuccessfulOutcome.h"
#include "M2AP_UnsuccessfulOutcome.h"
#include "M2AP_ProtocolIE-FieldPair.h"
#include "M2AP_ProtocolIE-ContainerPair.h"
#include "M2AP_ProtocolExtensionField.h"
#include "M2AP_ProtocolExtensionContainer.h"
#include "M2AP_PMCH-Configuration-Item.h"
#include "M2AP_asn_constant.h"
#include "intertask_interface.h"
#include "common/ran_context.h"
#ifndef M2AP_COMMON_H_
#define M2AP_COMMON_H_
/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
/* Checking version of ASN1C compiler */
#if (ASN1C_ENVIRONMENT_VERSION < 923)
# error "You are compiling m2ap with the wrong version of ASN1C"
#endif
#ifndef M2AP_PORT
# define M2AP_PORT 36423
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
extern int asn1_xer_print;
#if defined(ENB_MODE)
# include "common/utils/LOG/log.h"
# include "m2ap_default_values.h"
# define M2AP_INFO(x, args...) LOG_I(M2AP, x, ##args)
# define M2AP_ERROR(x, args...) LOG_E(M2AP, x, ##args)
# define M2AP_WARN(x, args...) LOG_W(M2AP, x, ##args)
# define M2AP_DEBUG(x, args...) LOG_D(M2AP, x, ##args)
#else
# define M2AP_INFO(x, args...) do { fprintf(stdout, "[M2AP][I]"x, ##args); } while(0)
# define M2AP_ERROR(x, args...) do { fprintf(stdout, "[M2AP][E]"x, ##args); } while(0)
# define M2AP_WARN(x, args...) do { fprintf(stdout, "[M2AP][W]"x, ##args); } while(0)
# define M2AP_DEBUG(x, args...) do { fprintf(stdout, "[M2AP][D]"x, ##args); } while(0)
#endif
#define M2AP_FIND_PROTOCOLIE_BY_ID(IE_TYPE, ie, container, IE_ID, mandatory) \
do {\
IE_TYPE **ptr; \
ie = NULL; \
for (ptr = container->protocolIEs.list.array; \
ptr < &container->protocolIEs.list.array[container->protocolIEs.list.count]; \
ptr++) { \
if((*ptr)->id == IE_ID) { \
ie = *ptr; \
break; \
} \
} \
if (mandatory) DevAssert(ie != NULL); \
} while(0)
/** \brief Function callback prototype.
**/
typedef int (*m2ap_message_decoded_callback)(
instance_t instance,
uint32_t assocId,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
typedef int (*m2ap_MCE_message_decoded_callback)(
instance_t instance,
uint32_t assocId,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
typedef int (*m2ap_eNB_message_decoded_callback)(
instance_t instance,
uint32_t assocId,
uint32_t stream,
M2AP_M2AP_PDU_t *pdu);
/** \brief Encode a successfull outcome message
\param buffer pointer to buffer in which data will be encoded
\param length pointer to the length of buffer
\param procedureCode Procedure code for the message
\param criticality Criticality of the message
\param td ASN1C type descriptor of the sptr
\param sptr Deferenced pointer to the structure to encode
@returns size in bytes encded on success or 0 on failure
**/
ssize_t m2ap_generate_successfull_outcome(
uint8_t **buffer,
uint32_t *length,
M2AP_ProcedureCode_t procedureCode,
M2AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr);
/** \brief Encode an initiating message
\param buffer pointer to buffer in which data will be encoded
\param length pointer to the length of buffer
\param procedureCode Procedure code for the message
\param criticality Criticality of the message
\param td ASN1C type descriptor of the sptr
\param sptr Deferenced pointer to the structure to encode
@returns size in bytes encded on success or 0 on failure
**/
ssize_t m2ap_generate_initiating_message(
uint8_t **buffer,
uint32_t *length,
M2AP_ProcedureCode_t procedureCode,
M2AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr);
/** \brief Encode an unsuccessfull outcome message
\param buffer pointer to buffer in which data will be encoded
\param length pointer to the length of buffer
\param procedureCode Procedure code for the message
\param criticality Criticality of the message
\param td ASN1C type descriptor of the sptr
\param sptr Deferenced pointer to the structure to encode
@returns size in bytes encded on success or 0 on failure
**/
ssize_t m2ap_generate_unsuccessfull_outcome(
uint8_t **buffer,
uint32_t *length,
M2AP_ProcedureCode_t procedureCode,
M2AP_Criticality_t criticality,
asn_TYPE_descriptor_t *td,
void *sptr);
/** \brief Handle criticality
\param criticality Criticality of the IE
@returns void
**/
void m2ap_handle_criticality(M2AP_Criticality_t criticality);
#endif /* M2AP_COMMON_H_ */
+194
View File
@@ -0,0 +1,194 @@
/*
* 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 m2ap_decoder.c
* \brief m2ap decoder procedures
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdio.h>
#include "assertions.h"
#include "intertask_interface.h"
#include "m2ap_common.h"
#include "m2ap_decoder.h"
static int m2ap_decode_initiating_message(M2AP_M2AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.initiatingMessage.procedureCode) {
case M2AP_ProcedureCode_id_sessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_sessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_m2Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
// case M2AP_ProcedureCode_id_handoverPreparation:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_initiating_message!\n");
// break;
//
// case M2AP_ProcedureCode_id_uEContextRelease:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_initiating_message!\n");
// break;
//
// case M2AP_ProcedureCode_id_handoverCancel:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_initiating_message!\n");
// break;
//
default:
M2AP_ERROR("Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
(int)pdu->choice.initiatingMessage.procedureCode);
return -1;
}
return 0;
}
static int m2ap_decode_successful_outcome(M2AP_M2AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.successfulOutcome.procedureCode) {
case M2AP_ProcedureCode_id_sessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_successfuloutcome_message!\n");
break;
case M2AP_ProcedureCode_id_sessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
break;
case M2AP_ProcedureCode_id_m2Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
break;
case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_succesfuloutcome_message!\n");
break;
// case M2AP_ProcedureCode_id_handoverPreparation:
// //asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
// M2AP_INFO("m2ap__decode_successfuloutcome_message!\n");
// break;
//
default:
M2AP_ERROR("Unknown procedure ID (%d) for successfull outcome message\n",
(int)pdu->choice.successfulOutcome.procedureCode);
return -1;
}
return 0;
}
static int m2ap_decode_unsuccessful_outcome(M2AP_M2AP_PDU_t *pdu)
{
DevAssert(pdu != NULL);
switch(pdu->choice.unsuccessfulOutcome.procedureCode) {
case M2AP_ProcedureCode_id_sessionStart:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_sessionStop:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_m2Setup:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
case M2AP_ProcedureCode_id_mbmsSchedulingInformation:
//asn_encode_to_new_buffer(NULL, ATS_CANONICAL_XER, &asn_DEF_M2AP_M2AP_PDU, pdu);
M2AP_INFO("m2ap__decode_initiating_message!\n");
break;
default:
M2AP_ERROR("Unknown procedure ID (%d) for unsuccessfull outcome message\n",
(int)pdu->choice.unsuccessfulOutcome.procedureCode);
return -1;
}
return 0;
}
int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
{
asn_dec_rval_t dec_ret;
DevAssert(buffer != NULL);
dec_ret = aper_decode(NULL,
&asn_DEF_M2AP_M2AP_PDU,
(void **)&pdu,
buffer,
length,
0,
0);
if (asn1_xer_print) {
xer_fprint(stdout, &asn_DEF_M2AP_M2AP_PDU, pdu);
}
if (dec_ret.code != RC_OK) {
M2AP_ERROR("Failed to decode pdu\n");
return -1;
}
switch(pdu->present) {
case M2AP_M2AP_PDU_PR_initiatingMessage:
return m2ap_decode_initiating_message(pdu);
case M2AP_M2AP_PDU_PR_successfulOutcome:
return m2ap_decode_successful_outcome(pdu);
case M2AP_M2AP_PDU_PR_unsuccessfulOutcome:
return m2ap_decode_unsuccessful_outcome(pdu);
default:
M2AP_DEBUG("Unknown presence (%d) or not implemented\n", (int)pdu->present);
break;
}
return -1;
}
+35
View File
@@ -0,0 +1,35 @@
/*
* 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 m2ap_decoder.h
* \brief m2ap decoder procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_DECODER_H_
#define M2AP_DECODER_H_
int m2ap_decode_pdu(M2AP_M2AP_PDU_t *pdu, const uint8_t *const buffer, uint32_t length)
__attribute__ ((warn_unused_result));
#endif /* M2AP_DECODER_H_ */
+47
View File
@@ -0,0 +1,47 @@
/*
* 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 m2ap_default_values.h
* \brief default values for m2ap procedures
* \author Javier Morgade
* \date 2019
* \version 0.1
* \company Vicomtech
* \email: javier.morgade@ieee.org
* \note
* \warning
*/
#ifndef M2AP_DEFAULT_VALUES_H_
#define M2AP_DEFAULT_VALUES_H_
#define ENB_TAC (1)
#define ENB_MCC (208)
#define ENB_MNC (92)
#define ENB_NAME "Eurecom ENB"
#define ENB_NAME_FORMAT (ENB_NAME" %u")
#define M2AP_PORT_NUMBER (36443)
#define M2AP_SCTP_PPID (43)
#endif /* M2AP_DEFAULT_VALUES_H_ */
+704
View File
@@ -0,0 +1,704 @@
/*
* 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 m2ap_eNB.c
* \brief m2ap tasks for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <arpa/inet.h>
#include "intertask_interface.h"
#include "m2ap_eNB.h"
#include "m2ap_eNB_defs.h"
#include "m2ap_eNB_management_procedures.h"
#include "m2ap_eNB_handler.h"
#include "m2ap_eNB_generate_messages.h"
#include "m2ap_common.h"
#include "m2ap_eNB_interface_management.h"
#include "m2ap_ids.h"
#include "m2ap_timers.h"
#include "queue.h"
#include "assertions.h"
#include "conversions.h"
struct m2ap_enb_map;
struct m2ap_eNB_data_s;
m2ap_setup_req_t * m2ap_enb_data_g;
RB_PROTOTYPE(m2ap_enb_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id);
static
void m2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind);
static
void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
static
void m2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind);
static
void m2ap_eNB_handle_register_eNB(instance_t instance,
m2ap_register_enb_req_t *m2ap_register_eNB);
static
void m2ap_eNB_register_eNB(m2ap_eNB_instance_t *instance_p,
net_ip_address_t *target_eNB_ip_addr,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t enb_port_for_M2C,
int multi_sd);
//static
//void m2ap_eNB_handle_handover_req(instance_t instance,
// m2ap_handover_req_t *m2ap_handover_req);
//
//static
//void m2ap_eNB_handle_handover_req_ack(instance_t instance,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//static
//void m2ap_eNB_ue_context_release(instance_t instance,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
static
void m2ap_eNB_handle_sctp_data_ind(instance_t instance, sctp_data_ind_t *sctp_data_ind) {
int result;
DevAssert(sctp_data_ind != NULL);
m2ap_eNB_handle_message(instance, sctp_data_ind->assoc_id, sctp_data_ind->stream,
sctp_data_ind->buffer, sctp_data_ind->buffer_length);
result = itti_free(TASK_UNKNOWN, sctp_data_ind->buffer);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
static
void m2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp) {
m2ap_eNB_instance_t *instance_p;
m2ap_eNB_data_t *m2ap_enb_data_p;
DevAssert(sctp_new_association_resp != NULL);
// printf("m2ap_eNB_handle_sctp_association_resp at 1\n");
// dump_trees_m2();
instance_p = m2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
/* if the assoc_id is already known, it is certainly because an IND was received
* before. In this case, just update streams and return
*/
if (sctp_new_association_resp->assoc_id != -1) {
m2ap_enb_data_p = m2ap_get_eNB(instance_p, sctp_new_association_resp->assoc_id,
sctp_new_association_resp->ulp_cnx_id);
if (m2ap_enb_data_p != NULL) {
/* some sanity check - to be refined at some point */
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
M2AP_ERROR("m2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n");
abort();
}
m2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
m2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
return;
}
}
m2ap_enb_data_p = m2ap_get_eNB(instance_p, -1,
sctp_new_association_resp->ulp_cnx_id);
DevAssert(m2ap_enb_data_p != NULL);
//printf("m2ap_eNB_handle_sctp_association_resp at 2\n");
//dump_trees_m2();
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
M2AP_WARN("Received unsuccessful result for SCTP association (%u), instance %d, cnx_id %u\n",
sctp_new_association_resp->sctp_state,
instance,
sctp_new_association_resp->ulp_cnx_id);
//m2ap_handle_m2_setup_message(instance_p, m2ap_enb_data_p,
// sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
return;
}
//printf("m2ap_eNB_handle_sctp_association_resp at 3\n");
//dump_trees_m2();
/* Update parameters */
m2ap_enb_data_p->assoc_id = sctp_new_association_resp->assoc_id;
m2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams;
m2ap_enb_data_p->out_streams = sctp_new_association_resp->out_streams;
//printf("m2ap_eNB_handle_sctp_association_resp at 4\n");
//dump_trees_m2();
m2ap_enb_data_g->assoc_id = sctp_new_association_resp->assoc_id;
m2ap_enb_data_g->sctp_in_streams = sctp_new_association_resp->in_streams;
m2ap_enb_data_g->sctp_out_streams = sctp_new_association_resp->out_streams;
/* Prepare new m2 Setup Request */
//m2ap_eNB_generate_m2_setup_request(instance_p, m2ap_enb_data_p);
eNB_send_M2_SETUP_REQUEST(instance_p, m2ap_enb_data_p);
//eNB_send_M2_SETUP_REQUEST(instance_p, m2ap_enb_data_g);
}
static
void m2ap_eNB_handle_sctp_association_ind(instance_t instance, sctp_new_association_ind_t *sctp_new_association_ind) {
m2ap_eNB_instance_t *instance_p;
m2ap_eNB_data_t *m2ap_enb_data_p;
//printf("m2ap_eNB_handle_sctp_association_ind at 1 (called for instance %d)\n", instance);
//dump_trees_m2();
DevAssert(sctp_new_association_ind != NULL);
instance_p = m2ap_eNB_get_instance(instance);
DevAssert(instance_p != NULL);
m2ap_enb_data_p = m2ap_get_eNB(instance_p, sctp_new_association_ind->assoc_id, -1);
if (m2ap_enb_data_p != NULL) abort();
// DevAssert(m2ap_enb_data_p != NULL);
if (m2ap_enb_data_p == NULL) {
/* Create new eNB descriptor */
m2ap_enb_data_p = calloc(1, sizeof(*m2ap_enb_data_p));
DevAssert(m2ap_enb_data_p != NULL);
m2ap_enb_data_p->cnx_id = m2ap_eNB_fetch_add_global_cnx_id();
m2ap_enb_data_p->m2ap_eNB_instance = instance_p;
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
RB_INSERT(m2ap_enb_map, &instance_p->m2ap_enb_head, m2ap_enb_data_p);
m2ap_enb_data_p->state = M2AP_ENB_STATE_CONNECTED;
instance_p->m2_target_enb_nb++;
if (instance_p->m2_target_enb_pending_nb > 0) {
instance_p->m2_target_enb_pending_nb--;
}
} else {
M2AP_WARN("m2ap_enb_data_p already exists\n");
}
//printf("m2ap_eNB_handle_sctp_association_ind at 2\n");
//dump_trees_m2();
/* Update parameters */
m2ap_enb_data_p->assoc_id = sctp_new_association_ind->assoc_id;
m2ap_enb_data_p->in_streams = sctp_new_association_ind->in_streams;
m2ap_enb_data_p->out_streams = sctp_new_association_ind->out_streams;
//printf("m2ap_eNB_handle_sctp_association_ind at 3\n");
//dump_trees_m2();
}
int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M2C) {
// Create and alloc new message
MessageDef *message;
sctp_init_t *sctp_init = NULL;
DevAssert(instance_p != NULL);
DevAssert(local_ip_addr != NULL);
message = itti_alloc_new_message (TASK_M2AP_ENB, SCTP_INIT_MSG_MULTI_REQ);
sctp_init = &message->ittiMsg.sctp_init_multi;
sctp_init->port = enb_port_for_M2C;
sctp_init->ppid = M2AP_SCTP_PPID;
sctp_init->ipv4 = 1;
sctp_init->ipv6 = 0;
sctp_init->nb_ipv4_addr = 1;
#if 0
memcpy(&sctp_init->ipv4_address,
local_ip_addr,
sizeof(*local_ip_addr));
#endif
sctp_init->ipv4_address[0] = inet_addr(local_ip_addr->ipv4_address);
/*
* SR WARNING: ipv6 multi-homing fails sometimes for localhost.
* * * * Disable it for now.
*/
sctp_init->nb_ipv6_addr = 0;
sctp_init->ipv6_address[0] = "0:0:0:0:0:0:0:1";
return itti_send_msg_to_task (TASK_SCTP, instance_p->instance, message);
}
static void m2ap_eNB_register_eNB(m2ap_eNB_instance_t *instance_p,
net_ip_address_t *target_eNB_ip_address,
net_ip_address_t *local_ip_addr,
uint16_t in_streams,
uint16_t out_streams,
uint32_t enb_port_for_M2C,
int multi_sd) {
MessageDef *message = NULL;
sctp_new_association_req_multi_t *sctp_new_association_req = NULL;
m2ap_eNB_data_t *m2ap_enb_data = NULL;
DevAssert(instance_p != NULL);
DevAssert(target_eNB_ip_address != NULL);
message = itti_alloc_new_message(TASK_M2AP_ENB, SCTP_NEW_ASSOCIATION_REQ_MULTI);
sctp_new_association_req = &message->ittiMsg.sctp_new_association_req_multi;
sctp_new_association_req->port = enb_port_for_M2C;
sctp_new_association_req->ppid = M2AP_SCTP_PPID;
sctp_new_association_req->in_streams = in_streams;
sctp_new_association_req->out_streams = out_streams;
sctp_new_association_req->multi_sd = multi_sd;
memcpy(&sctp_new_association_req->remote_address,
target_eNB_ip_address,
sizeof(*target_eNB_ip_address));
memcpy(&sctp_new_association_req->local_address,
local_ip_addr,
sizeof(*local_ip_addr));
/* Create new eNB descriptor */
m2ap_enb_data = calloc(1, sizeof(*m2ap_enb_data));
DevAssert(m2ap_enb_data != NULL);
m2ap_enb_data->cnx_id = m2ap_eNB_fetch_add_global_cnx_id();
sctp_new_association_req->ulp_cnx_id = m2ap_enb_data->cnx_id;
m2ap_enb_data->assoc_id = -1;
m2ap_enb_data->m2ap_eNB_instance = instance_p;
m2ap_enb_data_g = (m2ap_setup_req_t*)calloc(1,sizeof(m2ap_setup_req_t));
//
m2ap_enb_data->eNB_name = "enb_name";
/* Insert the new descriptor in list of known eNB
* but not yet associated.
*/
RB_INSERT(m2ap_enb_map, &instance_p->m2ap_enb_head, m2ap_enb_data);
m2ap_enb_data->state = M2AP_ENB_STATE_WAITING;
instance_p->m2_target_enb_nb ++;
instance_p->m2_target_enb_pending_nb ++;
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message);
}
static
void m2ap_eNB_handle_register_eNB(instance_t instance,
m2ap_register_enb_req_t *m2ap_register_eNB) {
m2ap_eNB_instance_t *new_instance;
DevAssert(m2ap_register_eNB != NULL);
/* Look if the provided instance already exists */
new_instance = m2ap_eNB_get_instance(instance);
if (new_instance != NULL) {
/* Checks if it is a retry on the same eNB */
DevCheck(new_instance->eNB_id == m2ap_register_eNB->eNB_id, new_instance->eNB_id, m2ap_register_eNB->eNB_id, 0);
DevCheck(new_instance->cell_type == m2ap_register_eNB->cell_type, new_instance->cell_type, m2ap_register_eNB->cell_type, 0);
DevCheck(new_instance->tac == m2ap_register_eNB->tac, new_instance->tac, m2ap_register_eNB->tac, 0);
DevCheck(new_instance->mcc == m2ap_register_eNB->mcc, new_instance->mcc, m2ap_register_eNB->mcc, 0);
DevCheck(new_instance->mnc == m2ap_register_eNB->mnc, new_instance->mnc, m2ap_register_eNB->mnc, 0);
M2AP_WARN("eNB[%d] already registered\n", instance);
} else {
new_instance = calloc(1, sizeof(m2ap_eNB_instance_t));
DevAssert(new_instance != NULL);
RB_INIT(&new_instance->m2ap_enb_head);
/* Copy usefull parameters */
new_instance->instance = instance;
new_instance->eNB_name = m2ap_register_eNB->eNB_name;
new_instance->eNB_id = m2ap_register_eNB->eNB_id;
new_instance->cell_type = m2ap_register_eNB->cell_type;
new_instance->tac = m2ap_register_eNB->tac;
new_instance->mcc = m2ap_register_eNB->mcc;
new_instance->mnc = m2ap_register_eNB->mnc;
new_instance->mnc_digit_length = m2ap_register_eNB->mnc_digit_length;
new_instance->num_cc = m2ap_register_eNB->num_cc;
m2ap_id_manager_init(&new_instance->id_manager);
m2ap_timers_init(&new_instance->timers,
m2ap_register_eNB->t_reloc_prep,
m2ap_register_eNB->tm2_reloc_overall);
for (int i = 0; i< m2ap_register_eNB->num_cc; i++) {
new_instance->eutra_band[i] = m2ap_register_eNB->eutra_band[i];
new_instance->downlink_frequency[i] = m2ap_register_eNB->downlink_frequency[i];
new_instance->uplink_frequency_offset[i] = m2ap_register_eNB->uplink_frequency_offset[i];
new_instance->Nid_cell[i] = m2ap_register_eNB->Nid_cell[i];
new_instance->N_RB_DL[i] = m2ap_register_eNB->N_RB_DL[i];
new_instance->frame_type[i] = m2ap_register_eNB->frame_type[i];
new_instance->fdd_earfcn_DL[i] = m2ap_register_eNB->fdd_earfcn_DL[i];
new_instance->fdd_earfcn_UL[i] = m2ap_register_eNB->fdd_earfcn_UL[i];
}
DevCheck(m2ap_register_eNB->nb_m2 <= M2AP_MAX_NB_ENB_IP_ADDRESS,
M2AP_MAX_NB_ENB_IP_ADDRESS, m2ap_register_eNB->nb_m2, 0);
memcpy(new_instance->target_mce_m2_ip_address,
m2ap_register_eNB->target_mce_m2_ip_address,
m2ap_register_eNB->nb_m2 * sizeof(net_ip_address_t));
new_instance->nb_m2 = m2ap_register_eNB->nb_m2;
new_instance->enb_m2_ip_address = m2ap_register_eNB->enb_m2_ip_address;
new_instance->sctp_in_streams = m2ap_register_eNB->sctp_in_streams;
new_instance->sctp_out_streams = m2ap_register_eNB->sctp_out_streams;
new_instance->enb_port_for_M2C = m2ap_register_eNB->enb_port_for_M2C;
new_instance->num_mbms_configuration_data_list = m2ap_register_eNB->num_mbms_configuration_data_list;
for(int j=0; j < m2ap_register_eNB->num_mbms_configuration_data_list;j++){
new_instance->mbms_configuration_data_list[j].num_mbms_service_area_list = m2ap_register_eNB->mbms_configuration_data_list[j].num_mbms_service_area_list;
for(int i=0; i < m2ap_register_eNB->mbms_configuration_data_list[j].num_mbms_service_area_list; i++ ){
//strcpy(&new_instance->mbms_configuration_data_list[j].mbms_service_area_list[i],&m2ap_register_eNB->mbms_configuration_data_list[j].mbms_service_area_list[i]);
new_instance->mbms_configuration_data_list[j].mbms_service_area_list[i]=m2ap_register_eNB->mbms_configuration_data_list[j].mbms_service_area_list[i];
}
}
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
m2ap_eNB_insert_new_instance(new_instance);
M2AP_INFO("Registered new eNB[%d] and %s eNB id %u\n",
instance,
m2ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
m2ap_register_eNB->eNB_id);
/* initiate the SCTP listener */
if (m2ap_eNB_init_sctp(new_instance,&m2ap_register_eNB->enb_m2_ip_address,m2ap_register_eNB->enb_port_for_M2C) < 0 ) {
M2AP_ERROR ("Error while sending SCTP_INIT_MSG to SCTP \n");
return;
}
M2AP_INFO("eNB[%d] eNB id %u acting as a listner (server)\n",
instance, m2ap_register_eNB->eNB_id);
}
}
static
void m2ap_eNB_handle_sctp_init_msg_multi_cnf(
instance_t instance_id,
sctp_init_msg_multi_cnf_t *m) {
m2ap_eNB_instance_t *instance;
int index;
DevAssert(m != NULL);
instance = m2ap_eNB_get_instance(instance_id);
DevAssert(instance != NULL);
instance->multi_sd = m->multi_sd;
/* Exit if CNF message reports failure.
* Failure means multi_sd < 0.
*/
if (instance->multi_sd < 0) {
M2AP_ERROR("Error: be sure to properly configure M2 in your configuration file.\n");
DevAssert(instance->multi_sd >= 0);
}
/* Trying to connect to the provided list of eNB ip address */
for (index = 0; index < instance->nb_m2; index++) {
M2AP_INFO("eNB[%d] eNB id %u acting as an initiator (client)\n",
instance_id, instance->eNB_id);
m2ap_eNB_register_eNB(instance,
&instance->target_mce_m2_ip_address[index],
&instance->enb_m2_ip_address,
instance->sctp_in_streams,
instance->sctp_out_streams,
instance->enb_port_for_M2C,
instance->multi_sd);
}
}
//static
//void m2ap_eNB_handle_handover_req(instance_t instance,
// m2ap_handover_req_t *m2ap_handover_req)
//{
// m2ap_eNB_instance_t *instance_p;
// m2ap_eNB_data_t *target;
// m2ap_id_manager *id_manager;
// int ue_id;
//
// int target_pci = m2ap_handover_req->target_physCellId;
//
// instance_p = m2ap_eNB_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m2ap_is_eNB_pci_in_list(target_pci);
// DevAssert(target != NULL);
//
// /* allocate m2ap ID */
// id_manager = &instance_p->id_manager;
// ue_id = m2ap_allocate_new_id(id_manager);
// if (ue_id == -1) {
// M2AP_ERROR("could not allocate a new M2AP UE ID\n");
// /* TODO: cancel handover: send (to be defined) message to RRC */
// exit(1);
// }
// /* id_source is ue_id, id_target is unknown yet */
// m2ap_set_ids(id_manager, ue_id, m2ap_handover_req->rnti, ue_id, -1);
// m2ap_id_set_state(id_manager, ue_id, M2ID_STATE_SOURCE_PREPARE);
// m2ap_set_reloc_prep_timer(id_manager, ue_id,
// m2ap_timer_get_tti(&instance_p->timers));
// m2ap_id_set_target(id_manager, ue_id, target);
//
// m2ap_eNB_generate_m2_handover_request(instance_p, target, m2ap_handover_req, ue_id);
//}
//static
//void m2ap_eNB_handle_handover_req_ack(instance_t instance,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack)
//{
// /* TODO: remove this hack (the goal is to find the correct
// * eNodeB structure for the other end) - we need a proper way for RRC
// * and M2AP to identify eNodeBs
// * RRC knows about mod_id and M2AP knows about eNB_id (eNB_ID in
// * the configuration file)
// * as far as I understand.. CROUX
// */
// m2ap_eNB_instance_t *instance_p;
// m2ap_eNB_data_t *target;
// int source_assoc_id = m2ap_handover_req_ack->source_assoc_id;
// int ue_id;
// int id_source;
// int id_target;
//
// instance_p = m2ap_eNB_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m2ap_get_eNB(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// /* rnti is a new information, save it */
// ue_id = m2ap_handover_req_ack->m2_id_target;
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
// m2ap_set_ids(&instance_p->id_manager, ue_id, m2ap_handover_req_ack->rnti, id_source, id_target);
//
// m2ap_eNB_generate_m2_handover_request_ack(instance_p, target, m2ap_handover_req_ack);
//}
//
//static
//void m2ap_eNB_ue_context_release(instance_t instance,
// m2ap_ue_context_release_t *m2ap_ue_context_release)
//{
// m2ap_eNB_instance_t *instance_p;
// m2ap_eNB_data_t *target;
// int source_assoc_id = m2ap_ue_context_release->source_assoc_id;
// int ue_id;
// instance_p = m2ap_eNB_get_instance(instance);
// DevAssert(instance_p != NULL);
//
// target = m2ap_get_eNB(NULL, source_assoc_id, 0);
// DevAssert(target != NULL);
//
// m2ap_eNB_generate_m2_ue_context_release(instance_p, target, m2ap_ue_context_release);
//
// /* free the M2AP UE ID */
// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
// exit(1);
// }
// m2ap_release_id(&instance_p->id_manager, ue_id);
//}
//void MCE_task_send_sctp_init_req(instance_t enb_id) {
// // 1. get the itti msg, and retrive the enb_id from the message
// // 2. use RC.rrc[enb_id] to fill the sctp_init_t with the ip, port
// // 3. creat an itti message to init
//
// LOG_I(M2AP, "M2AP_SCTP_REQ(create socket)\n");
// MessageDef *message_p = NULL;
//
// message_p = itti_alloc_new_message (M2AP, SCTP_INIT_MSG);
// message_p->ittiMsg.sctp_init.port = M2AP_PORT_NUMBER;
// message_p->ittiMsg.sctp_init.ppid = M2AP_SCTP_PPID;
// message_p->ittiMsg.sctp_init.ipv4 = 1;
// message_p->ittiMsg.sctp_init.ipv6 = 0;
// message_p->ittiMsg.sctp_init.nb_ipv4_addr = 1;
// //message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr(RC.rrc[enb_id]->eth_params_s.my_addr);
// message_p->ittiMsg.sctp_init.ipv4_address[0] = inet_addr("127.0.0.7");
// /*
// * SR WARNING: ipv6 multi-homing fails sometimes for localhost.
// * * * * Disable it for now.
// */
// message_p->ittiMsg.sctp_init.nb_ipv6_addr = 0;
// message_p->ittiMsg.sctp_init.ipv6_address[0] = "0:0:0:0:0:0:0:1";
//
// itti_send_msg_to_task(TASK_SCTP, enb_id, message_p);
//}
//
void *m2ap_eNB_task(void *arg) {
MessageDef *received_msg = NULL;
int result;
M2AP_DEBUG("Starting M2AP layer\n");
m2ap_eNB_prepare_internal_data();
itti_mark_task_ready(TASK_M2AP_ENB);
// MCE_task_send_sctp_init_req(0);
while (1) {
itti_receive_msg(TASK_M2AP_ENB, &received_msg);
switch (ITTI_MSG_ID(received_msg)) {
case MESSAGE_TEST:
LOG_D(M2AP,"eNB Received MESSAGE_TEST Message %s\n",itti_get_task_name(ITTI_MSG_ORIGIN_ID(received_msg)));
//MessageDef * message_p = itti_alloc_new_message(TASK_M2AP_ENB, MESSAGE_TEST);
//itti_send_msg_to_task(TASK_M3AP, 1/*ctxt_pP->module_id*/, message_p);
break;
case TERMINATE_MESSAGE:
M2AP_WARN(" *** Exiting M2AP thread\n");
itti_exit_task();
break;
case M2AP_SUBFRAME_PROCESS:
m2ap_check_timers(ITTI_MESSAGE_GET_INSTANCE(received_msg));
break;
case M2AP_REGISTER_ENB_REQ:
LOG_I(M2AP,"eNB Received M2AP_REGISTER_ENB_REQ Message\n");
m2ap_eNB_handle_register_eNB(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_REGISTER_ENB_REQ(received_msg));
break;
case M2AP_MBMS_SCHEDULING_INFORMATION_RESP:
LOG_I(M2AP,"eNB M2AP_MBMS_SCHEDULING_INFORMATION_RESP Message\n");
eNB_send_MBMS_SCHEDULING_INFORMATION_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SCHEDULING_INFORMATION_RESP(received_msg));
break;
case M2AP_MBMS_SESSION_START_RESP:
LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_RESP Message\n");
eNB_send_MBMS_SESSION_START_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SESSION_START_RESP(received_msg));
break;
case M2AP_MBMS_SESSION_START_FAILURE:
LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_START_FAILURE Message\n");
eNB_send_MBMS_SESSION_START_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SESSION_START_FAILURE(received_msg));
break;
case M2AP_MBMS_SESSION_STOP_RESP:
LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_STOP_RESP Message\n");
eNB_send_MBMS_SESSION_STOP_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SESSION_STOP_RESP(received_msg));
break;
case M2AP_ENB_CONFIGURATION_UPDATE:
LOG_I(M2AP,"eNB M2AP_ENB_CONFIGURATION_UPDATE Message\n");
eNB_send_eNB_CONFIGURATION_UPDATE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_ENB_CONFIGURATION_UPDATE(received_msg));
break;
case M2AP_MCE_CONFIGURATION_UPDATE_ACK:
LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_ACK Message\n");
//eNB_send_MCE_CONFIGURATION_UPDATE_ACKNOWLEDGE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
// &M2AP_MCE_CONFIGURATION_UPDATE_ACK(received_msg));
break;
case M2AP_MCE_CONFIGURATION_UPDATE_FAILURE:
LOG_I(M2AP,"eNB M2AP_MCE_CONFIGURATION_UPDATE_FAILURE Message\n");
//(ITTI_MESSAGE_GET_INSTANCE(received_msg),
//&M2AP_MCE_CONFIGURATION_UPDATE_FAILURE(received_msg));
break;
case M2AP_MBMS_SESSION_UPDATE_RESP:
LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_RESP Message\n");
eNB_send_MBMS_SESSION_UPDATE_RESPONSE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SESSION_UPDATE_RESP(received_msg));
break;
case M2AP_MBMS_SESSION_UPDATE_FAILURE:
LOG_I(M2AP,"eNB M2AP_MBMS_SESSION_UPDATE_FAILURE Message\n");
eNB_send_MBMS_SESSION_UPDATE_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SESSION_UPDATE_FAILURE(received_msg));
break;
case M2AP_MBMS_SERVICE_COUNTING_REPORT:
LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_REPORT Message\n");
eNB_send_MBMS_SERVICE_COUNTING_REPORT(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SERVICE_COUNTING_REPORT(received_msg));
break;
case M2AP_MBMS_OVERLOAD_NOTIFICATION:
LOG_I(M2AP,"eNB M2AP_MBMS_OVERLOAD_NOTIFICATION Message\n");
eNB_send_MBMS_OVERLOAD_NOTIFICATION(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_OVERLOAD_NOTIFICATION(received_msg));
break;
case M2AP_MBMS_SERVICE_COUNTING_RESP:
LOG_I(M2AP,"eNB M2AP_MBMS_SERVICE_COUNTING_RESP Message\n");
eNB_send_MBMS_SERVICE_COUNTING_RESP(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SERVICE_COUNTING_RESP(received_msg));
break;
case M2AP_MBMS_SERVICE_COUNTING_FAILURE:
LOG_I(M2AP,"eNB Message\n");
eNB_send_MBMS_SERVICE_COUNTING_FAILURE(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&M2AP_MBMS_SERVICE_COUNTING_FAILURE(received_msg));
break;
case SCTP_INIT_MSG_MULTI_CNF:
LOG_I(M2AP,"eNB Received SCTP_INIT_MSG_MULTI_CNF Message\n");
m2ap_eNB_handle_sctp_init_msg_multi_cnf(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_init_msg_multi_cnf);
break;
case SCTP_NEW_ASSOCIATION_RESP:
LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION_RESP Message\n");
m2ap_eNB_handle_sctp_association_resp(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_resp);
break;
case SCTP_NEW_ASSOCIATION_IND:
LOG_I(M2AP,"eNB Received SCTP_NEW_ASSOCIATION Message\n");
m2ap_eNB_handle_sctp_association_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_new_association_ind);
break;
case SCTP_DATA_IND:
LOG_I(M2AP,"eNB Received SCTP_DATA_IND Message\n");
m2ap_eNB_handle_sctp_data_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg),
&received_msg->ittiMsg.sctp_data_ind);
break;
default:
M2AP_ERROR("eNB Received unhandled message: %d:%s\n",
ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg));
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(received_msg), received_msg);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
received_msg = NULL;
}
return NULL;
}
#include "common/config/config_userapi.h"
int is_m2ap_eNB_enabled(void)
{
static volatile int config_loaded = 0;
static volatile int enabled = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if (pthread_mutex_lock(&mutex)) goto mutex_error;
if (config_loaded) {
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
}
char *enable_m2 = NULL;
paramdef_t p[] = {
{ "enable_enb_m2", "yes/no", 0, strptr:&enable_m2, defstrval:"", TYPE_STRING, 0 }
};
/* TODO: do it per module - we check only first eNB */
config_get(p, sizeof(p)/sizeof(paramdef_t), "eNBs.[0]");
if (enable_m2 != NULL && strcmp(enable_m2, "yes") == 0)
enabled = 1;
config_loaded = 1;
if (pthread_mutex_unlock(&mutex)) goto mutex_error;
return enabled;
mutex_error:
LOG_E(M2AP, "mutex error\n");
exit(1);
}
+55
View File
@@ -0,0 +1,55 @@
/*
* 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 m2ap_eNB.h
* \brief m2ap tasks for eNB
* \author Konstantinos Alexandris <Konstantinos.Alexandris@eurecom.fr>, Cedric Roux <Cedric.Roux@eurecom.fr>, Navid Nikaein <Navid.Nikaein@eurecom.fr>
* \date 2018
* \version 1.0
*/
#include <stdio.h>
#include <stdint.h>
/** @defgroup _m2ap_impl_ M2AP Layer Reference Implementation
* @ingroup _ref_implementation_
* @{
*/
#ifndef M2AP_ENB_H_
#define M2AP_ENB_H_
#include "m2ap_eNB_defs.h"
int m2ap_eNB_init_sctp (m2ap_eNB_instance_t *instance_p,
net_ip_address_t *local_ip_addr,
uint32_t enb_port_for_M2C);
void *m2ap_eNB_task(void *arg);
int is_m2ap_eNB_enabled(void);
#endif /* M2AP_ENB_H_ */
/**
* @}
*/
+221
View File
@@ -0,0 +1,221 @@
/*
* 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 m2ap_eNB_defs.h
* \brief m2ap struct definitions for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "queue.h"
#include "tree.h"
#include "sctp_eNB_defs.h"
#include "m2ap_ids.h" //looks X2AP specific for HO
#include "m2ap_timers.h"
#ifndef M2AP_ENB_DEFS_H_
#define M2AP_ENB_DEFS_H_
#define M2AP_ENB_NAME_LENGTH_MAX (150)
typedef enum {
/* Disconnected state: initial state for any association. */
M2AP_ENB_STATE_DISCONNECTED = 0x0,
/* State waiting for m2 Setup response message if the target eNB accepts or
* M2 Setup failure if rejects the eNB.
*/
M2AP_ENB_STATE_WAITING = 0x1,
/* The eNB is successfully connected to another eNB. */
M2AP_ENB_STATE_CONNECTED = 0x2,
/* M2AP is ready, and the eNB is successfully connected to another eNB. */
M2AP_ENB_STATE_READY = 0x3,
M2AP_ENB_STATE_OVERLOAD = 0x4,
M2AP_ENB_STATE_RESETTING = 0x5,
/* Max number of states available */
M2AP_ENB_STATE_MAX,
} m2ap_eNB_state_t;
/* Served PLMN identity element */
/*struct plmn_identity_s {
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
STAILQ_ENTRY(plmn_identity_s) next;
};*/
/* Served group id element */
/*struct served_group_id_s {
uint16_t enb_group_id;
STAILQ_ENTRY(served_group_id_s) next;
};*/
/* Served enn code for a particular eNB */
/*struct enb_code_s {
uint8_t enb_code;
STAILQ_ENTRY(enb_code_s) next;
};*/
struct m2ap_eNB_instance_s;
/* This structure describes association of a eNB to another eNB */
typedef struct m2ap_eNB_data_s {
/* eNB descriptors tree, ordered by sctp assoc id */
RB_ENTRY(m2ap_eNB_data_s) entry;
/* This is the optional name provided by the MME */
char *eNB_name;
/* target eNB ID */
uint32_t eNB_id;
/* Current eNB load information (if any). */
//m2ap_load_state_t overload_state;
/* Current eNB->eNB M2AP association state */
m2ap_eNB_state_t state;
/* Next usable stream for UE signalling */
int32_t nextstream;
/* Number of input/ouput streams */
uint16_t in_streams;
uint16_t out_streams;
/* Connexion id used between SCTP/M2AP */
uint16_t cnx_id;
/* SCTP association id */
int32_t assoc_id;
/* Nid cells */
uint32_t Nid_cell[MAX_NUM_CCs];
int num_cc;
/* Only meaningfull in virtual mode */
struct m2ap_eNB_instance_s *m2ap_eNB_instance;
} m2ap_eNB_data_t;
typedef struct m2ap_eNB_instance_s {
/* used in simulation to store multiple eNB instances*/
STAILQ_ENTRY(m2ap_eNB_instance_s) m2ap_eNB_entries;
/* Number of target eNBs requested by eNB (tree size) */
uint32_t m2_target_enb_nb;
/* Number of target eNBs for which association is pending */
uint32_t m2_target_enb_pending_nb;
/* Number of target eNB successfully associated to eNB */
uint32_t m2_target_enb_associated_nb;
/* Tree of M2AP eNB associations ordered by association ID */
RB_HEAD(m2ap_enb_map, m2ap_eNB_data_s) m2ap_enb_head;
/* Tree of UE ordered by eNB_ue_m2ap_id's */
// RB_HEAD(m2ap_ue_map, m2ap_eNB_ue_context_s) m2ap_ue_head;
/* For virtual mode, mod_id as defined in the rest of the L1/L2 stack */
instance_t instance;
/* Displayable name of eNB */
char *eNB_name;
/* Unique eNB_id to identify the eNB within EPC.
* In our case the eNB is a macro eNB so the id will be 20 bits long.
* For Home eNB id, this field should be 28 bits long.
*/
uint32_t eNB_id;
/* The type of the cell */
cell_type_t cell_type;
//uint16_t num_mbms_service_area_list;
//uint16_t mbms_service_area_list[8];
struct{
uint16_t mbsfn_sync_area;
uint16_t mbms_service_area_list[8];
uint16_t num_mbms_service_area_list;
}mbms_configuration_data_list[8];
uint8_t num_mbms_configuration_data_list;
/* Tracking area code */
uint16_t tac;
/* Mobile Country Code
* Mobile Network Code
*/
uint16_t mcc;
uint16_t mnc;
uint8_t mnc_digit_length;
/* CC params */
int16_t eutra_band[MAX_NUM_CCs];
uint32_t downlink_frequency[MAX_NUM_CCs];
int32_t uplink_frequency_offset[MAX_NUM_CCs];
uint32_t Nid_cell[MAX_NUM_CCs];
int16_t N_RB_DL[MAX_NUM_CCs];
lte_frame_type_t frame_type[MAX_NUM_CCs];
uint32_t fdd_earfcn_DL[MAX_NUM_CCs];
uint32_t fdd_earfcn_UL[MAX_NUM_CCs];
int num_cc;
net_ip_address_t target_mce_m2_ip_address[M2AP_MAX_NB_ENB_IP_ADDRESS];
uint8_t nb_m2;
net_ip_address_t enb_m2_ip_address;
uint16_t sctp_in_streams;
uint16_t sctp_out_streams;
uint32_t enb_port_for_M2C;
int multi_sd;
m2ap_id_manager id_manager;
m2ap_timers_t timers;
} m2ap_eNB_instance_t;
typedef struct {
/* List of served eNBs
* Only used for virtual mode
*/
STAILQ_HEAD(m2ap_eNB_instances_head_s, m2ap_eNB_instance_s) m2ap_eNB_instances_head;
/* Nb of registered eNBs */
uint8_t nb_registered_eNBs;
/* Generate a unique connexion id used between M2AP and SCTP */
uint16_t global_cnx_id;
} m2ap_eNB_internal_data_t;
int m2ap_eNB_compare_assoc_id(struct m2ap_eNB_data_s *p1, struct m2ap_eNB_data_s *p2);
/* Generate the tree management functions */
struct m2ap_eNB_map;
struct m2ap_eNB_data_s;
RB_PROTOTYPE(m2ap_eNB_map, m2ap_eNB_data_s, entry, m2ap_eNB_compare_assoc_id);
#endif /* M2AP_ENB_DEFS_H_ */
+808
View File
@@ -0,0 +1,808 @@
/*
* 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 m2ap_eNB_generate_messages.c
* \brief m2ap procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include "intertask_interface.h"
//#include "M2AP_LastVisitedCell-Item.h"
#include "m2ap_common.h"
#include "m2ap_eNB.h"
#include "m2ap_eNB_generate_messages.h"
#include "m2ap_encoder.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
#include "m2ap_itti_messaging.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
//int m2ap_eNB_generate_m2_setup_request(
// m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p)
//{
// module_id_t enb_mod_idP=0;
// module_id_t du_mod_idP=0;
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_M2SetupRequest_t *out;
// M2AP_M2SetupRequest_Ies_t *ie;
//
// uint8_t *buffer;
// uint32_t len;
// int i = 0;
// int j = 0;
//
// /* Create */
// /* 0. pdu Type */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// //pdu.choice.initiatingMessage = (M2AP_InitiatingMessage_t *)calloc(1, sizeof(M2AP_InitiatingMessage_t));
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_m2Setup;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_M2SetupRequest;
// out = &pdu.choice.initiatingMessage.value.choice.M2SetupRequest;
//
// /* mandatory */
// /* c1. GlobalENB_ID (integer value) */
// ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
// ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_GlobalENB_ID;
// //ie->value.choice.GlobalENB_ID.eNB_ID = 1;//M2AP_get_next_transaction_identifier(enb_mod_idP, du_mod_idP);
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GlobalENB_ID.pLMN_Identity);
// ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
// MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
// &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
// M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
// ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
// ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
// ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// ///* mandatory */
// ///* c2. GNB_eNB_ID (integrer value) */
// //ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_gNB_eNB_ID;
// //ie->criticality = M2AP_Criticality_reject;
// //ie->value.present = M2AP_M2SetupRequestIEs__value_PR_GNB_eNB_ID;
// //asn_int642INTEGER(&ie->value.choice.GNB_eNB_ID, f1ap_du_data->gNB_eNB_id);
// //ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional */
// /* c3. ENBname */
// if (m2ap_eNB_data_p->eNB_name != NULL) {
// ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
// ie->id = M2AP_ProtocolIE_ID_id_ENBname;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENBname;
// //OCTET_STRING_fromBuf(&ie->value.choice.ENB_Name, m2ap_eNB_data_p->eNB_name,
// //strlen(m2ap_eNB_data_p->eNB_name));
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
// }
//
// /* mandatory */
// /* c4. serverd cells list */
// ie = (M2AP_M2SetupRequest_Ies_t *)calloc(1, sizeof(M2AP_M2SetupRequest_Ies_t));
// ie->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_List;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_M2SetupRequest_Ies__value_PR_ENB_MBMS_Configuration_data_List;
//
// int num_mbms_available = 1;//m2ap_du_data->num_mbms_available;
// LOG_D(M2AP, "num_mbms_available = %d \n", num_mbms_available);
//
// for (i=0;
// i<num_mbms_available;
// i++) {
// /* mandatory */
// /* 4.1 serverd cells item */
//
// M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *mbms_configuration_data_list_item_ies;
// mbms_configuration_data_list_item_ies = (M2AP_ENB_MBMS_Configuration_data_ItemIEs_t *)calloc(1, sizeof(M2AP_ENB_MBMS_Configuration_data_ItemIEs_t));
// mbms_configuration_data_list_item_ies->id = M2AP_ProtocolIE_ID_id_ENB_MBMS_Configuration_data_Item;
// mbms_configuration_data_list_item_ies->criticality = M2AP_Criticality_reject;
// mbms_configuration_data_list_item_ies->value.present = M2AP_ENB_MBMS_Configuration_data_ItemIEs__value_PR_ENB_MBMS_Configuration_data_Item;
//
// M2AP_ENB_MBMS_Configuration_data_Item_t *mbms_configuration_data_item;
// mbms_configuration_data_item = &mbms_configuration_data_list_item_ies->value.choice.ENB_MBMS_Configuration_data_Item;
// {
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &mbms_configuration_data_item->eCGI.pLMN_Identity);
// MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
// &mbms_configuration_data_item->eCGI.eUTRANcellIdentifier);
// M2AP_MBMS_Service_Area_t * mbms_service_area;
// mbms_service_area = (M2AP_MBMS_Service_Area_t*)calloc(1,sizeof(M2AP_MBMS_Service_Area_t));
// ASN_SEQUENCE_ADD(&mbms_configuration_data_item->mbmsServiceAreaList.list,mbms_service_area);
//
//
// }
//
//
// //M2AP_ENB_MBMS_Configuration_data_Item_t mbms_configuration_data_item;
// //memset((void *)&mbms_configuration_data_item, 0, sizeof(M2AP_ENB_MBMS_Configuration_data_Item_t));
//
// //M2AP_ECGI_t eCGI;
// //M2AP_PLMN_Identity_t pLMN_Identity;
// //M2AP_EUTRANCellIdentifier_t eUTRANcellIdentifier
// //M2AP_MBSFN_SynchronisationArea_ID_t mbsfnSynchronisationArea;
// //M2AP_MBMS_Service_Area_ID_List_t mbmsServiceAreaList;
//
//
// ASN_SEQUENCE_ADD(&ie->value.choice.ENB_MBMS_Configuration_data_List.list,mbms_configuration_data_list_item_ies);
//
// }
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// LOG_W(M2AP,"m2ap_eNB_data_p->assoc_id %d\n",m2ap_eNB_data_p->assoc_id);
// /* encode */
// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
// LOG_E(M2AP, "Failed to encode M2 setup request\n");
// return -1;
// }
//
//
// LOG_W(M2AP,"pdu.present %d\n",pdu.present);
// // MSC_LOG_TX_MESSAGE(
// // MSC_M2AP_eNB,
// // MSC_M2AP_MCE,
// // (const char *)buffer,
// // len,
// // MSC_AS_TIME_FMT" M2_SETUP_REQUEST initiatingMessage MCEname %s",
// // 0,0,//MSC_AS_TIME_ARGS(ctxt_pP),
// // m2ap_eNB_data_p->ENBname);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p, m2ap_eNB_data_p->assoc_id, buffer, len, 0);
//
// return 0;
//
//
//}
//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_M2SetupResponse_t *out;
// M2AP_M2SetupResponse_Ies_t *ie;
// //M2AP_PLMN_Identity_t *plmn;
// //ServedCells__Member *servedCellMember;
// //M2AP_GU_Group_ID_t *gu;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// /* Prepare the M2AP message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_M2SetupResponse;
// out = &pdu.choice.successfulOutcome.value.choice.M2SetupResponse;
//
// /* mandatory */
// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_GlobalENB_ID;
// //ie->criticality = M2AP_Criticality_reject;
// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GlobalENB_ID;
// //MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// // &ie->value.choice.GlobalENB_ID.pLMN_Identity);
// //ie->value.choice.GlobalENB_ID.eNB_ID.present = M2AP_ENB_ID_PR_macro_eNB_ID;
// //MACRO_ENB_ID_TO_BIT_STRING(instance_p->eNB_id,
// // &ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID);
// //M2AP_INFO("%d -> %02x%02x%02x\n", instance_p->eNB_id,
// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[0],
// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[1],
// // ie->value.choice.GlobalENB_ID.eNB_ID.choice.macro_eNB_ID.buf[2]);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_ServedCells;
// //ie->criticality = M2AP_Criticality_reject;
// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_ServedCells;
// //{
// // for (int i = 0; i<instance_p->num_cc; i++){
// // servedCellMember = (ServedCells__Member *)calloc(1,sizeof(ServedCells__Member));
// // {
// // servedCellMember->servedCellInfo.pCI = instance_p->Nid_cell[i];
//
// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// // &servedCellMember->servedCellInfo.cellId.pLMN_Identity);
// // MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,0,
// // &servedCellMember->servedCellInfo.cellId.eUTRANcellIdentifier);
//
// // INT16_TO_OCTET_STRING(instance_p->tac, &servedCellMember->servedCellInfo.tAC);
// // plmn = (M2AP_PLMN_Identity_t *)calloc(1,sizeof(M2AP_PLMN_Identity_t));
// // {
// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length, plmn);
// // ASN_SEQUENCE_ADD(&servedCellMember->servedCellInfo.broadcastPLMNs.list, plmn);
// // }
//
// // if (instance_p->frame_type[i] == FDD) {
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.present = M2AP_EUTRA_Mode_Info_PR_fDD;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_EARFCN = instance_p->fdd_earfcn_DL[i];
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_EARFCN = instance_p->fdd_earfcn_UL[i];
// // switch (instance_p->N_RB_DL[i]) {
// // case 6:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw6;
// // break;
// // case 15:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw15;
// // break;
// // case 25:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw25;
// // break;
// // case 50:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw50;
// // break;
// // case 75:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw75;
// // break;
// // case 100:
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.uL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// // servedCellMember->servedCellInfo.eUTRA_Mode_Info.choice.fDD.dL_Transmission_Bandwidth = M2AP_Transmission_Bandwidth_bw100;
// // break;
// // default:
// // AssertFatal(0,"Failed: Check value for N_RB_DL/N_RB_UL");
// // break;
// // }
// // }
// // else {
// // AssertFatal(0,"M2Setupresponse not supported for TDD!");
// // }
// // }
// // ASN_SEQUENCE_ADD(&ie->value.choice.ServedCells.list, servedCellMember);
// // }
// //}
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_M2SetupResponse_Ies_t *)calloc(1, sizeof(M2AP_M2SetupResponse_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_GUGroupIDList;
// //ie->criticality = M2AP_Criticality_reject;
// //ie->value.present = M2AP_M2SetupResponse_IEs__value_PR_GUGroupIDList;
// //{
// // gu = (M2AP_GU_Group_ID_t *)calloc(1, sizeof(M2AP_GU_Group_ID_t));
// // {
// // MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// // &gu->pLMN_Identity);
// // //@TODO: consider to update this value
// // INT16_TO_OCTET_STRING(0, &gu->mME_Group_ID);
// // }
// // ASN_SEQUENCE_ADD(&ie->value.choice.GUGroupIDList.list, gu);
// //}
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode M2 setup response\n");
// return -1;
// }
//
// m2ap_eNB_data_p->state = M2AP_ENB_STATE_READY;
//
// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 M2Setup/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 0);
//
// return ret;
//}
//int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
// uint32_t assoc_id,
// M2AP_Cause_PR cause_type,
// long cause_value,
// long time_to_wait)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_M2SetupFailure_t *out;
// M2AP_M2SetupFailure_Ies_t *ie;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// /* Prepare the M2AP message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_unsuccessfulOutcome;
// pdu.choice.unsuccessfulOutcome.procedureCode = M2AP_ProcedureCode_id_m2Setup;
// pdu.choice.unsuccessfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.unsuccessfulOutcome.value.present = M2AP_UnsuccessfulOutcome__value_PR_M2SetupFailure;
// out = &pdu.choice.unsuccessfulOutcome.value.choice.M2SetupFailure;
//
// /* mandatory */
// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_Cause;
// //ie->criticality = M2AP_Criticality_ignore;
// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_Cause;
//
// //m2ap_eNB_set_cause (&ie->value.choice.Cause, cause_type, cause_value);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional: consider to handle this later */
// ie = (M2AP_M2SetupFailure_Ies_t *)calloc(1, sizeof(M2AP_M2SetupFailure_Ies_t));
// //ie->id = M2AP_ProtocolIE_ID_id_TimeToWait;
// //ie->criticality = M2AP_Criticality_ignore;
// //ie->value.present = M2AP_M2SetupFailure_IEs__value_PR_TimeToWait;
//
// //if (time_to_wait > -1) {
// // ie->value.choice.TimeToWait = time_to_wait;
// //}
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode M2 setup failure\n");
// return -1;
// }
//
// //MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB,
// // MSC_M2AP_TARGET_ENB, NULL, 0,
// // "0 M2Setup/unsuccessfulOutcome assoc_id %u cause %u value %u",
// // assoc_id, cause_type, cause_value);
//
// m2ap_eNB_itti_send_sctp_data_req(instance, assoc_id, buffer, len, 0);
//
// return ret;
//}
int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value)
{
DevAssert (cause_p != NULL);
cause_p->present = cause_type;
switch (cause_type) {
case M2AP_Cause_PR_radioNetwork:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_transport:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_protocol:
cause_p->choice.misc = cause_value;
break;
case M2AP_Cause_PR_misc:
cause_p->choice.misc = cause_value;
break;
default:
return -1;
}
return 0;
}
//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequest_t *out;
// M2AP_HandoverRequest_IEs_t *ie;
// M2AP_E_RABs_ToBeSetup_ItemIEs_t *e_RABS_ToBeSetup_ItemIEs;
// M2AP_E_RABs_ToBeSetup_Item_t *e_RABs_ToBeSetup_Item;
// M2AP_LastVisitedCell_Item_t *lastVisitedCell_Item;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_reject;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverRequest;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverRequest;
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_Cause;
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork = M2AP_CauseRadioNetwork_handover_desirable_for_radio_reasons;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargetCell_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_ECGI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.ECGI.pLMN_Identity);
// MACRO_ENB_ID_TO_CELL_IDENTITY(m2ap_eNB_data_p->eNB_id, 0, &ie->value.choice.ECGI.eUTRANcellIdentifier);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_GUMMEI_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_GUMMEI;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &ie->value.choice.GUMMEI.gU_Group_ID.pLMN_Identity);
// //@TODO: consider to update these values
// INT16_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_group_id, &ie->value.choice.GUMMEI.gU_Group_ID.mME_Group_ID);
// MME_CODE_TO_OCTET_STRING(m2ap_handover_req->ue_gummei.mme_code, &ie->value.choice.GUMMEI.mME_Code);
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_ContextInformation;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_ContextInformation;
// //@TODO: consider to update this value
// ie->value.choice.UE_ContextInformation.mME_UE_S1AP_ID = m2ap_handover_req->mme_ue_s1ap_id;
//
// KENB_STAR_TO_BIT_STRING(m2ap_handover_req->kenb,&ie->value.choice.UE_ContextInformation.aS_SecurityInformation.key_eNodeB_star);
//
// if (m2ap_handover_req->kenb_ncc >=0) { // Check this condition
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = m2ap_handover_req->kenb_ncc;
// }
// else {
// ie->value.choice.UE_ContextInformation.aS_SecurityInformation.nextHopChainingCount = 1;
// }
//
// ENCRALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.encryption_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.encryptionAlgorithms);
//
// INTPROTALG_TO_BIT_STRING(m2ap_handover_req->security_capabilities.integrity_algorithms,
// &ie->value.choice.UE_ContextInformation.uESecurityCapabilities.integrityProtectionAlgorithms);
//
// //@TODO: update with proper UEAMPR
// UEAGMAXBITRTD_TO_ASN_PRIMITIVES(3L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateDownlink);
// UEAGMAXBITRTU_TO_ASN_PRIMITIVES(6L,&ie->value.choice.UE_ContextInformation.uEaggregateMaximumBitRate.uEaggregateMaximumBitRateUplink);
// {
// for (int i=0;i<m2ap_handover_req->nb_e_rabs_tobesetup;i++) {
// e_RABS_ToBeSetup_ItemIEs = (M2AP_E_RABs_ToBeSetup_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_ToBeSetup_ItemIEs_t));
// e_RABS_ToBeSetup_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_ToBeSetup_Item;
// e_RABS_ToBeSetup_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_ToBeSetup_ItemIEs->value.present = M2AP_E_RABs_ToBeSetup_ItemIEs__value_PR_E_RABs_ToBeSetup_Item;
// e_RABs_ToBeSetup_Item = &e_RABS_ToBeSetup_ItemIEs->value.choice.E_RABs_ToBeSetup_Item;
// {
// e_RABs_ToBeSetup_Item->e_RAB_ID = m2ap_handover_req->e_rabs_tobesetup[i].e_rab_id;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.qCI = m2ap_handover_req->e_rab_param[i].qos.qci;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.priorityLevel = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.priority_level;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionCapability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_capability;
// e_RABs_ToBeSetup_Item->e_RAB_Level_QoS_Parameters.allocationAndRetentionPriority.pre_emptionVulnerability = m2ap_handover_req->e_rab_param[i].qos.allocation_retention_priority.pre_emp_vulnerability;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size = (uint8_t)(m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length/8);
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.bits_unused = m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.length%8;
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf =
// calloc(1,e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// memcpy (e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.buf,
// m2ap_handover_req->e_rabs_tobesetup[i].eNB_addr.buffer,
// e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.transportLayerAddress.size);
//
// INT32_TO_OCTET_STRING(m2ap_handover_req->e_rabs_tobesetup[i].gtp_teid,&e_RABs_ToBeSetup_Item->uL_GTPtunnelEndpoint.gTP_TEID);
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_ContextInformation.e_RABs_ToBeSetup_List.list, e_RABS_ToBeSetup_ItemIEs);
// }
// }
//
// OCTET_STRING_fromBuf(&ie->value.choice.UE_ContextInformation.rRC_Context, (char*) m2ap_handover_req->rrc_buffer, m2ap_handover_req->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequest_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequest_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_UE_HistoryInformation;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequest_IEs__value_PR_UE_HistoryInformation;
// //@TODO: consider to update this value
// {
// lastVisitedCell_Item = (M2AP_LastVisitedCell_Item_t *)calloc(1, sizeof(M2AP_LastVisitedCell_Item_t));
// lastVisitedCell_Item->present = M2AP_LastVisitedCell_Item_PR_e_UTRAN_Cell;
// MCC_MNC_TO_PLMNID(instance_p->mcc, instance_p->mnc, instance_p->mnc_digit_length,
// &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.pLMN_Identity);
// MACRO_ENB_ID_TO_CELL_IDENTITY(0, 0, &lastVisitedCell_Item->choice.e_UTRAN_Cell.global_Cell_ID.eUTRANcellIdentifier);
// lastVisitedCell_Item->choice.e_UTRAN_Cell.cellType.cell_Size = M2AP_Cell_Size_small;
// lastVisitedCell_Item->choice.e_UTRAN_Cell.time_UE_StayedInCell = 2;
// ASN_SEQUENCE_ADD(&ie->value.choice.UE_HistoryInformation.list, lastVisitedCell_Item);
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover request\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverRequestAcknowledge_t *out;
// M2AP_HandoverRequestAcknowledge_IEs_t *ie;
// M2AP_E_RABs_Admitted_ItemIEs_t *e_RABS_Admitted_ItemIEs;
// M2AP_E_RABs_Admitted_Item_t *e_RABs_Admitted_Item;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// ue_id = m2ap_handover_req_ack->m2_id_target;
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP handover message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_successfulOutcome;
// pdu.choice.successfulOutcome.procedureCode = M2AP_ProcedureCode_id_handoverPreparation;
// pdu.choice.successfulOutcome.criticality = M2AP_Criticality_reject;
// pdu.choice.successfulOutcome.value.present = M2AP_SuccessfulOutcome__value_PR_HandoverRequestAcknowledge;
// out = &pdu.choice.successfulOutcome.value.choice.HandoverRequestAcknowledge;
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_List;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_E_RABs_Admitted_List;
//
// {
// for (int i=0;i<m2ap_handover_req_ack->nb_e_rabs_tobesetup;i++) {
// e_RABS_Admitted_ItemIEs = (M2AP_E_RABs_Admitted_ItemIEs_t *)calloc(1,sizeof(M2AP_E_RABs_Admitted_ItemIEs_t));
// e_RABS_Admitted_ItemIEs->id = M2AP_ProtocolIE_ID_id_E_RABs_Admitted_Item;
// e_RABS_Admitted_ItemIEs->criticality = M2AP_Criticality_ignore;
// e_RABS_Admitted_ItemIEs->value.present = M2AP_E_RABs_Admitted_ItemIEs__value_PR_E_RABs_Admitted_Item;
// e_RABs_Admitted_Item = &e_RABS_Admitted_ItemIEs->value.choice.E_RABs_Admitted_Item;
// {
// e_RABs_Admitted_Item->e_RAB_ID = m2ap_handover_req_ack->e_rabs_tobesetup[i].e_rab_id;
// }
// ASN_SEQUENCE_ADD(&ie->value.choice.E_RABs_Admitted_List.list, e_RABS_Admitted_ItemIEs);
// }
// }
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_HandoverRequestAcknowledge_IEs_t *)calloc(1, sizeof(M2AP_HandoverRequestAcknowledge_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_TargeteNBtoSource_eNBTransparentContainer;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverRequestAcknowledge_IEs__value_PR_TargeteNBtoSource_eNBTransparentContainer;
//
// OCTET_STRING_fromBuf(&ie->value.choice.TargeteNBtoSource_eNBTransparentContainer, (char*) m2ap_handover_req_ack->rrc_buffer, m2ap_handover_req_ack->rrc_buffer_size);
//
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 handover response\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2Handover/successfulOutcome assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p, m2ap_ue_context_release_t *m2ap_ue_context_release)
//{
//
// M2AP_M2AP_PDU_t pdu;
// M2AP_UEContextRelease_t *out;
// M2AP_UEContextRelease_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// ue_id = m2ap_find_id_from_rnti(&instance_p->id_manager, m2ap_ue_context_release->rnti);
// if (ue_id == -1) {
// M2AP_ERROR("could not find UE %x\n", m2ap_ue_context_release->rnti);
// exit(1);
// }
// id_source = m2ap_id_get_id_source(&instance_p->id_manager, ue_id);
// id_target = ue_id;
//
// /* Prepare the M2AP ue context relase message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_uEContextRelease;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_UEContextRelease;
// out = &pdu.choice.initiatingMessage.value.choice.UEContextRelease;
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* mandatory */
// ie = (M2AP_UEContextRelease_IEs_t *)calloc(1, sizeof(M2AP_UEContextRelease_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_UEContextRelease_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 UE Context Release\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2UEContextRelease/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
//
//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause)
//{
// M2AP_M2AP_PDU_t pdu;
// M2AP_HandoverCancel_t *out;
// M2AP_HandoverCancel_IEs_t *ie;
// int ue_id;
// int id_source;
// int id_target;
//
// uint8_t *buffer;
// uint32_t len;
// int ret = 0;
//
// DevAssert(instance_p != NULL);
// DevAssert(m2ap_eNB_data_p != NULL);
//
// ue_id = m2_ue_id;
// id_source = ue_id;
// id_target = m2ap_id_get_id_target(&instance_p->id_manager, ue_id);
//
// /* Prepare the M2AP handover cancel message to encode */
// memset(&pdu, 0, sizeof(pdu));
// pdu.present = M2AP_M2AP_PDU_PR_initiatingMessage;
// pdu.choice.initiatingMessage.procedureCode = M2AP_ProcedureCode_id_handoverCancel;
// pdu.choice.initiatingMessage.criticality = M2AP_Criticality_ignore;
// pdu.choice.initiatingMessage.value.present = M2AP_InitiatingMessage__value_PR_HandoverCancel;
// out = &pdu.choice.initiatingMessage.value.choice.HandoverCancel;
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Old_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_reject;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID;
// ie->value.choice.UE_M2AP_ID = id_source;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// /* optional */
// if (id_target != -1) {
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_New_eNB_UE_M2AP_ID;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_UE_M2AP_ID_1;
// ie->value.choice.UE_M2AP_ID_1 = id_target;
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
// }
//
// /* mandatory */
// ie = (M2AP_HandoverCancel_IEs_t *)calloc(1, sizeof(M2AP_HandoverCancel_IEs_t));
// ie->id = M2AP_ProtocolIE_ID_id_Cause;
// ie->criticality = M2AP_Criticality_ignore;
// ie->value.present = M2AP_HandoverCancel_IEs__value_PR_Cause;
// switch (cause) {
// case M2AP_T_RELOC_PREP_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_trelocprep_expiry;
// break;
// case M2AP_TX2_RELOC_OVERALL_TIMEOUT:
// ie->value.choice.Cause.present = M2AP_Cause_PR_radioNetwork;
// ie->value.choice.Cause.choice.radioNetwork =
// M2AP_CauseRadioNetwork_tx2relocoverall_expiry;
// break;
// default:
// /* we can't come here */
// M2AP_ERROR("unhandled cancel cause\n");
// exit(1);
// }
// ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
//
// if (m2ap_eNB_encode_pdu(&pdu, &buffer, &len) < 0) {
// M2AP_ERROR("Failed to encode X2 Handover Cancel\n");
// abort();
// return -1;
// }
//
// MSC_LOG_TX_MESSAGE (MSC_M2AP_SRC_ENB, MSC_M2AP_TARGET_ENB, NULL, 0, "0 X2HandoverCancel/initiatingMessage assoc_id %u", m2ap_eNB_data_p->assoc_id);
//
// m2ap_eNB_itti_send_sctp_data_req(instance_p->instance, m2ap_eNB_data_p->assoc_id, buffer, len, 1);
//
// return ret;
//}
@@ -0,0 +1,63 @@
/*
* 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 m2ap_eNB_generate_messages.h
* \brief m2ap procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_ENB_GENERATE_MESSAGES_H_
#define M2AP_ENB_GENERATE_MESSAGES_H_
#include "m2ap_eNB_defs.h"
#include "m2ap_common.h"
//int m2ap_eNB_generate_m2_setup_request(m2ap_eNB_instance_t *instance_p,
// m2ap_eNB_data_t *m2ap_eNB_data_p);
//
//int m2ap_MCE_generate_m2_setup_response(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p);
//
/*int m2ap_MCE_generate_m2_setup_failure(instance_t instance,
uint32_t assoc_id,
M2AP_Cause_PR cause_type,
long cause_value,
long time_to_wait);*/
int m2ap_eNB_set_cause (M2AP_Cause_t * cause_p,
M2AP_Cause_PR cause_type,
long cause_value);
//int m2ap_eNB_generate_m2_handover_request (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_t *m2ap_handover_req, int ue_id);
//
//int m2ap_eNB_generate_m2_handover_request_ack (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_handover_req_ack_t *m2ap_handover_req_ack);
//
//int m2ap_eNB_generate_m2_ue_context_release (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// m2ap_ue_context_release_t *m2ap_ue_context_release);
//
//int m2ap_eNB_generate_m2_handover_cancel (m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *m2ap_eNB_data_p,
// int m2_ue_id,
// m2ap_handover_cancel_cause_t cause);
#endif /* M2AP_ENB_GENERATE_MESSAGES_H_ */
+123
View File
@@ -0,0 +1,123 @@
/*
* 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 m2ap_eNB_handler.c
* \brief m2ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#include <stdint.h>
#include "intertask_interface.h"
#include "asn1_conversions.h"
#include "m2ap_common.h"
#include "m2ap_eNB_defs.h"
#include "m2ap_eNB_handler.h"
#include "m2ap_decoder.h"
#include "m2ap_ids.h"
#include "m2ap_eNB_management_procedures.h"
#include "m2ap_eNB_generate_messages.h"
//#include "m2ap_MCE_interface_management.h"
#include "m2ap_eNB_interface_management.h"
#include "msc.h"
#include "assertions.h"
#include "conversions.h"
/* Handlers matrix. Only eNB related procedure present here */
m2ap_eNB_message_decoded_callback m2ap_eNB_messages_callback[][3] = {
{ eNB_handle_MBMS_SESSION_START_REQUEST, 0, 0 }, /* MBMSSessionStart */
{ eNB_handle_MBMS_SESSION_STOP_REQUEST, 0, 0 }, /* MBMSSessionStop */
{ eNB_handle_MBMS_SCHEDULING_INFORMATION, 0, 0 }, /* MBMSSchedulingInformation */
{ 0, 0, 0 }, /* Error Indication */
{ 0, 0, 0 }, /* Reset */
{ 0,eNB_handle_M2_SETUP_RESPONSE,eNB_handle_M2_SETUP_FAILURE }, /* M2 Setup */
{ 0, 0, 0 }, /* eNBConfigurationUpdate */
{ 0, 0, 0 }, /* MCEConfigurationUpdate */
{ 0, 0, 0 }, /* privateMessage */
{ 0, 0, 0 }, /* MBMSSessionUpdate */
{ 0, 0, 0 }, /* MBMSServiceCounting */
{ 0, 0, 0 }, /* MBMSServiceCountingResultReport */
{ 0, 0, 0 } /* MBMSOverloadNotification */
};
static char *m2ap_direction2String(int m2ap_dir) {
static char *m2ap_direction_String[] = {
"", /* Nothing */
"Originating message", /* originating message */
"Successfull outcome", /* successfull outcome */
"UnSuccessfull outcome", /* successfull outcome */
};
return(m2ap_direction_String[m2ap_dir]);
}
int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length)
{
M2AP_M2AP_PDU_t pdu;
int ret;
DevAssert(data != NULL);
memset(&pdu, 0, sizeof(pdu));
if (m2ap_decode_pdu(&pdu, data, data_length) < 0) {
LOG_E(M2AP, "Failed to decode PDU\n");
return -1;
}
/* Checking procedure Code and direction of message */
if (pdu.choice.initiatingMessage.procedureCode > sizeof(m2ap_eNB_messages_callback) / (3 * sizeof(
m2ap_message_decoded_callback))
|| (pdu.present > M2AP_M2AP_PDU_PR_unsuccessfulOutcome)) {
LOG_E(M2AP, "[SCTP %d] Either procedureCode %ld or direction %d exceed expected\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode, pdu.present);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* No handler present.
* This can mean not implemented or no procedure for eNB (wrong direction).
*/
if (m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1] == NULL) {
LOG_E(M2AP, "[SCTP %d] No handler for procedureCode %ld in %s\n",
assoc_id, pdu.choice.initiatingMessage.procedureCode,
m2ap_direction2String(pdu.present - 1));
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return -1;
}
/* Calling the right handler */
LOG_I(M2AP, "Calling handler with instance %d\n",instance);
ret = (*m2ap_eNB_messages_callback[pdu.choice.initiatingMessage.procedureCode][pdu.present - 1])
(instance, assoc_id, stream, &pdu);
ASN_STRUCT_FREE_CONTENTS_ONLY(asn_DEF_M2AP_M2AP_PDU, &pdu);
return ret;
}
+43
View File
@@ -0,0 +1,43 @@
/*
* 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 m2ap_handler.h
* \brief m2ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M2AP_ENB_HANDLERS_H_
#define M2AP_ENB_HANDLERS_H_
#include "m2ap_eNB_defs.h"
//void m2ap_handle_m2_setup_message(m2ap_eNB_instance_t *instance_p, m2ap_eNB_data_t *eNB_desc_p, int sctp_shutdown);
int m2ap_eNB_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
const uint8_t * const data, const uint32_t data_length);
//int m2ap_handle_message(instance_t instance, uint32_t assoc_id, int32_t stream,
//const uint8_t * const data, const uint32_t data_length);
#endif /* M2AP_ENB_HANDLERS_H_ */

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