Merge remote-tracking branch 'origin/develop' into nr_csirs_rrc_harmonization
This commit is contained in:
+26
-39
@@ -30,11 +30,15 @@
|
||||
|
||||
|
||||
|
||||
|
||||
import logging
|
||||
import re
|
||||
import subprocess
|
||||
import logging
|
||||
import math
|
||||
import sshconnection
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s"
|
||||
)
|
||||
|
||||
class Log_Mgt:
|
||||
|
||||
@@ -49,40 +53,25 @@ class Log_Mgt:
|
||||
#-----------------$
|
||||
|
||||
|
||||
def __CheckAvailSpace(self):
|
||||
def __CheckUsedSpace(self):
|
||||
HOST=self.Username+'@'+self.IPAddress
|
||||
COMMAND="df "+ self.path
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
result = ssh.stdout.readlines()
|
||||
s=result[1].decode('utf-8').rstrip()#result[1] is the second line with the results we are looking for
|
||||
tmp=s.split()
|
||||
return tmp[3] #return avail space from the line
|
||||
used=s.split()[4] #get 4th field ex: 70%
|
||||
m = re.match('^(\d+)\%',used)
|
||||
if m is not None:
|
||||
return int(m.group(1))
|
||||
|
||||
def __GetOldestFile(self):
|
||||
HOST=self.Username+'@'+self.IPAddress
|
||||
COMMAND="ls -rtl "+ self.path #-rtl will bring oldest file on top
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
result = ssh.stdout.readlines()
|
||||
s=result[1].decode('utf-8').rstrip()
|
||||
tmp=s.split()
|
||||
return tmp[8]#return filename from the line
|
||||
def __RemoveOldest(self):
|
||||
mySSH = sshconnection.SSHConnection()
|
||||
mySSH.open(self.IPAddress, self.Username, self.Password)
|
||||
COMMAND='echo ' + self.Password + ' | sudo -S find ' + self.path + ' -type f -mtime +14 -delete'
|
||||
mySSH.command(COMMAND,'\$',20)
|
||||
mySSH.close()
|
||||
|
||||
|
||||
def __AvgSize(self):
|
||||
HOST=self.Username+'@'+self.IPAddress
|
||||
COMMAND="ls -rtl "+ self.path
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
result = ssh.stdout.readlines()
|
||||
if len(result)>1: #at least 1 file present
|
||||
total_size=0
|
||||
for i in range(1,len(result)):
|
||||
s=result[i].decode('utf-8').rstrip()
|
||||
tmp=s.split()
|
||||
total_size+=int(tmp[4]) #get filesize
|
||||
return math.floor(total_size/(len(result)-1)) #compute average file/artifact size
|
||||
else:#empty,no files
|
||||
return 0
|
||||
|
||||
|
||||
#-----------------$
|
||||
#PUBLIC Methods$
|
||||
@@ -90,17 +79,15 @@ class Log_Mgt:
|
||||
|
||||
|
||||
def LogRotation(self):
|
||||
avail_space =int(self.__CheckAvailSpace())*1000 #avail space in target folder, initially displayed in Gb
|
||||
avg_size=self.__AvgSize() #average size of artifacts in the target folder
|
||||
logging.debug("Avail Space : " + str(avail_space) + " / Artifact Avg Size : " + str(avg_size))
|
||||
if avail_space < 50*avg_size: #reserved space is 50x artifact file ; oldest file will be deleted
|
||||
oldestfile=self.__GetOldestFile()
|
||||
HOST=self.Username+'@'+self.IPAddress
|
||||
COMMAND="echo " + self.Password + " | sudo -S rm "+ self.path + "/" + oldestfile
|
||||
logging.debug(COMMAND)
|
||||
ssh = subprocess.Popen(["ssh", "%s" % HOST, COMMAND],shell=False,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
used_space = self.__CheckUsedSpace() #avail space in target folder
|
||||
if used_space > 80 :
|
||||
logging.debug('\u001B[1;37;41m Used Disk > 80%, on ' + self.Username+'@'+self.IPAddress + '\u001B[0m')
|
||||
logging.debug('\u001B[1;37;41m Removing Artifacts older than 14 days \u001B[0m')
|
||||
self.__RemoveOldest()
|
||||
else:
|
||||
logging.debug("Still some space left for artifacts storage")
|
||||
logging.debug('Used Disk < 80%, on ' + self.Username+'@'+self.IPAddress +', no cleaning required')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -50,10 +50,6 @@ memleak:openair1/PHY/CODING/TESTBENCH/ltetest.c
|
||||
invalidPrintfArgType_sint:openair1/PHY/CODING/TESTBENCH/pdcch_test.c
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// oaisim deprecated, remove?
|
||||
doubleFree:openair3/TEST/oaisim_mme_list_benchmark.c
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// is itti analyzer deprecated
|
||||
nullPointer:common/utils/itti_analyzer/itti_analyzer.c
|
||||
nullPointerRedundantCheck:common/utils/itti_analyzer/libbuffers/buffers.c
|
||||
|
||||
@@ -4,16 +4,14 @@
|
||||
Title : Processing Time (us)
|
||||
ColNames :
|
||||
- Metric
|
||||
- Average
|
||||
- Max
|
||||
- Average vs Reference Deviation (Reference Value ; Acceptability Threshold)
|
||||
- Average; Max; Count
|
||||
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
|
||||
Ref :
|
||||
feprx : 120.0
|
||||
feptx_prec : 8.0
|
||||
feptx_ofdm : 50.0
|
||||
feptx_total : 75.0
|
||||
L1 Tx processing thread 0 : 300.0
|
||||
L1 Tx processing thread 1 : 300.0
|
||||
L1 Tx processing : 300.0
|
||||
DLSCH encoding : 230.0
|
||||
L1 Rx processing : 175.0
|
||||
PUSCH inner-receiver : 100.0
|
||||
@@ -25,8 +23,7 @@ Threshold :
|
||||
feptx_prec : 1.25
|
||||
feptx_ofdm : 1.25
|
||||
feptx_total : 1.25
|
||||
L1 Tx processing thread 0 : 1.25
|
||||
L1 Tx processing thread 1 : 1.25
|
||||
L1 Tx processing : 1.25
|
||||
DLSCH encoding : 1.25
|
||||
L1 Rx processing : 1.25
|
||||
PUSCH inner-receiver : 1.25
|
||||
|
||||
@@ -4,16 +4,14 @@
|
||||
Title : Processing Time (us)
|
||||
ColNames :
|
||||
- Metric
|
||||
- Average
|
||||
- Max
|
||||
- Average vs Reference Deviation (Reference Value ; Acceptability Threshold)
|
||||
- Average; Max; Count
|
||||
- Average vs Reference Deviation (Reference Value; Acceptability Threshold)
|
||||
Ref :
|
||||
feprx : 60.0
|
||||
feptx_prec : 8.0
|
||||
feptx_ofdm : 50.0
|
||||
feptx_total : 75.0
|
||||
L1 Tx processing thread 0 : 300.0
|
||||
L1 Tx processing thread 1 : 300.0
|
||||
L1 Tx processing : 300.0
|
||||
DLSCH encoding : 230.0
|
||||
L1 Rx processing : 175.0
|
||||
PUSCH inner-receiver : 100.0
|
||||
@@ -25,8 +23,7 @@ Threshold :
|
||||
feptx_prec : 1.25
|
||||
feptx_ofdm : 1.25
|
||||
feptx_total : 1.25
|
||||
L1 Tx processing thread 0 : 1.25
|
||||
L1 Tx processing thread 1 : 1.25
|
||||
L1 Tx processing : 1.25
|
||||
DLSCH encoding : 1.25
|
||||
L1 Rx processing : 1.25
|
||||
PUSCH inner-receiver : 1.25
|
||||
|
||||
+6
-8
@@ -478,21 +478,19 @@ class HTMLManagement():
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.write(' <tr bgcolor = "#33CCFF" >\n')
|
||||
self.htmlFile.write(' <th colspan="3">'+ DataLog['ColNames'][0] +'</th>\n')
|
||||
self.htmlFile.write(' <th>' + DataLog['ColNames'][1] + '</th>\n')
|
||||
self.htmlFile.write(' <th>' + DataLog['ColNames'][2] + '</th>\n')
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + '>'+ DataLog['ColNames'][3] +'</th>\n')
|
||||
self.htmlFile.write(' <th colspan="2">' + DataLog['ColNames'][1] + '</th>\n')
|
||||
self.htmlFile.write(' <th colspan=' + str(1+self.htmlUEConnected) + '>'+ DataLog['ColNames'][2] +'</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
|
||||
for k in DataLog['Data']:
|
||||
# TestRow
|
||||
self.htmlFile.write(' <tr>\n')
|
||||
self.htmlFile.write(' <td colspan="3" bgcolor = "lightcyan" >' + k + ' </td>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + DataLog['Data'][k][0] + ' </td>\n')
|
||||
self.htmlFile.write(' <td bgcolor = "lightcyan" >' + DataLog['Data'][k][1] + ' </td>\n')
|
||||
if float(DataLog['Data'][k][2])> DataLog['Threshold'][k]:
|
||||
self.htmlFile.write(' <th bgcolor = "red" >' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
|
||||
self.htmlFile.write(' <td colspan="2" bgcolor = "lightcyan" >' + DataLog['Data'][k][0] + '; ' + DataLog['Data'][k][1] + '; ' + DataLog['Data'][k][2] + ' </td>\n')
|
||||
if float(DataLog['Data'][k][3])> DataLog['Threshold'][k]:
|
||||
self.htmlFile.write(' <th bgcolor = "red" >' + DataLog['Data'][k][3] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
|
||||
else:
|
||||
self.htmlFile.write(' <th bgcolor = "green" ><font color="white">' + DataLog['Data'][k][2] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
|
||||
self.htmlFile.write(' <th bgcolor = "green" ><font color="white">' + DataLog['Data'][k][3] + ' (Ref = ' + str(DataLog['Ref'][k]) + ' ; Thres = ' +str(DataLog['Threshold'][k])+') ' + '</th>\n')
|
||||
self.htmlFile.write(' </tr>\n')
|
||||
self.htmlFile.close()
|
||||
|
||||
|
||||
+5
-3
@@ -1174,17 +1174,19 @@ class RANManagement():
|
||||
datalog_rt_stats['Data']={}
|
||||
if len(real_time_stats)!=0: #check if dictionary is not empty
|
||||
for k in real_time_stats:
|
||||
tmp=re.match(r'^(?P<metric>.*):\s+(?P<avg>\d+\.\d+) us;\s+\d+;\s+(?P<max>\d+\.\d+) us;',real_time_stats[k])
|
||||
tmp=re.match(r'^(?P<metric>.*):\s+(?P<avg>\d+\.\d+) us;\s+(?P<count>\d+);\s+(?P<max>\d+\.\d+) us;',real_time_stats[k])
|
||||
if tmp is not None:
|
||||
metric=tmp.group('metric')
|
||||
avg=float(tmp.group('avg'))
|
||||
max=float(tmp.group('max'))
|
||||
datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])]
|
||||
count=int(tmp.group('count'))
|
||||
datalog_rt_stats['Data'][metric]=["{:.0f}".format(avg),"{:.0f}".format(max),"{:d}".format(count),"{:.2f}".format(avg/datalog_rt_stats['Ref'][metric])]
|
||||
#once all metrics are collected, store the data as a class attribute to build a dedicated HTML table afterward
|
||||
self.datalog_rt_stats=datalog_rt_stats
|
||||
#check if there is a fail => will render the test as failed
|
||||
for k in datalog_rt_stats['Data']:
|
||||
if float(datalog_rt_stats['Data'][k][2])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
|
||||
if float(datalog_rt_stats['Data'][k][3])> datalog_rt_stats['Threshold'][k]: #condition for fail : avg/ref is greater than the fixed threshold
|
||||
logging.debug('\u001B[1;30;43m datalog_rt_stats metric ' + k + '=' + datalog_rt_stats['Data'][k][3] + ' > threshold ' + str(datalog_rt_stats['Threshold'][k]) + ' \u001B[0m')
|
||||
RealTimeProcessingIssue = True
|
||||
else:
|
||||
statMsg = 'No real time stats found in the log file\n'
|
||||
|
||||
@@ -20,8 +20,7 @@ gnb :
|
||||
feptx_prec:
|
||||
feptx_ofdm:
|
||||
feptx_total:
|
||||
L1 Tx processing thread 0:
|
||||
L1 Tx processing thread 1:
|
||||
L1 Tx processing:
|
||||
DLSCH encoding:
|
||||
L1 Rx processing:
|
||||
PUSCH inner-receiver:
|
||||
@@ -40,12 +39,11 @@ gnb :
|
||||
rt.feptx_ofdm:
|
||||
rt.feptx_total:
|
||||
page3:
|
||||
rt.L1 Tx processing thread 0:
|
||||
rt.L1 Tx processing thread 1:
|
||||
rt.L1 Tx processing:
|
||||
rt.DLSCH encoding:
|
||||
rt.L1 Rx processing:
|
||||
page4:
|
||||
rt.PUSCH inner-receiver:
|
||||
rt.PUSCH decoding:
|
||||
rt.DL & UL scheduling timing stats:
|
||||
rt.UL Indication:
|
||||
rt.UL Indication:
|
||||
|
||||
@@ -96,8 +96,8 @@
|
||||
|
||||
<testCase id="072000">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/140Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 140M -t 60</iperf_args>
|
||||
<desc>iperf (DL/200Mbps/UDP)(60 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 200M -t 60</iperf_args>
|
||||
<direction>DL</direction>
|
||||
<id>nrmodule2_quectel</id>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
000001
|
||||
071004
|
||||
000001
|
||||
071005
|
||||
000001
|
||||
011002
|
||||
081000
|
||||
</TestCaseRequestedList>
|
||||
@@ -148,7 +150,16 @@
|
||||
<iperf_bitrate_threshold>90</iperf_bitrate_threshold>
|
||||
<iperf_profile>single-ue</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
<testCase id="071005">
|
||||
<class>Iperf</class>
|
||||
<desc>iperf (DL/130Mbps/UDP)(30 sec)(single-ue profile)</desc>
|
||||
<iperf_args>-u -b 130M -t 30</iperf_args>
|
||||
<direction>DL</direction>
|
||||
<id>nrmodule2_quectel</id>
|
||||
<iperf_packetloss_threshold>50</iperf_packetloss_threshold>
|
||||
<iperf_bitrate_threshold>50</iperf_bitrate_threshold>
|
||||
<iperf_profile>single-ue</iperf_profile>
|
||||
</testCase>
|
||||
|
||||
|
||||
<testCase id="081000">
|
||||
|
||||
+25
-221
@@ -690,19 +690,13 @@ add_list1_option(NB_ANTENNAS_RX "4" "Number of antennas in reception" "1" "2" "4
|
||||
add_list1_option(NB_ANTENNAS_TX "4" "Number of antennas in transmission" "1" "2" "4")
|
||||
|
||||
#NOKIA config enhancement
|
||||
set (CONFIG_ROOTDIR
|
||||
${OPENAIR_DIR}/common/config
|
||||
)
|
||||
set (CONFIG_SOURCES
|
||||
set (CONFIG_ROOTDIR ${OPENAIR_DIR}/common/config)
|
||||
add_library(CONFIG_LIB
|
||||
${CONFIG_ROOTDIR}/config_load_configmodule.c
|
||||
${CONFIG_ROOTDIR}/config_userapi.c
|
||||
${CONFIG_ROOTDIR}/config_cmdline.c
|
||||
)
|
||||
set (CONFIG_LIBCONFIG_SOURCES
|
||||
${CONFIG_ROOTDIR}/libconfig/config_libconfig.c
|
||||
)
|
||||
add_library(CONFIG_LIB ${CONFIG_SOURCES})
|
||||
add_library(params_libconfig MODULE ${CONFIG_LIBCONFIG_SOURCES} )
|
||||
)
|
||||
add_library(params_libconfig MODULE ${CONFIG_ROOTDIR}/libconfig/config_libconfig.c)
|
||||
target_link_libraries(params_libconfig config)
|
||||
# shared library loader
|
||||
set (SHLIB_LOADER_SOURCES
|
||||
@@ -1161,15 +1155,6 @@ set(FSPT_MSG_LIB FSPT_MSG)
|
||||
message("fspt c dir is : ${FSPT_C_DIR}")
|
||||
include_directories (${FSPT_C_DIR})
|
||||
|
||||
# add_library(ASYNC_IF
|
||||
# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/socket_link.c
|
||||
# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/link_manager.c
|
||||
# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/message_queue.c
|
||||
# ${OPENAIR2_DIR}/UTIL/ASYNC_IF/ringbuffer_queue.c
|
||||
# )
|
||||
# set(ASYNC_IF_LIB ASYNC_IF)
|
||||
# include_directories(${OPENAIR2_DIR}/UTIL/ASYNC_IF)
|
||||
|
||||
set(PROTOBUF_LIB "protobuf-c")
|
||||
|
||||
#set(PROTOBUF_LIB "protobuf") #for Cpp
|
||||
@@ -1180,55 +1165,19 @@ add_library(HASHTABLE
|
||||
)
|
||||
include_directories(${OPENAIR_DIR}/common/utils/hashtable)
|
||||
|
||||
set(UTIL_SRC
|
||||
# ${OPENAIR2_DIR}/UTIL/CLI/cli.c
|
||||
# ${OPENAIR2_DIR}/UTIL/CLI/cli_cmd.c
|
||||
# ${OPENAIR2_DIR}/UTIL/CLI/cli_server.c
|
||||
${OPENAIR2_DIR}/UTIL/FIFO/pad_list.c
|
||||
add_library(UTIL
|
||||
${OPENAIR2_DIR}/UTIL/LISTS/list.c
|
||||
${OPENAIR2_DIR}/UTIL/LISTS/list2.c
|
||||
${OPENAIR_DIR}/common/utils/LOG/log.c
|
||||
${OPENAIR_DIR}/common/utils/LOG/vcd_signal_dumper.c
|
||||
${OPENAIR2_DIR}/UTIL/MATH/oml.c
|
||||
# ${OPENAIR2_DIR}/UTIL/MEM/mem_block.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OCG/OCG.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OCG/OCG_create_dir.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OCG/OCG_detect_file.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OCG/OCG_generate_report.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_filename.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OCG/OCG_parse_XML.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OCG/OCG_save_XML.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/common.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/grid.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/job.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/mobility_parser.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/omg.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/omg_hashtable.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/rwalk.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/rwp.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/static.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/steadystaterwp.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/trace.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/trace_hashtable.c
|
||||
${OPENAIR2_DIR}/UTIL/OPT/probe.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OTG/otg_tx.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OTG/otg.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OTG/otg_kpi.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OTG/otg_models.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OTG/otg_form.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OTG/otg_rx.c
|
||||
)
|
||||
add_library(UTIL ${UTIL_SRC})
|
||||
add_dependencies(UTIL rrc_flag)
|
||||
|
||||
#set(OMG_SUMO_SRC
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/client_traci_OMG.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/id_manager.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/sumo.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/socket_traci_OMG.c
|
||||
# ${OPENAIR2_DIR}/UTIL/OMG/storage_traci_OMG.c
|
||||
# )
|
||||
#add_library(OMG_SUMO ${OMG_SUMO_SRC})
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||
${OPENAIR_DIR}/common/utils/time_meas.c
|
||||
)
|
||||
|
||||
set(SECU_OSA_SRC
|
||||
${OPENAIR2_DIR}/UTIL/OSA/osa_key_deriver.c
|
||||
@@ -1491,7 +1440,6 @@ set(PHY_SRC_COMMON
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
|
||||
)
|
||||
|
||||
@@ -1628,7 +1576,6 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
|
||||
${PHY_POLARSRC}
|
||||
${PHY_SMALLBLOCKSRC}
|
||||
@@ -1682,7 +1629,6 @@ set(PHY_SRC_UE
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/signal_energy.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/dB_routines.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/sqrt.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/time_meas.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lut.c
|
||||
${OPENAIR1_DIR}/PHY/INIT/nr_init_ue.c
|
||||
# ${OPENAIR1_DIR}/SIMULATION/NR_UE_PHY/unit_tests/src/pucch_uci_test.c
|
||||
@@ -1910,6 +1856,7 @@ set(NR_L2_SRC_UE
|
||||
${NR_SDAP_SRC}
|
||||
${NR_UE_RRC_DIR}/L2_interface_ue.c
|
||||
${NR_UE_RRC_DIR}/main_ue.c
|
||||
${NR_RRC_DIR}/nr_rrc_config.c
|
||||
${NR_UE_RRC_DIR}/rrc_UE.c
|
||||
${NR_UE_RRC_DIR}/rrc_nsa.c
|
||||
${NR_RRC_DIR}/nr_rrc_config.c
|
||||
@@ -2602,7 +2549,7 @@ add_library(minimal_lib
|
||||
${OPENAIR_DIR}/common/utils/minimal_stub.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries(minimal_lib pthread dl ${T_LIB} ${CONFIG_LIB})
|
||||
target_link_libraries(minimal_lib pthread dl ${T_LIB} CONFIG_LIB)
|
||||
|
||||
add_executable(nfapi_test
|
||||
${OPENAIR_DIR}/openair2/NR_PHY_INTERFACE/nfapi_5g_test.c
|
||||
@@ -2631,7 +2578,6 @@ add_executable(lte-softmodem
|
||||
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
|
||||
${OPENAIR_TARGETS}/RT/USER/ru_control.c
|
||||
${OPENAIR_TARGETS}/RT/USER/lte-softmodem.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR2_DIR}/ENB_APP/NB_IoT_interface.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
@@ -2646,14 +2592,11 @@ add_executable(lte-softmodem
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
add_dependencies(lte-softmodem rrc_flag s1ap_flag x2_flag oai_iqplayer)
|
||||
@@ -2666,14 +2609,13 @@ target_link_libraries (lte-softmodem
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (lte-softmodem ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries (lte-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
|
||||
target_link_libraries (lte-softmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES})
|
||||
target_link_libraries (lte-softmodem ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (lte-softmodem ${T_LIB})
|
||||
|
||||
|
||||
add_executable(ocp-enb
|
||||
${OPENAIR_DIR}/executables/main-ocp.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR_DIR}/executables/main-fs6.c
|
||||
${OPENAIR_DIR}/executables/transport_split.c
|
||||
@@ -2689,14 +2631,11 @@ add_executable(ocp-enb
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_libconfig rfsimulator)
|
||||
@@ -2708,7 +2647,7 @@ target_link_libraries (ocp-enb
|
||||
PHY_COMMON PHY PHY_RU LFDS L2 L2_LTE NFAPI_COMMON_LIB NFAPI_LIB MISC_NFAPI_LTE_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB LFDS7 SIMU_COMMON
|
||||
${RAL_LIB} ${NAS_UE_LIB} ITTI ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} ${FLEXRAN_AGENT_LIB} ${FSPT_MSG_LIB}
|
||||
-Wl,--end-group z dl)
|
||||
target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m ${CONFIG_LIBRARIES} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
|
||||
target_link_libraries (ocp-enb ${LIBXML2_LIBRARIES} pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${LIB_LMS_LIBRARIES} ${T_LIB})
|
||||
|
||||
add_executable(oairu
|
||||
${OPENAIR_TARGETS}/RT/USER/lte-ru.c
|
||||
@@ -2717,23 +2656,18 @@ add_executable(oairu
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR_DIR}/openair1/SCHED/phy_procedures_lte_common.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/executables/main_ru.c
|
||||
${T_SOURCE}
|
||||
${OPENAIR_DIR}/common/utils/LOG/log.c
|
||||
${CONFIG_SOURCES}
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
target_link_libraries (oairu
|
||||
-Wl,--start-group
|
||||
SCHED_RU_LIB
|
||||
PHY_COMMON PHY_RU
|
||||
PHY_COMMON PHY_RU UTIL
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (oairu pthread m ${CONFIG_LIB} rt ${CMAKE_DL_LIBS} ${T_LIB})
|
||||
target_link_libraries (oairu pthread m CONFIG_LIB rt ${CMAKE_DL_LIBS} ${T_LIB})
|
||||
|
||||
|
||||
# lte-uesoftmodem is UE implementation
|
||||
@@ -2752,13 +2686,10 @@ add_executable(lte-uesoftmodem
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/multicast_link.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/socket.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
|
||||
@@ -2776,7 +2707,7 @@ target_link_libraries (lte-uesoftmodem
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (lte-uesoftmodem ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries (lte-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (lte-uesoftmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (lte-uesoftmodem ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (lte-uesoftmodem ${T_LIB})
|
||||
|
||||
@@ -2789,7 +2720,6 @@ add_executable(nr-softmodem
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_DIR}/executables/nr-gnb.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/executables/nr-ru.c
|
||||
${OPENAIR_DIR}/executables/nr-softmodem.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
@@ -2799,15 +2729,12 @@ add_executable(nr-softmodem
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c
|
||||
)
|
||||
@@ -2821,52 +2748,12 @@ target_link_libraries (nr-softmodem
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (nr-softmodem ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries (nr-softmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (nr-softmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (nr-softmodem ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (nr-softmodem ${T_LIB})
|
||||
|
||||
add_dependencies( nr-softmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
|
||||
|
||||
add_executable(ocp-gnb
|
||||
${rrc_h}
|
||||
${nr_rrc_h}
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_DIR}/executables/ocp-gnb.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/record_player.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${XFORMS_SOURCE_NR}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
)
|
||||
|
||||
target_link_libraries (ocp-gnb
|
||||
-Wl,--start-group
|
||||
UTIL HASHTABLE SCTP_CLIENT SCHED_LIB SCHED_RU_LIB SCHED_NR_LIB PHY_NR PHY PHY_COMMON PHY_NR_COMMON PHY_RU LFDS GTPV1U SECU_CN SECU_OSA
|
||||
ITTI ${FLPT_MSG_LIB} ${ASYNC_IF_LIB} LFDS7 ${RAL_LIB} ${NAS_UE_LIB} RRC_LIB NR_RRC_LIB
|
||||
NGAP_LIB NGAP_GNB S1AP_LIB S1AP_ENB L2_LTE_NR L2_NR MAC_NR_COMMON NFAPI_COMMON_LIB NFAPI_LIB NFAPI_VNF_LIB NFAPI_PNF_LIB NFAPI_USER_LIB
|
||||
X2AP_LIB X2AP_ENB F1AP_LIB F1AP M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB SIMU_COMMON
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (ocp-gnb ${LIBXML2_LIBRARIES} )
|
||||
target_link_libraries (ocp-gnb pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (ocp-gnb ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (ocp-gnb ${T_LIB})
|
||||
add_dependencies(ocp-gnb ldpc_orig ldpc_optim ldpc_optim8seg ldpc params_libconfig rfsimulator oai_usrpdevif rfsimulator nrscope)
|
||||
|
||||
|
||||
# nr-uesoftmodem is UE implementation
|
||||
#######################################
|
||||
|
||||
@@ -2874,7 +2761,6 @@ add_executable(nr-uesoftmodem
|
||||
${rrc_h}
|
||||
${s1ap_h}
|
||||
# ${OPENAIR_BIN_DIR}/messages_xml.h
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/executables/nr-uesoftmodem.c
|
||||
${OPENAIR_DIR}/executables/nr-ue.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
@@ -2886,13 +2772,9 @@ add_executable(nr-uesoftmodem
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
${UTIL_SRC}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
|
||||
@@ -2907,7 +2789,7 @@ target_link_libraries (nr-uesoftmodem
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (nr-uesoftmodem ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (nr-uesoftmodem ${T_LIB})
|
||||
|
||||
@@ -2915,7 +2797,6 @@ add_dependencies( nr-uesoftmodem ldpc_orig ldpc_optim ldpc_optim8seg ldpc )
|
||||
if (CUDA_FOUND)
|
||||
add_dependencies( nr-uesoftmodem ldpc_cuda)
|
||||
add_dependencies( nr-softmodem ldpc_cuda)
|
||||
add_dependencies( ocp-gnb ldpc_cuda)
|
||||
endif (CUDA_FOUND)
|
||||
###################################"
|
||||
# Addexecutables for tests
|
||||
@@ -2929,30 +2810,25 @@ endif (CUDA_FOUND)
|
||||
add_executable(dlsim_tm4
|
||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/dlsim_tm4.c
|
||||
${OPENAIR1_DIR}/PHY/TOOLS/lte_phy_scope_tm4.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${T_SOURCE}
|
||||
)
|
||||
target_link_libraries (dlsim_tm4
|
||||
-Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB PHY LFDS ITTI -Wl,--end-group
|
||||
pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${T_LIB}
|
||||
pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES} ${T_LIB}
|
||||
)
|
||||
|
||||
add_executable(rftest
|
||||
${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_test.c
|
||||
${OPENAIR_DIR}/openair1/PHY/TOOLS/calibration_scope.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_TARGETS}/ARCH/COMMON/common_lib.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
target_link_libraries(rftest minimal_lib PHY_NR_COMMON pthread dl m forms ${T_LIB} )
|
||||
target_link_libraries(rftest minimal_lib CONFIG_LIB PHY_NR_COMMON UTIL pthread dl m forms ${T_LIB} )
|
||||
|
||||
add_executable(polartest
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/polartest.c
|
||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -2963,9 +2839,7 @@ target_link_libraries(polartest
|
||||
|
||||
add_executable(smallblocktest
|
||||
${OPENAIR1_DIR}/PHY/CODING/TESTBENCH/smallblocktest.c
|
||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -2995,11 +2869,7 @@ target_link_libraries(ldpctest
|
||||
|
||||
add_executable(nr_dlschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlschsim.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -3010,11 +2880,7 @@ target_link_libraries(nr_dlschsim
|
||||
|
||||
add_executable(nr_pbchsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pbchsim.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -3026,12 +2892,7 @@ target_link_libraries(nr_pbchsim
|
||||
#PUCCH ---> Prashanth
|
||||
add_executable(nr_pucchsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/pucchsim.c
|
||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -3042,17 +2903,13 @@ target_link_libraries(nr_pucchsim
|
||||
|
||||
add_executable(nr_dlsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/dlsim.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${NR_UE_RRC_DIR}/rrc_nsa.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -3064,17 +2921,13 @@ target_compile_definitions(nr_dlsim PUBLIC -DPHYSICAL_SIMULATOR)
|
||||
|
||||
add_executable(nr_prachsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/prachsim.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${NR_UE_RRC_DIR}/rrc_nsa.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES})
|
||||
target_link_libraries(nr_prachsim
|
||||
@@ -3083,12 +2936,8 @@ target_link_libraries(nr_prachsim
|
||||
|
||||
add_executable(nr_ulschsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulschsim.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -3099,9 +2948,6 @@ target_link_libraries(nr_ulschsim
|
||||
|
||||
add_executable(nr_ulsim
|
||||
${OPENAIR1_DIR}/SIMULATION/NR_PHY/ulsim.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/executables/softmodem-common.c
|
||||
${OPENAIR2_DIR}/RRC/NAS/nas_config.c
|
||||
@@ -3109,7 +2955,6 @@ add_executable(nr_ulsim
|
||||
${NR_UE_RRC_DIR}/rrc_nsa.c
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
${PHY_INTERFACE_DIR}/queue_t.c
|
||||
${UTIL_SRC}
|
||||
${T_SOURCE}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
@@ -3123,58 +2968,21 @@ foreach(myExe dlsim dlsim_tm7 ulsim pbchsim scansim mbmssim pdcchsim pucchsim pr
|
||||
|
||||
add_executable(${myExe}
|
||||
${OPENAIR1_DIR}/SIMULATION/LTE_PHY/${myExe}.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/common/utils/backtrace.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${OPENAIR1_DIR}/PHY/INIT/lte_param_init.c
|
||||
${XFORMS_SOURCE}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
${NFAPI_USER_DIR}/nfapi.c
|
||||
)
|
||||
target_link_libraries (${myExe}
|
||||
-Wl,--start-group SIMU_COMMON SIMU UTIL SCHED_LIB SCHED_RU_LIB SCHED_UE_LIB PHY_COMMON PHY_NR_COMMON PHY PHY_UE PHY_RU LFDS ITTI LFDS7 -Wl,--end-group
|
||||
pthread m rt ${CONFIG_LIB} ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl
|
||||
pthread m rt CONFIG_LIB ${ATLAS_LIBRARIES} ${XFORMS_LIBRARIES} ${T_LIB} dl
|
||||
)
|
||||
|
||||
endforeach(myExe)
|
||||
|
||||
add_executable(test_epc_generate_scenario
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/generate_scenario.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/generate_scenario.h
|
||||
${OPENAIR2_DIR}/ENB_APP/enb_config.h
|
||||
${OPENAIR2_DIR}/COMMON/commonDef.h
|
||||
${OPENAIR2_DIR}/COMMON/messages_def.h
|
||||
${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 M2AP_LIB M2AP_ENB M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB PHY LFDS ITTI L2 -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
|
||||
)
|
||||
|
||||
add_executable(test_epc_play_scenario
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_decode.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_display.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_fsm.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_parse.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap_compare_ie.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_s1ap_eNB_defs.h
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario_sctp.c
|
||||
${OPENAIR3_DIR}/TEST/EPC_TEST/play_scenario.h
|
||||
${OPENAIR2_DIR}/COMMON/commonDef.h
|
||||
${OPENAIR2_DIR}/COMMON/messages_def.h
|
||||
)
|
||||
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 M3AP_LIB M3AP_ENB F1AP_LIB F1AP GTPV1U LIB_NAS_UE SECU_CN UTIL HASHTABLE SCTP_CLIENT MME_APP SCHED_LIB PHY_NR_COMMON PHY_COMMON PHY PHY_UE LFDS ITTI -Wl,--end-group pthread m rt crypt sctp ${LIBXML2_LIBRARIES} ${LIBXSLT_LIBRARIES} ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
|
||||
)
|
||||
|
||||
|
||||
#unitary tests for Core NEtwork pieces
|
||||
#################################
|
||||
foreach(myExe s1ap
|
||||
@@ -3191,7 +2999,7 @@ foreach(myExe s1ap
|
||||
${OPENAIR3_DIR}/TEST/test_${myExe}.c
|
||||
)
|
||||
target_link_libraries (test_${myExe}
|
||||
-Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${CONFIG_LIB}
|
||||
-Wl,--start-group SECU_CN UTIL LFDS -Wl,--end-group m rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} CONFIG_LIB
|
||||
)
|
||||
endforeach(myExe)
|
||||
|
||||
@@ -3310,16 +3118,12 @@ add_executable(nr-ittisim
|
||||
${OPENAIR2_DIR}/RRC/NAS/rb_config.c
|
||||
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
|
||||
${OPENAIR3_DIR}/NAS/UE/nas_ue_task.c
|
||||
${OPENAIR_DIR}/common/utils/utils.c
|
||||
${OPENAIR_DIR}/common/utils/system.c
|
||||
${OPENAIR_DIR}/common/utils/nr/nr_common.c
|
||||
${OPENAIR_DIR}/common/utils/threadPool/thread-pool.c
|
||||
${OPENAIR_DIR}/common/utils/lte/ue_power.c
|
||||
${OPENAIR_DIR}/common/utils/lte/prach_utils.c
|
||||
${OPENAIR2_DIR}/ENB_APP/flexran_agent_ran_api_to_fix.c
|
||||
${XFORMSINTERFACE_SOURCE}
|
||||
${T_SOURCE}
|
||||
${CONFIG_SOURCES}
|
||||
${SHLIB_LOADER_SOURCES}
|
||||
)
|
||||
|
||||
@@ -3333,7 +3137,7 @@ target_link_libraries (nr-ittisim
|
||||
-Wl,--end-group z dl)
|
||||
|
||||
target_link_libraries (nr-ittisim ${LIBXML2_LIBRARIES})
|
||||
target_link_libraries (nr-ittisim pthread m ${CONFIG_LIB} rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (nr-ittisim pthread m CONFIG_LIB rt crypt ${CRYPTO_LIBRARIES} ${OPENSSL_LIBRARIES} ${NETTLE_LIBRARIES} sctp ${XFORMS_LIBRARIES} ${PROTOBUF_LIB} ${CMAKE_DL_LIBS} ${LIBYAML_LIBRARIES} ${ATLAS_LIBRARIES})
|
||||
target_link_libraries (nr-ittisim ${LIB_LMS_LIBRARIES})
|
||||
target_link_libraries (nr-ittisim ${T_LIB})
|
||||
|
||||
|
||||
@@ -1093,17 +1093,18 @@
|
||||
(Test8: 217 PRB 100 PDSCH-PRBs 110 PDSCH-Offset),
|
||||
(Test9: 106 PRBs 50 PDSCH-PRBs MCS Index 27),
|
||||
(Test10: 106 PRBs 50 PDSCH-PRBs MCS Index 16),
|
||||
(Test11: HARQ test 25% TP (4 rounds),
|
||||
(Test12: HARQ test 33% TP (3 rounds),
|
||||
(Test13: HARQ test 50% TP (2 rounds),
|
||||
(Test14: 3 PTRS, 8 Interpolated Symbols),
|
||||
(Test15: 6 PTRS, 5 Interpolated Symbols),
|
||||
(Test16: 11 PTRS, 0 Interpolated Symbols),
|
||||
(Test17: Mapping type A, 2 DMRS Symbols),
|
||||
(Test18: Mapping type A, 3 DMRS Symbols),
|
||||
(Test19: Mapping type B, 4 DMRS Symbols),
|
||||
(Test20: 4x4 MIMO, 1 Layer),
|
||||
(Test21: 4x4 MIMO, 2 Layers)</desc>
|
||||
(Test11: 106 MCS-TABLE 256 QAM MCS Index 26),
|
||||
(Test12: HARQ test 25% TP (4 rounds),
|
||||
(Test13: HARQ test 33% TP (3 rounds),
|
||||
(Test14: HARQ test 50% TP (2 rounds),
|
||||
(Test15: 3 PTRS, 8 Interpolated Symbols),
|
||||
(Test16: 6 PTRS, 5 Interpolated Symbols),
|
||||
(Test17: 11 PTRS, 0 Interpolated Symbols),
|
||||
(Test18: Mapping type A, 2 DMRS Symbols),
|
||||
(Test19: Mapping type A, 3 DMRS Symbols),
|
||||
(Test20: Mapping type B, 4 DMRS Symbols),
|
||||
(Test21: 4x4 MIMO, 1 Layer),
|
||||
(Test22: 4x4 MIMO, 2 Layers)</desc>
|
||||
<pre_compile_prog></pre_compile_prog>
|
||||
<compile_prog>$OPENAIR_DIR/cmake_targets/build_oai</compile_prog>
|
||||
<compile_prog_args> --phy_simulators -c </compile_prog_args>
|
||||
@@ -1118,8 +1119,9 @@
|
||||
-n100 -R217 -b100 -s5
|
||||
-n100 -R217 -a80 -s5
|
||||
-n100 -R217 -a110 -s5 -b100
|
||||
-n100 -e27 -s30
|
||||
-n100 -e16 -s10
|
||||
-n100 -e27 -s30
|
||||
-n100 -e16 -s10
|
||||
-n100 -q1 -e27 -s30
|
||||
-n100 -s1 -t25
|
||||
-n100 -s1 -t33
|
||||
-n100 -s1 -t50
|
||||
@@ -1131,7 +1133,7 @@
|
||||
-n100 -s2 -U 2 1 3
|
||||
-n10 -s20 -U 3 0 0 2 -gR -x1 -y4 -z4
|
||||
-n10 -s20 -U 3 0 0 2 -gR -x2 -y4 -z4</main_exec_args>
|
||||
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21</tags>
|
||||
<tags>nr_dlsim.test1 nr_dlsim.test2 nr_dlsim.test3 nr_dlsim.test4 nr_dlsim.test5 nr_dlsim.test6 nr_dlsim.test7 nr_dlsim.test8 nr_dlsim.test9 nr_dlsim.test10 nr_dlsim.test11 nr_dlsim.test12 nr_dlsim.test13 nr_dlsim.test14 nr_dlsim.test15 nr_dlsim.test16 nr_dlsim.test17 nr_dlsim.test18 nr_dlsim.test19 nr_dlsim.test20 nr_dlsim.test21 nr_dlsim.test22</tags>
|
||||
<search_expr_true>PDSCH test OK</search_expr_true>
|
||||
<search_expr_false>segmentation fault|assertion|exiting|fatal</search_expr_false>
|
||||
<nruns>3</nruns>
|
||||
|
||||
@@ -473,130 +473,6 @@ int32_t write_file_matlab(const char *fname, const char *vname, void *data, int
|
||||
|
||||
/* @}*/
|
||||
|
||||
static __inline__ uint64_t rdtsc(void) {
|
||||
uint32_t a, d;
|
||||
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
|
||||
return (((uint64_t)d)<<32) | ((uint64_t)a);
|
||||
}
|
||||
|
||||
#define DEBUG_REALTIME 1
|
||||
#if DEBUG_REALTIME
|
||||
|
||||
extern double cpuf;
|
||||
|
||||
static inline uint64_t checkTCPU(int timeout,
|
||||
char *file,
|
||||
int line)
|
||||
{
|
||||
static uint64_t __thread lastCPUTime=0;
|
||||
static uint64_t __thread last=0;
|
||||
uint64_t cur=rdtsc();
|
||||
struct timespec CPUt;
|
||||
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &CPUt);
|
||||
uint64_t CPUTime=CPUt.tv_sec*1000*1000+CPUt.tv_nsec/1000;
|
||||
double microCycles=(double)(cpuf*1000);
|
||||
int duration=(int)((cur-last)/microCycles);
|
||||
|
||||
if ( last!=0 && duration > timeout ) {
|
||||
//struct timespec ts;
|
||||
//clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
printf("%s:%d lte-ue delay %d (exceed %d), CPU for this period: %lld\n", file, line,
|
||||
duration, timeout, (long long)CPUTime-lastCPUTime );
|
||||
}
|
||||
|
||||
last=cur;
|
||||
lastCPUTime=CPUTime;
|
||||
return cur;
|
||||
}
|
||||
|
||||
static inline unsigned long long checkT(int timeout,
|
||||
char *file,
|
||||
int line)
|
||||
{
|
||||
static unsigned long long __thread last=0;
|
||||
unsigned long long cur=rdtsc();
|
||||
int microCycles=(int)(cpuf*1000);
|
||||
int duration=(int)((cur-last)/microCycles);
|
||||
|
||||
if ( last!=0 && duration > timeout )
|
||||
printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line,
|
||||
duration, timeout);
|
||||
|
||||
last=cur;
|
||||
return cur;
|
||||
}
|
||||
|
||||
typedef struct m {
|
||||
uint64_t iterations;
|
||||
uint64_t sum;
|
||||
uint64_t maxArray[11];
|
||||
} Meas;
|
||||
|
||||
static inline void printMeas(char *txt,
|
||||
Meas *M,
|
||||
int period)
|
||||
{
|
||||
if (M->iterations%period == 0 ) {
|
||||
char txt2[512];
|
||||
sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%"
|
||||
PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n",
|
||||
txt,
|
||||
M->sum/M->iterations,
|
||||
M->iterations,
|
||||
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5],
|
||||
M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
|
||||
#if T_TRACER
|
||||
LOG_W(PHY,"%s",txt2);
|
||||
#else
|
||||
printf("%s",txt2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static inline int cmpint(const void *a,
|
||||
const void *b)
|
||||
{
|
||||
uint64_t *aa=(uint64_t *)a;
|
||||
uint64_t *bb=(uint64_t *)b;
|
||||
return (int)(*aa-*bb);
|
||||
}
|
||||
|
||||
static inline void updateTimes(uint64_t start,
|
||||
Meas *M,
|
||||
int period,
|
||||
char *txt)
|
||||
{
|
||||
if (start!=0) {
|
||||
uint64_t end=rdtsc();
|
||||
long long diff=(end-start)/(cpuf*1000);
|
||||
M->maxArray[0]=diff;
|
||||
M->sum+=diff;
|
||||
M->iterations++;
|
||||
qsort(M->maxArray, 11, sizeof(uint64_t), cmpint);
|
||||
printMeas(txt,M,period);
|
||||
}
|
||||
}
|
||||
|
||||
#define check(a) do { checkT(a,__FILE__,__LINE__); } while (0)
|
||||
#define checkcpu(a) do { checkTCPU(a,__FILE__,__LINE__); } while (0)
|
||||
#define initRefTimes(a) static __thread Meas a= {0}
|
||||
#define pickTime(a) uint64_t a=rdtsc()
|
||||
#define readTime(a) a
|
||||
#define initStaticTime(a) static __thread uint64_t a={0}
|
||||
#define pickStaticTime(a) do { a=rdtsc(); } while (0)
|
||||
|
||||
#else
|
||||
#define check(a) do {} while (0)
|
||||
#define checkcpu(a) do {} while (0)
|
||||
#define initRefTimes(a) do {} while (0)
|
||||
#define initStaticTime(a) do {} while (0)
|
||||
#define pickTime(a) do {} while (0)
|
||||
#define readTime(a) 0
|
||||
#define pickStaticTime(a) do {} while (0)
|
||||
#define updateTimes(a,b,c,d) do {} while (0)
|
||||
#define printMeas(a,b,c) do {} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -36,6 +36,27 @@
|
||||
|
||||
const char *duplex_mode[]={"FDD","TDD"};
|
||||
|
||||
int tables_5_3_2[5][11] = {
|
||||
{25, 52, 79, 106, 133, 160, 216, 270, -1, -1, -1}, // 15 FR1
|
||||
{11, 24, 38, 51, 65, 78, 106, 133, 162, 217, 273}, // 30 FR1
|
||||
{-1, 11, 18, 24, 31, 38, 51, 65, 79, 107, 135}, // 60 FR1
|
||||
{66, 132, 264, -1 , -1, -1, -1, -1, -1, -1, -1}, // 60 FR2
|
||||
{32, 66, 132, 264, -1, -1, -1, -1, -1, -1, -1} // 120FR2
|
||||
};
|
||||
|
||||
int get_supported_band_index(int scs, int band, int n_rbs){
|
||||
|
||||
int scs_index = scs;
|
||||
if (band>256)
|
||||
scs_index++;
|
||||
for (int i=0; i<11; i++) {
|
||||
if(n_rbs == tables_5_3_2[scs][i])
|
||||
return i;
|
||||
}
|
||||
return (-1); // not found
|
||||
}
|
||||
|
||||
|
||||
// Table 5.2-1 NR operating bands in FR1 & FR2 (3GPP TS 38.101)
|
||||
// Table 5.4.2.3-1 Applicable NR-ARFCN per operating band in FR1 & FR2 (3GPP TS 38.101)
|
||||
// Notes:
|
||||
|
||||
@@ -80,6 +80,7 @@ void SLIV2SL(int SLIV,int *S,int *L);
|
||||
int get_dmrs_port(int nl, uint16_t dmrs_ports);
|
||||
uint16_t SL_to_bitmap(int startSymbolIndex, int nrOfSymbols);
|
||||
int get_nb_periods_per_frame(uint8_t tdd_period);
|
||||
int get_supported_band_index(int scs, int band, int n_rbs);
|
||||
long rrc_get_max_nr_csrs(uint8_t max_rbs, long b_SRS);
|
||||
|
||||
#define CEILIDIV(a,b) ((a+b-1)/b)
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
|
||||
static char *grouptypes[] = {"ltestats","cpustats"};
|
||||
static double cpufreq;
|
||||
extern notifiedFIFO_t measur_fifo;
|
||||
#define TELNET_NUM_MEASURTYPES (sizeof(grouptypes)/sizeof(char *))
|
||||
|
||||
#define HDR "---------------------------------"
|
||||
|
||||
@@ -43,9 +43,9 @@ int main(int argc, char *argv[]) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint64_t deb=rdtsc();
|
||||
uint64_t deb=rdtsc_oai();
|
||||
usleep(100000);
|
||||
cpuCyclesMicroSec=(rdtsc()-deb)/100000;
|
||||
cpuCyclesMicroSec=(rdtsc_oai()-deb)/100000;
|
||||
printf("Cycles per µs: %lu\n",cpuCyclesMicroSec);
|
||||
printf("Key" SEP "delay to process" SEP "processing time" SEP "delay to be read answer\n");
|
||||
notifiedFIFO_elt_t doneRequest;
|
||||
|
||||
@@ -72,11 +72,11 @@ void *one_thread(void *arg) {
|
||||
do {
|
||||
notifiedFIFO_elt_t *elt=pullNotifiedFifoRemember(&tp->incomingFifo, myThread);
|
||||
|
||||
if (tp->measurePerf) elt->startProcessingTime=rdtsc();
|
||||
if (tp->measurePerf) elt->startProcessingTime=rdtsc_oai();
|
||||
|
||||
elt->processingFunc(NotifiedFifoData(elt));
|
||||
|
||||
if (tp->measurePerf) elt->endProcessingTime=rdtsc();
|
||||
if (tp->measurePerf) elt->endProcessingTime=rdtsc_oai();
|
||||
|
||||
if (elt->reponseFifo) {
|
||||
// Check if the job is still alive, else it has been aborted
|
||||
@@ -97,7 +97,7 @@ void initNamedTpool(char *params,tpool_t *pool, bool performanceMeas, char *name
|
||||
char *measr=getenv("threadPoolMeasurements");
|
||||
pool->measurePerf=performanceMeas;
|
||||
// force measurement if the output is defined
|
||||
pool->measurePerf=measr!=NULL;
|
||||
pool->measurePerf |= measr!=NULL;
|
||||
|
||||
if (measr) {
|
||||
mkfifo(measr,0666);
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <assertions.h>
|
||||
#include <LOG/log.h>
|
||||
#include <common/utils/system.h>
|
||||
//#include <stdatomic.h>
|
||||
#include "assertions.h"
|
||||
#include "common/utils/time_meas.h"
|
||||
#include "common/utils/system.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define THREADINIT PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
|
||||
@@ -60,10 +60,10 @@ typedef struct notifiedFIFO_elt_s {
|
||||
struct notifiedFIFO_s *reponseFifo;
|
||||
void (*processingFunc)(void *);
|
||||
bool malloced;
|
||||
uint64_t creationTime;
|
||||
uint64_t startProcessingTime;
|
||||
uint64_t endProcessingTime;
|
||||
uint64_t returnTime;
|
||||
oai_cputime_t creationTime;
|
||||
oai_cputime_t startProcessingTime;
|
||||
oai_cputime_t endProcessingTime;
|
||||
oai_cputime_t returnTime;
|
||||
void *msgData;
|
||||
} notifiedFIFO_elt_t;
|
||||
|
||||
@@ -97,12 +97,11 @@ static inline void *NotifiedFifoData(notifiedFIFO_elt_t *elt) {
|
||||
|
||||
static inline void delNotifiedFIFO_elt(notifiedFIFO_elt_t *elt) {
|
||||
if (elt->malloced) {
|
||||
elt->malloced=false;
|
||||
elt->malloced = false;
|
||||
free(elt);
|
||||
} else
|
||||
printf("delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
|
||||
|
||||
//LOG_W(UTIL,"delNotifiedFIFO on something not allocated by newNotifiedFIFO\n");
|
||||
}
|
||||
/* it is allowed to call delNotifiedFIFO_elt when the memory is managed by
|
||||
* the caller */
|
||||
}
|
||||
|
||||
static inline void initNotifiedFIFO_nothreadSafe(notifiedFIFO_t *nf) {
|
||||
@@ -141,8 +140,7 @@ static inline notifiedFIFO_elt_t *pullNotifiedFIFO_nothreadSafe(notifiedFIFO_t
|
||||
|
||||
notifiedFIFO_elt_t *ret=nf->outF;
|
||||
|
||||
if (nf->outF==nf->outF->next)
|
||||
LOG_E(UTIL,"Circular list in thread pool: push several times the same buffer is forbidden\n");
|
||||
AssertFatal(nf->outF != nf->outF->next,"Circular list in thread pool: push several times the same buffer is forbidden\n");
|
||||
|
||||
nf->outF=nf->outF->next;
|
||||
|
||||
@@ -174,6 +172,20 @@ static inline notifiedFIFO_elt_t *pollNotifiedFIFO(notifiedFIFO_t *nf) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline time_stats_t exec_time_stats_NotifiedFIFO(const notifiedFIFO_elt_t* elt)
|
||||
{
|
||||
time_stats_t ts = {0};
|
||||
if (elt->startProcessingTime == 0 && elt->endProcessingTime == 0)
|
||||
return ts; /* no measurements done */
|
||||
ts.in = elt->startProcessingTime;
|
||||
ts.diff = elt->endProcessingTime - ts.in;
|
||||
ts.p_time = ts.diff;
|
||||
ts.diff_square = ts.diff * ts.diff;
|
||||
ts.max = ts.diff;
|
||||
ts.trials = 1;
|
||||
return ts;
|
||||
}
|
||||
|
||||
// This function aborts all messages matching the key
|
||||
// If the queue is used in thread pools, it doesn't cancels already running processing
|
||||
// because the message has already been picked
|
||||
@@ -224,18 +236,18 @@ typedef struct thread_pool {
|
||||
} tpool_t;
|
||||
|
||||
static inline void pushTpool(tpool_t *t, notifiedFIFO_elt_t *msg) {
|
||||
if (t->measurePerf) msg->creationTime=rdtsc();
|
||||
if (t->measurePerf) msg->creationTime=rdtsc_oai();
|
||||
|
||||
if ( t->activated)
|
||||
pushNotifiedFIFO(&t->incomingFifo, msg);
|
||||
else {
|
||||
if (t->measurePerf)
|
||||
msg->startProcessingTime=rdtsc();
|
||||
msg->startProcessingTime=rdtsc_oai();
|
||||
|
||||
msg->processingFunc(NotifiedFifoData(msg));
|
||||
|
||||
if (t->measurePerf)
|
||||
msg->endProcessingTime=rdtsc();
|
||||
msg->endProcessingTime=rdtsc_oai();
|
||||
|
||||
if (msg->reponseFifo)
|
||||
pushNotifiedFIFO(msg->reponseFifo, msg);
|
||||
@@ -246,7 +258,7 @@ static inline notifiedFIFO_elt_t *pullTpool(notifiedFIFO_t *responseFifo, tpool_
|
||||
notifiedFIFO_elt_t *msg= pullNotifiedFIFO(responseFifo);
|
||||
AssertFatal(t->traceFd, "Thread pool used while not initialized");
|
||||
if (t->measurePerf)
|
||||
msg->returnTime=rdtsc();
|
||||
msg->returnTime=rdtsc_oai();
|
||||
|
||||
if (t->traceFd > 0)
|
||||
if(write(t->traceFd, msg, sizeof(*msg)));
|
||||
@@ -261,7 +273,7 @@ static inline notifiedFIFO_elt_t *tryPullTpool(notifiedFIFO_t *responseFifo, tpo
|
||||
return NULL;
|
||||
|
||||
if (t->measurePerf)
|
||||
msg->returnTime=rdtsc();
|
||||
msg->returnTime=rdtsc_oai();
|
||||
|
||||
if (t->traceFd)
|
||||
if(write(t->traceFd, msg, sizeof(*msg)));
|
||||
|
||||
@@ -267,6 +267,15 @@ void init_meas(void) {
|
||||
AssertFatal(rt==0, "couldn't create cpu measurment thread: %s\n",strerror(errno));
|
||||
}
|
||||
|
||||
void send_meas(time_stats_t *ts, int msgid) {
|
||||
if (MEASURE_ENABLED(ts) ) {
|
||||
ts->tstatptr->timestat_id=ts->meas_index;
|
||||
ts->tstatptr->msgid = msgid ;
|
||||
ts->tstatptr->ts = rdtsc_oai();
|
||||
pushNotifiedFIFO(&measur_fifo, ts->tpoolmsg);
|
||||
}
|
||||
}
|
||||
|
||||
void end_meas(void) {
|
||||
notifiedFIFO_elt_t *nfe = newNotifiedFIFO_elt(sizeof(time_stats_msg_t),0,NULL,NULL);
|
||||
time_stats_msg_t *msg = (time_stats_msg_t *)NotifiedFifoData(nfe);
|
||||
@@ -31,15 +31,14 @@
|
||||
#include <pthread.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include "common/utils/threadPool/thread-pool.h"
|
||||
// global var to enable openair performance profiler
|
||||
extern int opp_enabled;
|
||||
extern double cpu_freq_GHz __attribute__ ((aligned(32)));;
|
||||
// structure to store data to compute cpu measurment
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#define OAI_CPUTIME_TYPE long long
|
||||
typedef long long oai_cputime_t;
|
||||
#elif defined(__arm__)
|
||||
#define OAI_CPUTIME_TYPE uint32_t
|
||||
typedef uint32_t oai_cputime_t;
|
||||
#else
|
||||
#error "building on unsupported CPU architecture"
|
||||
#endif
|
||||
@@ -54,23 +53,23 @@ typedef void(*meas_printfunc_t)(const char* format, ...);
|
||||
typedef struct {
|
||||
int msgid; /*!< \brief message id, as defined by TIMESTAT_MSGID_X macros */
|
||||
int timestat_id; /*!< \brief points to the time_stats_t entry in cpumeas table */
|
||||
OAI_CPUTIME_TYPE ts; /*!< \brief time stamp */
|
||||
oai_cputime_t ts; /*!< \brief time stamp */
|
||||
meas_printfunc_t displayFunc; /*!< \brief function to call when DISPLAY message is received*/
|
||||
} time_stats_msg_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
OAI_CPUTIME_TYPE in; /*!< \brief time at measure starting point */
|
||||
OAI_CPUTIME_TYPE diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
||||
OAI_CPUTIME_TYPE p_time; /*!< \brief absolute process duration */
|
||||
OAI_CPUTIME_TYPE diff_square; /*!< \brief process duration square */
|
||||
OAI_CPUTIME_TYPE max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
||||
struct notifiedFIFO_elt_s;
|
||||
typedef struct time_stats {
|
||||
oai_cputime_t in; /*!< \brief time at measure starting point */
|
||||
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
||||
oai_cputime_t p_time; /*!< \brief absolute process duration */
|
||||
oai_cputime_t diff_square; /*!< \brief process duration square */
|
||||
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
||||
int trials; /*!< \brief number of start point - end point iterations */
|
||||
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
|
||||
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
|
||||
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
|
||||
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
|
||||
notifiedFIFO_elt_t *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
|
||||
struct notifiedFIFO_elt_s *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
|
||||
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations*/
|
||||
} time_stats_t;
|
||||
#define MEASURE_ENABLED(X) (X->meas_enabled)
|
||||
@@ -179,7 +178,7 @@ static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
|
||||
}
|
||||
}
|
||||
|
||||
static inline void merge_meas(time_stats_t *dst_ts, time_stats_t *src_ts)
|
||||
static inline void merge_meas(time_stats_t *dst_ts, const time_stats_t *src_ts)
|
||||
{
|
||||
if (!opp_enabled)
|
||||
return;
|
||||
@@ -189,25 +188,17 @@ static inline void merge_meas(time_stats_t *dst_ts, time_stats_t *src_ts)
|
||||
dst_ts->max = src_ts->max;
|
||||
}
|
||||
|
||||
extern notifiedFIFO_t measur_fifo;
|
||||
#define CPUMEASUR_SECTION "cpumeasur"
|
||||
|
||||
#define CPUMEASUR_PARAMS_DESC { \
|
||||
{"max_cpumeasur", "Max number of cpu measur entries", 0, uptr:&max_cpumeasur, defintval:100, TYPE_UINT, 0},\
|
||||
}
|
||||
|
||||
void init_meas(void);
|
||||
time_stats_t *register_meas(char *name);
|
||||
#define START_MEAS(X) send_meas(X, TIMESTAT_MSGID_START)
|
||||
#define STOP_MEAS(X) send_meas(X, TIMESTAT_MSGID_STOP)
|
||||
static inline void send_meas(time_stats_t *ts, int msgid) {
|
||||
if (MEASURE_ENABLED(ts) ) {
|
||||
ts->tstatptr->timestat_id=ts->meas_index;
|
||||
ts->tstatptr->msgid = msgid ;
|
||||
ts->tstatptr->ts = rdtsc_oai();
|
||||
pushNotifiedFIFO(&measur_fifo, ts->tpoolmsg);
|
||||
}
|
||||
}
|
||||
void end_meas(void);
|
||||
void init_meas(void);
|
||||
time_stats_t *register_meas(char *name);
|
||||
#define START_MEAS(X) send_meas(X, TIMESTAT_MSGID_START)
|
||||
#define STOP_MEAS(X) send_meas(X, TIMESTAT_MSGID_STOP)
|
||||
void send_meas(time_stats_t *ts, int msgid);
|
||||
void end_meas(void);
|
||||
|
||||
#endif
|
||||
@@ -23,7 +23,6 @@ This tuto for 5G gNB NAS design
|
||||
|
||||
# source files
|
||||
|
||||
executables/ocp-gnb.c: a main loop to create a debuggable gNB, see document SW_archi.md
|
||||
openair2/RRC/NR/nr_ngap_gNB.c: skeleton for interface with NGAP
|
||||
openair3/NAS/COMMON/milenage.h: a simple milenage implementation, depend only on crypto library
|
||||
openair3/NAS/COMMON/NR_NAS_defs.h: messages defined for NAS implemented in C: C struct, C enums and automatic conversion to labels for debug messages
|
||||
|
||||
@@ -85,10 +85,6 @@ end
|
||||
This tuto for 5G gNB design, with Open Cells main
|
||||
{: .text-center}
|
||||
|
||||
# Top file: executables/ocp-gnb.c
|
||||
|
||||
the function main() initializes the data from configuration file
|
||||
|
||||
# The main thread is in ru_thread()
|
||||
The infinite loop:
|
||||
## rx_rf()
|
||||
|
||||
+58
-5
@@ -55,6 +55,59 @@ int sum(uint8_t *b, int s) {
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
extern double cpuf;
|
||||
|
||||
typedef struct m {
|
||||
uint64_t iterations;
|
||||
uint64_t sum;
|
||||
uint64_t maxArray[11];
|
||||
} Meas;
|
||||
|
||||
int cmpint(const void *a, const void *b)
|
||||
{
|
||||
uint64_t *aa=(uint64_t *)a;
|
||||
uint64_t *bb=(uint64_t *)b;
|
||||
return (int)(*aa-*bb);
|
||||
}
|
||||
|
||||
static inline void printMeas(char *txt,
|
||||
Meas *M,
|
||||
int period)
|
||||
{
|
||||
if (M->iterations%period == 0 ) {
|
||||
char txt2[512];
|
||||
sprintf(txt2,"%s avg=%" PRIu64 " iterations=%" PRIu64 " max=%"
|
||||
PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 ":%" PRIu64 "\n",
|
||||
txt,
|
||||
M->sum/M->iterations,
|
||||
M->iterations,
|
||||
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4], M->maxArray[5],
|
||||
M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
|
||||
#if T_TRACER
|
||||
LOG_W(PHY,"%s",txt2);
|
||||
#else
|
||||
printf("%s",txt2);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void updateTimes(uint64_t start, Meas *M, int period, char *txt)
|
||||
{
|
||||
if (start!=0) {
|
||||
uint64_t end=rdtsc_oai();
|
||||
long long diff=(end-start)/(cpuf*1000);
|
||||
M->maxArray[0]=diff;
|
||||
M->sum+=diff;
|
||||
M->iterations++;
|
||||
qsort(M->maxArray, 11, sizeof(uint64_t), cmpint);
|
||||
printMeas(txt,M,period);
|
||||
}
|
||||
}
|
||||
|
||||
#define initStaticTime(a) static __thread uint64_t a={0}
|
||||
#define pickStaticTime(a) do { a=rdtsc_oai(); } while (0)
|
||||
#define initRefTimes(a) static __thread Meas a= {0}
|
||||
static inline int cmpintRev(const void *a, const void *b) {
|
||||
uint64_t *aa=(uint64_t *)a;
|
||||
uint64_t *bb=(uint64_t *)b;
|
||||
@@ -82,7 +135,7 @@ static inline void printMeas2(char *txt, Meas *M, int period, bool MaxMin) {
|
||||
|
||||
static inline void updateTimesReset(uint64_t start, Meas *M, int period, bool MaxMin, char *txt) {
|
||||
if (start!=0) {
|
||||
uint64_t end=rdtsc();
|
||||
uint64_t end=rdtsc_oai();
|
||||
long long diff=(end-start)/(cpuf*1000);
|
||||
M->maxArray[0]=diff;
|
||||
M->sum+=diff;
|
||||
@@ -107,7 +160,7 @@ static inline void updateTimesReset(uint64_t start, Meas *M, int period, bool Ma
|
||||
|
||||
static inline void measTransportTime(uint64_t DuSend, uint64_t CuMicroSec, Meas *M, int period, bool MaxMin, char *txt) {
|
||||
if (DuSend!=0) {
|
||||
uint64_t end=rdtsc();
|
||||
uint64_t end=rdtsc_oai();
|
||||
long long diff=(end-DuSend)/(cpuf*1000)-CuMicroSec;
|
||||
M->maxArray[0]=diff;
|
||||
M->sum+=diff;
|
||||
@@ -894,7 +947,7 @@ void phy_procedures_eNB_TX_fromsplit(uint8_t *bufferZone, int nbBlocks, PHY_VARS
|
||||
memcpy(eNB->pbch_pdu,hDL(bufferZone)->pbch_pdu, 4);
|
||||
|
||||
// Remove all scheduled DL, we will populate from the CU sending
|
||||
for (int UE_id=0; UE_id<NUMBER_OF_UE_MAX; UE_id++) {
|
||||
for (int UE_id=0; UE_id<NUMBER_OF_DLSCH_MAX; UE_id++) {
|
||||
LTE_eNB_DLSCH_t *dlsch0 = eNB->dlsch[UE_id][0];
|
||||
|
||||
if ( dlsch0 && dlsch0->rnti>0 ) {
|
||||
@@ -1463,7 +1516,7 @@ void DL_cu_fs6(RU_t *ru, L1_rxtx_proc_t *proc, uint64_t DuClock, uint64_t start
|
||||
}
|
||||
|
||||
hDL(bufferZone)->DuClock=DuClock;
|
||||
hDL(bufferZone)->CuSpentMicroSec=(rdtsc()-startCycle)/(cpuf*1000);
|
||||
hDL(bufferZone)->CuSpentMicroSec=(rdtsc_oai()-startCycle)/(cpuf*1000);
|
||||
updateTimesReset(startCycle, &CUprocessing, 1000, true,"CU entire processing from recv to send");
|
||||
sendSubFrame(&sockFS6, bufferZone, sizeof(fs6_dl_t), CTsentCUv0 );
|
||||
return;
|
||||
@@ -1476,7 +1529,7 @@ void UL_cu_fs6(RU_t *ru, L1_rxtx_proc_t *proc, uint64_t *TS, uint64_t *DuClock,
|
||||
pickStaticTime(begingWait);
|
||||
int nb_blocks=receiveSubFrame(&sockFS6, bufferZone, sizeof(bufferZone), CTsentDUv0 );
|
||||
* DuClock=hUDP(bufferZone)->senderClock;
|
||||
* startProcessing=rdtsc();
|
||||
* startProcessing=rdtsc_oai();
|
||||
updateTimesReset(begingWait, &fullLoop, 1000, false, "CU wait DU");
|
||||
|
||||
if (nb_blocks ==0) {
|
||||
|
||||
@@ -87,10 +87,10 @@ AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]= {0};
|
||||
AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]= {0};
|
||||
void flexran_agent_slice_update(mid_t module_idP) {
|
||||
}
|
||||
int proto_agent_start(mod_id_t mod_id, const cudu_params_t *p) {
|
||||
int proto_agent_start(mid_t mod_id, const cudu_params_t *p) {
|
||||
return 0;
|
||||
}
|
||||
void proto_agent_stop(mod_id_t mod_id) {
|
||||
void proto_agent_stop(mid_t mod_id) {
|
||||
}
|
||||
|
||||
static void *ru_thread( void *param );
|
||||
|
||||
@@ -300,8 +300,7 @@ void rx_func(void *param) {
|
||||
}
|
||||
static void dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output) {
|
||||
int stroff = 0;
|
||||
stroff += print_meas_log(gNB->phy_proc_tx[0], "L1 Tx processing thread 0", NULL, NULL, output);
|
||||
//stroff += print_meas_log(gNB->phy_proc_tx[1], "L1 Tx processing thread 1", NULL, NULL, output+stroff);
|
||||
stroff += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output);
|
||||
stroff += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output+stroff);
|
||||
stroff += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output+stroff);
|
||||
stroff += print_meas_log(&gNB->ul_indication_stats, "UL Indication", NULL, NULL, output+stroff);
|
||||
@@ -337,8 +336,7 @@ void *nrL1_stats_thread(void *param) {
|
||||
fd=fopen("nrL1_stats.log","w");
|
||||
AssertFatal(fd!=NULL,"Cannot open nrL1_stats.log\n");
|
||||
|
||||
reset_meas(gNB->phy_proc_tx[0]);
|
||||
//reset_meas(gNB->phy_proc_tx[1]);
|
||||
reset_meas(&gNB->phy_proc_tx);
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->ul_indication_stats);
|
||||
@@ -425,7 +423,7 @@ void init_gNB_Tpool(int inst) {
|
||||
s_offset += 3;
|
||||
}
|
||||
if (getenv("noThreads")) strcpy(pool, "n");
|
||||
initTpool(pool, gNB->threadPool, false);
|
||||
initTpool(pool, gNB->threadPool, cpumeas(CPUMEAS_GETSTATE));
|
||||
// ULSCH decoder result FIFO
|
||||
gNB->respDecode = (notifiedFIFO_t*) malloc(sizeof(notifiedFIFO_t));
|
||||
initNotifiedFIFO(gNB->respDecode);
|
||||
@@ -450,8 +448,6 @@ void init_gNB_Tpool(int inst) {
|
||||
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||
init_DLSCH_struct(gNB, msgDataTx);
|
||||
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
||||
reset_meas(&msgDataTx->phy_proc_tx);
|
||||
gNB->phy_proc_tx[i] = &msgDataTx->phy_proc_tx;
|
||||
pushNotifiedFIFO(gNB->L1_tx_free,msgL1Tx); // to unblock the process in the beginning
|
||||
}
|
||||
|
||||
|
||||
@@ -62,8 +62,6 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
#include "common/utils/LOG/vcd_signal_dumper.h"
|
||||
#include "UTIL/OPT/opt.h"
|
||||
|
||||
//#include "PHY/TOOLS/time_meas.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "PHY/INIT/phy_init.h"
|
||||
|
||||
+2
-2
@@ -766,9 +766,9 @@ void processSlotRX(void *arg) {
|
||||
#ifdef UE_SLOT_PARALLELISATION
|
||||
phy_procedures_slot_parallelization_nrUE_RX( UE, proc, 0, 0, 1, no_relay, NULL );
|
||||
#else
|
||||
uint64_t a=rdtsc();
|
||||
uint64_t a=rdtsc_oai();
|
||||
phy_procedures_nrUE_RX(UE, proc, gNB_id, get_nrUE_params()->nr_dlsch_parallel, &rxtxD->txFifo);
|
||||
LOG_D(PHY, "In %s: slot %d, time %lu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc()-a)/3500);
|
||||
LOG_D(PHY, "In %s: slot %d, time %llu\n", __FUNCTION__, proc->nr_slot_rx, (rdtsc_oai()-a)/3500);
|
||||
#endif
|
||||
|
||||
if(IS_SOFTMODEM_NOS1 || get_softmodem_params()->sa){
|
||||
|
||||
@@ -61,7 +61,6 @@ unsigned short config_frames[4] = {2,9,11,13};
|
||||
|
||||
#include "UTIL/OPT/opt.h"
|
||||
#include "enb_config.h"
|
||||
//#include "PHY/TOOLS/time_meas.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -120,7 +120,6 @@ extern "C"
|
||||
#define TIMING_SOURCE softmodem_params.timing_source
|
||||
#define SEND_DMRSSYNC softmodem_params.send_dmrs_sync
|
||||
#define USIM_TEST softmodem_params.usim_test
|
||||
#define USE_256QAM_TABLE softmodem_params.use_256qam_table
|
||||
#define PRB_INTERPOLATION softmodem_params.prb_interpolation
|
||||
#define NFAPI softmodem_params.nfapi
|
||||
#define NSA softmodem_params.nsa
|
||||
@@ -158,14 +157,13 @@ extern int usrp_tx_thread;
|
||||
{"basicsim", CONFIG_HLP_RFSIM, PARAMFLAG_BOOL, uptr:&basicsim, defintval:0, TYPE_INT, 0}, \
|
||||
{"nokrnmod", CONFIG_HLP_NOKRNMOD, PARAMFLAG_BOOL, uptr:&nokrnmod, defintval:0, TYPE_INT, 0}, \
|
||||
{"nbiot-disable", CONFIG_HLP_DISABLNBIOT, PARAMFLAG_BOOL, uptr:&nonbiot, defuintval:0, TYPE_INT, 0}, \
|
||||
{"use-256qam-table", CONFIG_HLP_256QAM, PARAMFLAG_BOOL, iptr:&USE_256QAM_TABLE, defintval:0, TYPE_INT, 0}, \
|
||||
{"nsa", CONFIG_HLP_NSA, PARAMFLAG_BOOL, iptr:&NSA, defintval:0, TYPE_INT, 0}, \
|
||||
{"node-number", NULL, 0, u16ptr:&NODE_NUMBER, defuintval:0, TYPE_UINT16, 0}, \
|
||||
{"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \
|
||||
{"do-prb-interpolation", CONFIG_HLP_PRBINTER, PARAMFLAG_BOOL, iptr:&PRB_INTERPOLATION, defintval:0, TYPE_INT, 0}, \
|
||||
{"nfapi", CONFIG_HLP_NFAPI, 0, u8ptr:&nfapi_mode, defintval:0, TYPE_UINT8, 0}, \
|
||||
{"non-stop", CONFIG_HLP_NONSTOP, PARAMFLAG_BOOL, iptr:&NON_STOP, defintval:0, TYPE_INT, 0}, \
|
||||
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0}, \
|
||||
{"emulate-l1", CONFIG_L1_EMULATOR, PARAMFLAG_BOOL, iptr:&EMULATE_L1, defintval:0, TYPE_INT, 0} \
|
||||
}
|
||||
|
||||
#define CONFIG_HLP_NSA "Enable NSA mode \n"
|
||||
@@ -250,7 +248,6 @@ typedef struct {
|
||||
uint32_t timing_source;
|
||||
int hw_timing_advance;
|
||||
uint32_t send_dmrs_sync;
|
||||
int use_256qam_table;
|
||||
int prb_interpolation;
|
||||
uint8_t nfapi;
|
||||
int nsa;
|
||||
|
||||
@@ -156,7 +156,7 @@ int receiveSubFrame(UDPsock_t *sock, void *bufferZone, int bufferSize, uint16_t
|
||||
int sendSubFrame(UDPsock_t *sock, void *bufferZone, ssize_t secondHeaderSize, uint16_t contentType) {
|
||||
commonUDP_t *UDPheader=(commonUDP_t *)bufferZone ;
|
||||
UDPheader->contentType=contentType;
|
||||
UDPheader->senderClock=rdtsc();
|
||||
UDPheader->senderClock=rdtsc_oai();
|
||||
int nbBlocks=UDPheader->nbBlocks;
|
||||
int blockId=0;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#ifndef __NR_LDPC_TYPES__H__
|
||||
#define __NR_LDPC_TYPES__H__
|
||||
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "nrLDPCdecoder_defs.h"
|
||||
// ==============================================================================
|
||||
// TYPES
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include "defs.h"
|
||||
#include "assertions.h"
|
||||
#include "openair1/PHY/CODING/nrLDPC_defs.h"
|
||||
@@ -280,4 +279,4 @@ int ldpc_encoder_orig(unsigned char *test_input,unsigned char *channel_input,int
|
||||
|
||||
int nrLDPC_encod(unsigned char **test_input,unsigned char **channel_input,int Zc,int Kb,short block_length, short BG, encoder_implemparams_t *impp) {
|
||||
return ldpc_encoder_orig(test_input[0],channel_input[0],Zc,Kb,block_length,BG,impp->gen_code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
#include <types.h>
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "defs.h"
|
||||
|
||||
#include "ldpc384_byte.c"
|
||||
|
||||
@@ -33,10 +33,9 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "openair1/PHY/CODING/nrLDPC_defs.h"
|
||||
#include "ldpc_encode_parity_check.c"
|
||||
#include "ldpc_generate_coefficient.c"
|
||||
|
||||
@@ -33,10 +33,9 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "openair1/PHY/CODING/nrLDPC_defs.h"
|
||||
#include "ldpc_encode_parity_check.c"
|
||||
#include "ldpc_generate_coefficient.c"
|
||||
|
||||
@@ -33,10 +33,9 @@
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <types.h>
|
||||
#include "assertions.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "openair1/PHY/CODING/nrLDPC_defs.h"
|
||||
|
||||
#include "ldpc_encode_parity_check.c"
|
||||
|
||||
@@ -51,7 +51,7 @@ void reset_stats(FL_OBJECT *button, long arg) {
|
||||
int i,j,k;
|
||||
PHY_VARS_eNB *phy_vars_eNB = RC.eNB[0][0];
|
||||
|
||||
for (i=0; i<NUMBER_OF_UE_MAX; i++) {
|
||||
for (i=0; i<NUMBER_OF_DLSCH_MAX; i++) {
|
||||
for (k=0; k<8; k++) { //harq_processes
|
||||
for (j=0; j<phy_vars_eNB->dlsch[i][0]->Mlimit; j++) {
|
||||
phy_vars_eNB->UE_stats[i].dlsch_NAK[k][j]=0;
|
||||
|
||||
@@ -122,7 +122,7 @@ static inline void* malloc16_clear( size_t size )
|
||||
#include "PHY/impl_defs_top_NB_IoT.h"
|
||||
#include "PHY/impl_defs_lte_NB_IoT.h"
|
||||
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
//#include "PHY/CODING/defs.h"
|
||||
#include "PHY/CODING/defs_NB_IoT.h"
|
||||
#include "openair2/PHY_INTERFACE/IF_Module_NB_IoT.h"
|
||||
@@ -452,9 +452,6 @@ typedef struct {
|
||||
int sub_frame_start;
|
||||
///
|
||||
int sub_frame_step;
|
||||
///
|
||||
unsigned long long gotIQs;
|
||||
|
||||
} UE_rxtx_proc_NB_IoT_t;
|
||||
|
||||
/// Context data structure for eNB subframe processing
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#include "common_lib.h"
|
||||
#include "openairinterface5g_limits.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "defs_common.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
#include "defs_common.h"
|
||||
#include "impl_defs_top.h"
|
||||
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "platform_types.h"
|
||||
@@ -154,7 +154,6 @@ typedef struct {
|
||||
|
||||
int sub_frame_start;
|
||||
int sub_frame_step;
|
||||
unsigned long long gotIQs;
|
||||
} UE_rxtx_proc_t;
|
||||
|
||||
/// Context data structure for eNB subframe processing
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
#include "assertions.h"
|
||||
|
||||
//#include <complex.h>
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "platform_types.h"
|
||||
#define MAX_NUM_RU_PER_eNB 64
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
#include "defs_common.h"
|
||||
#include "defs_RU.h"
|
||||
#include "impl_defs_top.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
//#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "platform_types.h"
|
||||
@@ -202,7 +202,7 @@ typedef struct {
|
||||
int repetition_number[4];
|
||||
} LTE_eNB_PRACH;
|
||||
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "PHY/LTE_TRANSPORT/transport_eNB.h"
|
||||
|
||||
@@ -856,7 +856,7 @@ typedef struct PHY_VARS_gNB_s {
|
||||
/*
|
||||
time_stats_t phy_proc;
|
||||
*/
|
||||
time_stats_t *phy_proc_tx[2];
|
||||
time_stats_t phy_proc_tx;
|
||||
time_stats_t phy_proc_rx;
|
||||
time_stats_t rx_prach;
|
||||
/*
|
||||
@@ -973,7 +973,6 @@ typedef struct processingData_L1tx {
|
||||
uint16_t num_pdsch_slot;
|
||||
int num_dl_pdcch;
|
||||
int num_ul_pdcch;
|
||||
time_stats_t phy_proc_tx;
|
||||
} processingData_L1tx_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
|
||||
#include "impl_defs_top.h"
|
||||
#include "impl_defs_nr.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
#include "PHY/CODING/coding_defs.h"
|
||||
#include "PHY/TOOLS/tools_defs.h"
|
||||
#include "platform_types.h"
|
||||
|
||||
@@ -62,7 +62,6 @@ typedef struct {
|
||||
|
||||
int sub_frame_start;
|
||||
int sub_frame_step;
|
||||
unsigned long long gotIQs;
|
||||
uint8_t decoder_thread_available1;
|
||||
int dci_err_cnt;
|
||||
} UE_nr_rxtx_proc_t;
|
||||
|
||||
@@ -165,6 +165,8 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){
|
||||
notifiedFIFO_elt_t *res;
|
||||
res = pullTpool(gNB->L1_tx_free, gNB->threadPool);
|
||||
processingData_L1tx_t *msgTx = (processingData_L1tx_t *)NotifiedFifoData(res);
|
||||
const time_stats_t ts = exec_time_stats_NotifiedFIFO(res);
|
||||
merge_meas(&gNB->phy_proc_tx, &ts);
|
||||
|
||||
msgTx->num_pdsch_slot=0;
|
||||
msgTx->num_dl_pdcch=0;
|
||||
|
||||
@@ -134,8 +134,6 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,1);
|
||||
|
||||
if (do_meas==1) start_meas(&msgTx->phy_proc_tx);
|
||||
|
||||
// clear the transmit data array and beam index for the current slot
|
||||
for (aa=0; aa<cfg->carrier_config.num_tx_ant.value; aa++) {
|
||||
memset(&gNB->common_vars.txdataF[aa][txdataF_offset],0,fp->samples_per_slot_wCP*sizeof(int32_t));
|
||||
@@ -193,8 +191,6 @@ void phy_procedures_gNB_TX(processingData_L1tx_t *msgTx,
|
||||
}
|
||||
|
||||
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_PROCEDURES_gNB_TX+offset,0);
|
||||
|
||||
if (do_meas==1) stop_meas(&msgTx->phy_proc_tx);
|
||||
}
|
||||
|
||||
void nr_postDecode(PHY_VARS_gNB *gNB, notifiedFIFO_elt_t *req) {
|
||||
|
||||
@@ -129,7 +129,6 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_
|
||||
slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||
// printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
|
||||
if (frame_parms->Ncp == 1)
|
||||
PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
|
||||
&txdata[aa][slot_offset], // output
|
||||
|
||||
@@ -112,7 +112,6 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_
|
||||
slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||
// printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
|
||||
|
||||
if (frame_parms->Ncp == 1)
|
||||
PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
|
||||
|
||||
@@ -333,7 +333,6 @@ void do_OFDM_mod(mod_sym_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_
|
||||
slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||
// printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
|
||||
|
||||
if (frame_parms->Ncp == 1)
|
||||
PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
|
||||
|
||||
@@ -121,7 +121,6 @@ void do_OFDM_mod_l(int32_t **txdataF, int32_t **txdata, uint16_t next_slot, LTE_
|
||||
slot_offset = (next_slot)*(frame_parms->samples_per_tti>>1);
|
||||
|
||||
for (aa=0; aa<frame_parms->nb_antennas_tx; aa++) {
|
||||
// printf("Thread %d starting ... aa %d (%llu)\n",omp_get_thread_num(),aa,rdtsc());
|
||||
if (frame_parms->Ncp == 1)
|
||||
PHY_ofdm_mod(&txdataF[aa][slot_offset_F], // input
|
||||
&txdata[aa][slot_offset], // output
|
||||
|
||||
@@ -441,7 +441,7 @@ int main(int argc, char **argv)
|
||||
|
||||
FILE *scg_fd=NULL;
|
||||
|
||||
while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:m:w:T:U:qX:")) != -1) {
|
||||
while ((c = getopt (argc, argv, "f:hA:pf:g:in:s:S:t:x:y:z:M:N:F:GR:dPIL:Ea:b:d:e:q:m:w:T:U:X:")) != -1) {
|
||||
switch (c) {
|
||||
case 'f':
|
||||
scg_fd = fopen(optarg,"r");
|
||||
@@ -607,16 +607,17 @@ int main(int argc, char **argv)
|
||||
case 'b':
|
||||
g_rbSize = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
dlsch_threads = atoi(optarg);
|
||||
break;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
g_mcsIndex = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
g_mcsTableIdx = 1;
|
||||
get_softmodem_params()->use_256qam_table = 1;
|
||||
g_mcsTableIdx = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
@@ -680,7 +681,7 @@ int main(int argc, char **argv)
|
||||
printf("-c Start symbol for PDSCH (fixed for now)\n");
|
||||
printf("-j Number of symbols for PDSCH (fixed for now)\n");
|
||||
printf("-e MSC index\n");
|
||||
printf("-q Use 2nd MCS table (256 QAM table) for PDSCH\n");
|
||||
printf("-q MCS Table index\n");
|
||||
printf("-t Acceptable effective throughput (in percentage)\n");
|
||||
printf("-T Enable PTRS, arguments list L_PTRS{0,1,2} K_PTRS{2,4}, e.g. -T 2 0 2 \n");
|
||||
printf("-U Change DMRS Config, arguments list DMRS TYPE{0=A,1=B} DMRS AddPos{0:2} DMRS ConfType{1:2}, e.g. -U 3 0 2 1 \n");
|
||||
@@ -781,12 +782,14 @@ int main(int argc, char **argv)
|
||||
fill_scc_sim(rrc.carrier.servingcellconfigcommon,&ssb_bitmap,N_RB_DL,N_RB_DL,mu,mu);
|
||||
ssb_bitmap = 1;// Enable only first SSB with index ssb_indx=0
|
||||
fix_scc(scc,ssb_bitmap);
|
||||
|
||||
prepare_scd(scd);
|
||||
|
||||
// TODO do a UECAP for phy-sim
|
||||
fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, NULL, 0, 1, n_tx, 6, 0, 0, 0);
|
||||
NR_UE_NR_Capability_t* UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
||||
prepare_sim_uecap(UE_Capability_nr,scc,mu,
|
||||
N_RB_DL,g_mcsTableIdx);
|
||||
|
||||
// TODO do a UECAP for phy-sim
|
||||
fill_default_secondaryCellGroup(scc, scd, secondaryCellGroup, UE_Capability_nr, 0, 1, n_tx, 6, 0, 0, 0);
|
||||
|
||||
/* RRC parameter validation for secondaryCellGroup */
|
||||
fix_scd(scd);
|
||||
@@ -1015,8 +1018,6 @@ int main(int argc, char **argv)
|
||||
msgDataTx->slot = slot;
|
||||
msgDataTx->frame = frame;
|
||||
memset(msgDataTx->ssb, 0, 64*sizeof(NR_gNB_SSB_t));
|
||||
reset_meas(&msgDataTx->phy_proc_tx);
|
||||
gNB->phy_proc_tx[0] = &msgDataTx->phy_proc_tx;
|
||||
|
||||
for (SNR = snr0; SNR < snr1; SNR += .2) {
|
||||
|
||||
@@ -1330,7 +1331,7 @@ int main(int argc, char **argv)
|
||||
printf("\ngNB TX function statistics (per %d us slot, NPRB %d, mcs %d, block %d)\n",
|
||||
1000>>*scc->ssbSubcarrierSpacing, g_rbSize, g_mcsIndex,
|
||||
msgDataTx->dlsch[0][0]->harq_process.pdsch_pdu.pdsch_pdu_rel15.TBSize[0]<<3);
|
||||
printDistribution(gNB->phy_proc_tx[0],table_tx,"PHY proc tx");
|
||||
printDistribution(&gNB->phy_proc_tx,table_tx,"PHY proc tx");
|
||||
printStatIndent2(&gNB->dlsch_encoding_stats,"DLSCH encoding time");
|
||||
printStatIndent3(&gNB->dlsch_segmentation_stats,"DLSCH segmentation time");
|
||||
printStatIndent3(&gNB->tinput,"DLSCH LDPC input processing time");
|
||||
|
||||
@@ -689,7 +689,6 @@ int main(int argc, char **argv)
|
||||
notifiedFIFO_elt_t *msgL1Tx = newNotifiedFIFO_elt(sizeof(processingData_L1tx_t),0,gNB->L1_tx_free,NULL);
|
||||
processingData_L1tx_t *msgDataTx = (processingData_L1tx_t *)NotifiedFifoData(msgL1Tx);
|
||||
msgDataTx->slot = -1;
|
||||
gNB->phy_proc_tx[0] = &msgDataTx->phy_proc_tx;
|
||||
//gNB_config = &gNB->gNB_config;
|
||||
|
||||
//memset((void *)&gNB->UL_INFO,0,sizeof(gNB->UL_INFO));
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "PHY_INTERFACE/phy_interface_extern.h"
|
||||
#include "UTIL/OCG/OCG.h"
|
||||
#include "UTIL/OPT/opt.h" // to test OPT
|
||||
#include "UTIL/FIFO/types.h"
|
||||
|
||||
#define RF
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
#include "nfapi_interface.h"
|
||||
#include "PHY_INTERFACE/IF_Module.h"
|
||||
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
|
||||
#include "PHY/defs_common.h" // for PRACH_RESOURCES_t
|
||||
#include "PHY/LTE_TRANSPORT/transport_common.h"
|
||||
|
||||
@@ -627,6 +627,8 @@ int rrc_mac_config_req_gNB(module_id_t Mod_idP,
|
||||
process_CellGroup(CellGroup,&UE_info->UE_sched_ctrl[UE_id]);
|
||||
const NR_ServingCellConfig_t *servingCellConfig = CellGroup ? CellGroup->spCellConfig->spCellConfigDedicated : NULL;
|
||||
NR_UE_sched_ctrl_t *sched_ctrl = &UE_info->UE_sched_ctrl[UE_id];
|
||||
sched_ctrl->update_pdsch_ps = true;
|
||||
sched_ctrl->update_pusch_ps = true;
|
||||
const NR_PDSCH_ServingCellConfig_t *pdsch = servingCellConfig ? servingCellConfig->pdsch_ServingCellConfig->choice.setup : NULL;
|
||||
if (get_softmodem_params()->sa) {
|
||||
// add all available DL HARQ processes for this UE in SA
|
||||
|
||||
@@ -393,12 +393,17 @@ int nr_write_ce_dlsch_pdu(module_id_t module_idP,
|
||||
|
||||
#define BLER_UPDATE_FRAME 10
|
||||
#define BLER_FILTER 0.9f
|
||||
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id)
|
||||
int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t slot, int UE_id, int mcs_table)
|
||||
{
|
||||
gNB_MAC_INST *nrmac = RC.nrmac[mod_id];
|
||||
const NR_ServingCellConfigCommon_t *scc = nrmac->common_channels[CC_id].ServingCellConfigCommon;
|
||||
const int n = nr_slots_per_frame[*scc->ssbSubcarrierSpacing];
|
||||
|
||||
int max_allowed_mcs = (mcs_table == 1) ? 27 : 28;
|
||||
int max_mcs = nrmac->dl_max_mcs;
|
||||
if (nrmac->dl_max_mcs>max_allowed_mcs)
|
||||
max_mcs = max_allowed_mcs;
|
||||
|
||||
NR_DL_bler_stats_t *bler_stats = &nrmac->UE_info.UE_sched_ctrl[UE_id].dl_bler_stats;
|
||||
/* first call: everything is zero. Initialize to sensible default */
|
||||
if (bler_stats->last_frame_slot == 0 && bler_stats->mcs == 0) {
|
||||
@@ -444,7 +449,7 @@ int get_mcs_from_bler(module_id_t mod_id, int CC_id, frame_t frame, sub_frame_t
|
||||
if (bler_stats->rd2_bler > nrmac->dl_rd2_bler_threshold && old_mcs > 6) {
|
||||
new_mcs -= 2;
|
||||
} else if (bler_stats->rd2_bler < nrmac->dl_rd2_bler_threshold) {*/
|
||||
if (bler_stats->bler < nrmac->dl_bler_target_lower && old_mcs < nrmac->dl_max_mcs && dtx > 9)
|
||||
if (bler_stats->bler < nrmac->dl_bler_target_lower && old_mcs < max_mcs && dtx > 9)
|
||||
new_mcs += 1;
|
||||
else if (bler_stats->bler > nrmac->dl_bler_target_upper && old_mcs > 6)
|
||||
new_mcs -= 1;
|
||||
@@ -586,8 +591,10 @@ bool allocate_dl_retransmission(module_id_t module_id,
|
||||
}
|
||||
/* check whether we need to switch the TDA allocation since the last
|
||||
* (re-)transmission */
|
||||
if (ps->time_domain_allocation != tda)
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, ps->nrOfLayers, sched_ctrl, ps);
|
||||
if (ps->time_domain_allocation != tda || sched_ctrl->update_pdsch_ps) {
|
||||
nr_set_pdsch_semi_static(scc, cg, sched_ctrl->active_bwp, bwpd, tda, ps->nrOfLayers, sched_ctrl, ps);
|
||||
sched_ctrl->update_pdsch_ps = false;
|
||||
}
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
* that we have enough resources */
|
||||
@@ -744,7 +751,7 @@ void pf_dl(module_id_t module_id,
|
||||
|
||||
/* Calculate coeff */
|
||||
set_dl_mcs(sched_pdsch,sched_ctrl,&mac->dl_max_mcs,ps->mcsTableIdx);
|
||||
sched_pdsch->mcs = get_mcs_from_bler(module_id, /* CC_id = */ 0, frame, slot, UE_id);
|
||||
sched_pdsch->mcs = get_mcs_from_bler(module_id, /* CC_id = */ 0, frame, slot, UE_id, ps->mcsTableIdx);
|
||||
layers[UE_id] = set_dl_nrOfLayers(sched_ctrl);
|
||||
const uint8_t Qm = nr_get_Qm_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
const uint16_t R = nr_get_code_rate_dl(sched_pdsch->mcs, ps->mcsTableIdx);
|
||||
@@ -863,8 +870,11 @@ void pf_dl(module_id_t module_id,
|
||||
NR_pdsch_semi_static_t *ps = &sched_ctrl->pdsch_semi_static;
|
||||
|
||||
if (ps->nrOfLayers != layers[UE_id] ||
|
||||
ps->time_domain_allocation != tda)
|
||||
ps->time_domain_allocation != tda ||
|
||||
sched_ctrl->update_pdsch_ps) {
|
||||
nr_set_pdsch_semi_static(scc, UE_info->CellGroup[UE_id], sched_ctrl->active_bwp, bwpd, tda, layers[UE_id], sched_ctrl, ps);
|
||||
sched_ctrl->update_pdsch_ps = false;
|
||||
}
|
||||
|
||||
const uint16_t slbitmap = SL_to_bitmap(ps->startSymbolIndex, ps->nrOfSymbols);
|
||||
// Freq-demain allocation
|
||||
|
||||
@@ -532,6 +532,7 @@ void nr_set_pdsch_semi_static(const NR_ServingCellConfigCommon_t *scc,
|
||||
ps->mcsTableIdx = 2;
|
||||
}
|
||||
else ps->mcsTableIdx = 0;
|
||||
LOG_D(NR_MAC,"MCS Table Index: %d\n",ps->mcsTableIdx);
|
||||
|
||||
NR_PDSCH_Config_t *pdsch_Config;
|
||||
if (bwp &&
|
||||
@@ -1943,7 +1944,6 @@ void create_nr_list(NR_list_t *list, int len)
|
||||
{
|
||||
list->head = -1;
|
||||
list->next = malloc(len * sizeof(*list->next));
|
||||
LOG_W(NR_MAC, "NR list->next %p\n", list->next);
|
||||
AssertFatal(list->next, "cannot malloc() memory for NR_list_t->next\n");
|
||||
for (int i = 0; i < len; ++i)
|
||||
list->next[i] = -1;
|
||||
@@ -2278,8 +2278,16 @@ void create_dl_harq_list(NR_UE_sched_ctrl_t *sched_ctrl,
|
||||
add_tail_nr_list(&sched_ctrl->available_dl_harq, harq);
|
||||
create_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ);
|
||||
create_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ);
|
||||
} else if (sched_ctrl->available_dl_harq.len == nrofHARQ) {
|
||||
LOG_D(NR_MAC, "nrofHARQ %d already configured\n", nrofHARQ);
|
||||
} else {
|
||||
const int old_nrofHARQ = sched_ctrl->available_dl_harq.len;
|
||||
AssertFatal(nrofHARQ > old_nrofHARQ,
|
||||
"cannot resize HARQ list to be smaller (nrofHARQ %d, old_nrofHARQ %d)\n",
|
||||
nrofHARQ, old_nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->available_dl_harq, nrofHARQ);
|
||||
for (int harq = old_nrofHARQ; harq < nrofHARQ; harq++)
|
||||
add_tail_nr_list(&sched_ctrl->available_dl_harq, harq);
|
||||
resize_nr_list(&sched_ctrl->feedback_dl_harq, nrofHARQ);
|
||||
resize_nr_list(&sched_ctrl->retrans_dl_harq, nrofHARQ);
|
||||
}
|
||||
|
||||
@@ -992,8 +992,11 @@ bool allocate_ul_retransmission(module_id_t module_id,
|
||||
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
LOG_D(NR_MAC, "%s(): retransmission keeping TDA %d and TBS %d\n", __func__, tda, retInfo->tb_size);
|
||||
} else {
|
||||
/* the retransmission will use a different time domain allocation, check
|
||||
@@ -1230,8 +1233,11 @@ void pf_ul(module_id_t module_id,
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
NR_sched_pusch_t *sched_pusch = &sched_ctrl->sched_pusch;
|
||||
sched_pusch->mcs = 9;
|
||||
update_ul_ue_R_Qm(sched_pusch, ps);
|
||||
@@ -1347,8 +1353,11 @@ void pf_ul(module_id_t module_id,
|
||||
const int tda = sched_ctrl->active_ubwp ? nrmac->preferred_ul_tda[sched_ctrl->active_ubwp->bwp_Id][slot] : 0;
|
||||
if (ps->time_domain_allocation != tda
|
||||
|| ps->dci_format != dci_format
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data)
|
||||
|| ps->num_dmrs_cdm_grps_no_data != num_dmrs_cdm_grps_no_data
|
||||
|| sched_ctrl->update_pusch_ps) {
|
||||
nr_set_pusch_semi_static(scc, sched_ctrl->active_ubwp, ubwpd, dci_format, tda, num_dmrs_cdm_grps_no_data, ps);
|
||||
sched_ctrl->update_pusch_ps = false;
|
||||
}
|
||||
update_ul_ue_R_Qm(sched_pusch, ps);
|
||||
|
||||
/* Calculate the current scheduling bytes and the necessary RBs */
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
/* PHY */
|
||||
#include "PHY/defs_gNB.h"
|
||||
#include "PHY/TOOLS/time_meas.h"
|
||||
#include "time_meas.h"
|
||||
|
||||
/* Interface */
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
@@ -620,6 +620,8 @@ typedef struct {
|
||||
int ul_failure;
|
||||
struct CSI_Report CSI_report;
|
||||
bool SR;
|
||||
bool update_pdsch_ps;
|
||||
bool update_pusch_ps;
|
||||
bool set_mcs;
|
||||
/// information about every HARQ process
|
||||
NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES];
|
||||
|
||||
@@ -1472,6 +1472,19 @@ void update_cellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig,
|
||||
|
||||
int curr_bwp = NRRIV2BW(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth,MAX_BWP_SIZE);
|
||||
config_csirs(scc, csi_MeasConfig, uid, carrier->pdsch_AntennaPorts, curr_bwp, carrier->do_CSIRS);
|
||||
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated = SpCellConfig->spCellConfigDedicated->initialDownlinkBWP;
|
||||
set_dl_mcs_table(scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.subcarrierSpacing,
|
||||
uecap, bwp_Dedicated, scc);
|
||||
|
||||
struct NR_ServingCellConfig__downlinkBWP_ToAddModList *DL_BWP_list = SpCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList;
|
||||
if (DL_BWP_list) {
|
||||
for (int i=0; i<DL_BWP_list->list.count; i++){
|
||||
NR_BWP_Downlink_t *bwp = DL_BWP_list->list.array[i];
|
||||
int scs = bwp->bwp_Common->genericParameters.subcarrierSpacing;
|
||||
set_dl_mcs_table(scs, uecap, bwp->bwp_Dedicated, carrier->servingcellconfigcommon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -169,6 +169,50 @@ void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
csi_MeasConfig->nzp_CSI_RS_ResourceToReleaseList = NULL;
|
||||
}
|
||||
|
||||
void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
int numerology,
|
||||
int rbsize,
|
||||
int mcs_table) {
|
||||
|
||||
int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
NR_BandNR_t *nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t));
|
||||
nr_bandnr->bandNR = band;
|
||||
ASN_SEQUENCE_ADD(&cap->rf_Parameters.supportedBandListNR.list,
|
||||
nr_bandnr);
|
||||
if (mcs_table == 1) {
|
||||
int bw = get_supported_band_index(numerology, band, rbsize);
|
||||
if (band>256) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[0];
|
||||
bandNRinfo->pdsch_256QAM_FR2 = CALLOC(1,sizeof(*bandNRinfo->pdsch_256QAM_FR2));
|
||||
*bandNRinfo->pdsch_256QAM_FR2 = NR_BandNR__pdsch_256QAM_FR2_supported;
|
||||
}
|
||||
else{
|
||||
cap->phy_Parameters.phy_ParametersFR1 = CALLOC(1,sizeof(*cap->phy_Parameters.phy_ParametersFR1));
|
||||
NR_Phy_ParametersFR1_t *phy_fr1 = cap->phy_Parameters.phy_ParametersFR1;
|
||||
phy_fr1->pdsch_256QAM_FR1 = CALLOC(1,sizeof(*phy_fr1->pdsch_256QAM_FR1));
|
||||
*phy_fr1->pdsch_256QAM_FR1 = NR_Phy_ParametersFR1__pdsch_256QAM_FR1_supported;
|
||||
}
|
||||
cap->featureSets = CALLOC(1,sizeof(*cap->featureSets));
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
fs->featureSetsDownlinkPerCC = CALLOC(1,sizeof(*fs->featureSetsDownlinkPerCC));
|
||||
NR_FeatureSetDownlinkPerCC_t *fs_cc = CALLOC(1,sizeof(NR_FeatureSetDownlinkPerCC_t));
|
||||
fs_cc->supportedSubcarrierSpacingDL = numerology;
|
||||
if(band>256) {
|
||||
fs_cc->supportedBandwidthDL.present = NR_SupportedBandwidth_PR_fr2;
|
||||
fs_cc->supportedBandwidthDL.choice.fr2 = bw;
|
||||
}
|
||||
else{
|
||||
fs_cc->supportedBandwidthDL.present = NR_SupportedBandwidth_PR_fr1;
|
||||
fs_cc->supportedBandwidthDL.choice.fr1 = bw;
|
||||
}
|
||||
fs_cc->supportedModulationOrderDL = CALLOC(1,sizeof(*fs_cc->supportedModulationOrderDL));
|
||||
*fs_cc->supportedModulationOrderDL = NR_ModulationOrder_qam256;
|
||||
ASN_SEQUENCE_ADD(&fs->featureSetsDownlinkPerCC->list,
|
||||
fs_cc);
|
||||
}
|
||||
}
|
||||
|
||||
void nr_rrc_config_dl_tda(NR_ServingCellConfigCommon_t *scc){
|
||||
|
||||
lte_frame_type_t frame_type = get_frame_type(*scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0], *scc->ssbSubcarrierSpacing);
|
||||
@@ -243,6 +287,52 @@ void nr_rrc_config_ul_tda(NR_ServingCellConfigCommon_t *scc, int min_fb_delay){
|
||||
ASN_SEQUENCE_ADD(&scc->uplinkConfigCommon->initialUplinkBWP->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list,pusch_timedomainresourceallocation_msg3);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_ServingCellConfigCommon_t *scc) {
|
||||
|
||||
if (cap == NULL){
|
||||
bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
int band = *scc->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
struct NR_FrequencyInfoDL__scs_SpecificCarrierList scs_list = scc->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList;
|
||||
int bw_rb = -1;
|
||||
for(int i=0; i<scs_list.list.count; i++){
|
||||
if(scs == scs_list.list.array[i]->subcarrierSpacing){
|
||||
bw_rb = scs_list.list.array[i]->carrierBandwidth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
AssertFatal(bw_rb>0,"Could not find scs-SpecificCarrierList element for scs %d",scs);
|
||||
int bw = get_supported_band_index(scs, band, bw_rb);
|
||||
AssertFatal(bw>0,"Supported band corresponding to %d RBs not found\n", bw_rb);
|
||||
|
||||
bool supported = false;
|
||||
if (band>256) {
|
||||
for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
|
||||
if(bandNRinfo->bandNR == band && bandNRinfo->pdsch_256QAM_FR2) {
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cap->phy_Parameters.phy_ParametersFR1 && cap->phy_Parameters.phy_ParametersFR1->pdsch_256QAM_FR1)
|
||||
supported = true;
|
||||
|
||||
if (supported) {
|
||||
if(bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table == NULL)
|
||||
bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table));
|
||||
*bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256;
|
||||
}
|
||||
else
|
||||
bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -119,6 +119,14 @@ void config_csirs(NR_ServingCellConfigCommon_t *servingcellconfigcommon,
|
||||
int num_dl_antenna_ports,
|
||||
int curr_bwp,
|
||||
int do_csirs);
|
||||
void set_dl_mcs_table(int scs, NR_UE_NR_Capability_t *cap,
|
||||
NR_BWP_DownlinkDedicated_t *bwp_Dedicated,
|
||||
NR_ServingCellConfigCommon_t *scc);
|
||||
void prepare_sim_uecap(NR_UE_NR_Capability_t *cap,
|
||||
NR_ServingCellConfigCommon_t *scc,
|
||||
int numerology,
|
||||
int rbsize,
|
||||
int mcs_table);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -709,6 +709,8 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
dedicatedNAS_MessageList = NULL;
|
||||
}
|
||||
|
||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
size = do_RRCReconfiguration(ctxt_pP, buffer, sizeof(buffer),
|
||||
xid,
|
||||
@@ -719,10 +721,10 @@ rrc_gNB_generate_defaultRRCReconfiguration(
|
||||
NULL,
|
||||
NULL,
|
||||
dedicatedNAS_MessageList,
|
||||
ue_context_pP,
|
||||
&rrc->carrier,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
ue_p->masterCellGroup);
|
||||
|
||||
free(ue_context_pP->ue_context.nas_pdu.buffer);
|
||||
|
||||
@@ -3350,51 +3352,6 @@ unsigned int get_ul_bw_mask(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
int is_dl_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_band = *rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->frequencyBandList.list.array[0];
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->downlinkConfigCommon->frequencyInfoDL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
if (common_band>256) {
|
||||
for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
|
||||
if (bandNRinfo->bandNR == common_band && !bandNRinfo->pdsch_256QAM_FR2) return (0);
|
||||
}
|
||||
}
|
||||
else if (cap->phy_Parameters.phy_ParametersFR1 && !cap->phy_Parameters.phy_ParametersFR1->pdsch_256QAM_FR1) return(0);
|
||||
|
||||
// check featureSet
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
if (fs) {
|
||||
// go through DL feature sets and look for one with current SCS
|
||||
for (int i=0;i<fs->featureSetsDownlinkPerCC->list.count;i++) {
|
||||
if (fs->featureSetsDownlinkPerCC->list.array[i]->supportedSubcarrierSpacingDL == common_scs &&
|
||||
fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL &&
|
||||
*fs->featureSetsDownlinkPerCC->list.array[i]->supportedModulationOrderDL == NR_ModulationOrder_qam256) return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int is_ul_256QAM_supported(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_band = *rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->frequencyBandList->list.array[0];
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
for (int i=0;i<cap->rf_Parameters.supportedBandListNR.list.count;i++) {
|
||||
NR_BandNR_t *bandNRinfo = cap->rf_Parameters.supportedBandListNR.list.array[i];
|
||||
if (bandNRinfo->bandNR == common_band && !bandNRinfo->pusch_256QAM) return (0);
|
||||
}
|
||||
|
||||
// check featureSet
|
||||
NR_FeatureSets_t *fs=cap->featureSets;
|
||||
if (fs) {
|
||||
// go through UL feature sets and look for one with current SCS
|
||||
for (int i=0;i<fs->featureSetsUplinkPerCC->list.count;i++) {
|
||||
if (fs->featureSetsUplinkPerCC->list.array[i]->supportedSubcarrierSpacingUL == common_scs &&
|
||||
fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL &&
|
||||
*fs->featureSetsUplinkPerCC->list.array[i]->supportedModulationOrderUL == NR_ModulationOrder_qam256) return(1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int get_ul_mimo_layersCB(gNB_RRC_INST *rrc,NR_UE_NR_Capability_t *cap) {
|
||||
int common_scs = rrc->carrier.servingcellconfigcommon->uplinkConfigCommon->frequencyInfoUL->scs_SpecificCarrierList.list.array[0]->subcarrierSpacing;
|
||||
|
||||
@@ -3464,11 +3421,9 @@ void nr_rrc_subframe_process(protocol_ctxt_t *const ctxt_pP, const int CC_id) {
|
||||
}
|
||||
|
||||
if (ue_context_p->ue_context.UE_Capability_nr) {
|
||||
fprintf(fd,"NR RRC UE cap: BW DL %x. BW UL %x, 256 QAM DL %s, 256 QAM UL %s, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n",
|
||||
fprintf(fd,"NR RRC UE cap: BW DL %x. BW UL %x, DL MIMO Layers %d UL MIMO Layers (CB) %d UL MIMO Layers (nonCB) %d\n",
|
||||
get_dl_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
get_ul_bw_mask(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
is_dl_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
|
||||
is_ul_256QAM_supported(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr) == 1 ? "yes" : "no",
|
||||
get_dl_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
get_ul_mimo_layersCB(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr),
|
||||
get_ul_mimo_layers(RC.nrrrc[0],ue_context_p->ue_context.UE_Capability_nr));
|
||||
|
||||
@@ -65,6 +65,9 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
AssertFatal(servingcellconfigcommon!=NULL,"servingcellconfigcommon is null\n");
|
||||
AssertFatal(secondaryCellGroup!=NULL,"secondaryCellGroup is null\n");
|
||||
|
||||
if(uecap == NULL)
|
||||
LOG_E(RRC,"No UE Capabilities available when programming default CellGroup in NSA\n");
|
||||
|
||||
// This assert will never happen in the current implementation because NUMBER_OF_UE_MAX = 4.
|
||||
// However, if in the future NUMBER_OF_UE_MAX is increased, it will be necessary to improve the allocation of SRS resources,
|
||||
// where the startPosition = 2 or 3 and sl160 = 17, 17, 27 ... 157 only give us 30 different allocations.
|
||||
@@ -338,12 +341,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1;
|
||||
if (!get_softmodem_params()->use_256qam_table) {
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table=NULL;
|
||||
} else {
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table));
|
||||
*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256;
|
||||
}
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->mcs_Table=NULL;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI));
|
||||
*secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1;
|
||||
secondaryCellGroup->spCellConfig->spCellConfigDedicated->initialDownlinkBWP->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling;
|
||||
@@ -607,43 +605,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1;
|
||||
if (!get_softmodem_params()->use_256qam_table) {
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL;
|
||||
} else {
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table));
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256;
|
||||
}
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI));
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling));
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize =
|
||||
calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize));
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.choice.staticBundling->bundleSize = NR_PDSCH_Config__prb_BundlingType__staticBundling__bundleSize_wideband;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToAddModList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->zp_CSI_RS_ResourceToReleaseList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->aperiodic_ZP_CSI_RS_ResourceSetsToAddModList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->aperiodic_ZP_CSI_RS_ResourceSetsToReleaseList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToAddModList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->sp_ZP_CSI_RS_ResourceSetsToReleaseList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->p_ZP_CSI_RS_ResourceSet=NULL;
|
||||
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->tci_StatesToReleaseList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->vrb_ToPRB_Interleaver=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->resourceAllocation=NR_PDSCH_Config__resourceAllocation_resourceAllocationType1;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_TimeDomainAllocationList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->pdsch_AggregationFactor=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternToAddModList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternToReleaseList=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup1=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rateMatchPatternGroup2=NULL;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->rbg_Size=NR_PDSCH_Config__rbg_Size_config1;
|
||||
if (!get_softmodem_params()->use_256qam_table) {
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table=NULL;
|
||||
} else {
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = calloc(1, sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table));
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->mcs_Table = NR_PDSCH_Config__mcs_Table_qam256;
|
||||
}
|
||||
set_dl_mcs_table(bwp->bwp_Common->genericParameters.subcarrierSpacing, uecap, bwp->bwp_Dedicated, servingcellconfigcommon);
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = calloc(1,sizeof(*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI));
|
||||
*bwp->bwp_Dedicated->pdsch_Config->choice.setup->maxNrofCodeWordsScheduledByDCI = NR_PDSCH_Config__maxNrofCodeWordsScheduledByDCI_n1;
|
||||
bwp->bwp_Dedicated->pdsch_Config->choice.setup->prb_BundlingType.present = NR_PDSCH_Config__prb_BundlingType_PR_staticBundling;
|
||||
@@ -746,8 +708,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco
|
||||
pusch_Config->pusch_TimeDomainAllocationList = NULL;
|
||||
pusch_Config->pusch_AggregationFactor=NULL;
|
||||
pusch_Config->mcs_Table=NULL;
|
||||
pusch_Config->mcs_TableTransformPrecoder=NULL;
|
||||
pusch_Config->transformPrecoder= NULL;
|
||||
pusch_Config->mcs_TableTransformPrecoder=NULL;
|
||||
/* if msg3_transformprecoding is set in conf file - pusch config should not disable it */
|
||||
if (servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) {
|
||||
pusch_Config->transformPrecoder=calloc(1,sizeof(*pusch_Config->transformPrecoder));
|
||||
|
||||
@@ -1,607 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file pad_list.c
|
||||
* \brief list management primimtives
|
||||
* \author Mohamed Said MOSLI BOUKSIAA, Lionel GAUTHIER, Navid Nikaein
|
||||
* \date 2012 - 2014
|
||||
* \version 0.5
|
||||
* @ingroup util
|
||||
*/
|
||||
//#define LIST_C
|
||||
//#define NULL 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "pad_list.h"
|
||||
//#include <mpi.h>
|
||||
|
||||
|
||||
void job_list_init (Job_List_t *listP) {
|
||||
listP->tail = NULL;
|
||||
listP->head = NULL;
|
||||
listP->nb_elements = 0;
|
||||
}
|
||||
|
||||
void event_list_init (Event_List_t *listP) {
|
||||
listP->tail = NULL;
|
||||
listP->head = NULL;
|
||||
listP->nb_elements = 0;
|
||||
}
|
||||
|
||||
void pkt_list_init (Packet_OTG_List_t *listP) {
|
||||
listP->tail = NULL;
|
||||
listP->head = NULL;
|
||||
listP->nb_elements = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void job_list_free (Job_List_t *listP) {
|
||||
Job_elt_t *le;
|
||||
|
||||
while ((le = job_list_remove_head (listP))) {
|
||||
free(le);
|
||||
}
|
||||
}
|
||||
|
||||
void event_list_free (Event_List_t *listP) {
|
||||
Event_elt_t *le;
|
||||
|
||||
while ((le = event_list_remove_head (listP))) {
|
||||
free(le);
|
||||
}
|
||||
}
|
||||
|
||||
void pkt_list_free (Packet_OTG_List_t *listP) {
|
||||
Packet_otg_elt_t *le;
|
||||
|
||||
while ((le = pkt_list_remove_head (listP))) {
|
||||
free(le);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Job_elt_t *job_list_get_head (Job_List_t *listP) {
|
||||
return listP->head;
|
||||
}
|
||||
|
||||
Event_elt_t *event_list_get_head (Event_List_t *listP) {
|
||||
return listP->head;
|
||||
}
|
||||
|
||||
Packet_otg_elt_t *pkt_list_get_head (Packet_OTG_List_t *listP) {
|
||||
return listP->head;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* remove an element from head of a list
|
||||
* @param pointer on targeted list
|
||||
* @return pointer on removed Job_elt_t
|
||||
*/
|
||||
Job_elt_t *job_list_remove_head (Job_List_t *listP) {
|
||||
// access optimisation
|
||||
Job_elt_t *head;
|
||||
head = listP->head;
|
||||
|
||||
// almost one element
|
||||
if (head != NULL) {
|
||||
listP->head = head->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
// if only one element, update tail
|
||||
if (listP->head == NULL) {
|
||||
listP->tail = NULL;
|
||||
} else {
|
||||
head->next = NULL;
|
||||
}
|
||||
} else {
|
||||
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
Event_elt_t *event_list_remove_head (Event_List_t *listP) {
|
||||
// access optimisation
|
||||
Event_elt_t *head;
|
||||
head = listP->head;
|
||||
|
||||
// almost one element
|
||||
if (head != NULL) {
|
||||
listP->head = head->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
// if only one element, update tail
|
||||
if (listP->head == NULL) {
|
||||
listP->tail = NULL;
|
||||
} else {
|
||||
head->next = NULL;
|
||||
}
|
||||
} else {
|
||||
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
Packet_otg_elt_t *pkt_list_remove_head (Packet_OTG_List_t *listP) {
|
||||
// access optimisation
|
||||
Packet_otg_elt_t *head;
|
||||
head = listP->head;
|
||||
|
||||
// almost one element
|
||||
if (head != NULL) {
|
||||
listP->head = head->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
// if only one element, update tail
|
||||
if (listP->head == NULL) {
|
||||
listP->tail = NULL;
|
||||
} else {
|
||||
head->next = NULL;
|
||||
}
|
||||
} else {
|
||||
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Job_elt_t *job_list_remove_element (Job_elt_t *elementP, Job_List_t *listP) {
|
||||
// access optimisation;
|
||||
Job_elt_t *head;
|
||||
|
||||
if (elementP != NULL) {
|
||||
// test head
|
||||
head = listP->head;
|
||||
|
||||
if (listP->head == elementP) {
|
||||
// almost one element
|
||||
if (head != NULL) {
|
||||
listP->head = head->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
// if only one element, update tail
|
||||
if (listP->head == NULL) {
|
||||
listP->tail = NULL;
|
||||
} else {
|
||||
head->next = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (head) {
|
||||
if (head->next == elementP) {
|
||||
head->next = elementP->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
if (listP->tail == elementP) {
|
||||
listP->tail = head;
|
||||
}
|
||||
|
||||
return elementP;
|
||||
} else {
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elementP;
|
||||
}
|
||||
|
||||
Event_elt_t *event_list_remove_element (Event_elt_t *elementP, Event_List_t *listP) {
|
||||
// access optimisation;
|
||||
Event_elt_t *head;
|
||||
|
||||
if (elementP != NULL) {
|
||||
// test head
|
||||
head = listP->head;
|
||||
|
||||
if (listP->head == elementP) {
|
||||
// almost one element
|
||||
if (head != NULL) {
|
||||
listP->head = head->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
// if only one element, update tail
|
||||
if (listP->head == NULL) {
|
||||
listP->tail = NULL;
|
||||
} else {
|
||||
head->next = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (head) {
|
||||
if (head->next == elementP) {
|
||||
head->next = elementP->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
if (listP->tail == elementP) {
|
||||
listP->tail = head;
|
||||
}
|
||||
|
||||
return elementP;
|
||||
} else {
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elementP;
|
||||
}
|
||||
|
||||
Packet_otg_elt_t *pkt_list_remove_element (Packet_otg_elt_t *elementP, Packet_OTG_List_t *listP) {
|
||||
// access optimisation;
|
||||
Packet_otg_elt_t *head;
|
||||
|
||||
if (elementP != NULL) {
|
||||
// test head
|
||||
head = listP->head;
|
||||
|
||||
if (listP->head == elementP) {
|
||||
// almost one element
|
||||
if (head != NULL) {
|
||||
listP->head = head->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
// if only one element, update tail
|
||||
if (listP->head == NULL) {
|
||||
listP->tail = NULL;
|
||||
} else {
|
||||
head->next = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (head) {
|
||||
if (head->next == elementP) {
|
||||
head->next = elementP->next;
|
||||
listP->nb_elements = listP->nb_elements - 1;
|
||||
|
||||
if (listP->tail == elementP) {
|
||||
listP->tail = head;
|
||||
}
|
||||
|
||||
return elementP;
|
||||
} else {
|
||||
head = head->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elementP;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* add an element to the beginning of a list
|
||||
* @param pointer on targeted list
|
||||
* @return pointer on removed Job_elt_t
|
||||
*/
|
||||
|
||||
void job_list_add_head (Job_elt_t *elementP, Job_List_t *listP) {
|
||||
// access optimisation;
|
||||
Job_elt_t *head;
|
||||
|
||||
if (elementP != NULL) {
|
||||
head = listP->head;
|
||||
listP->nb_elements = listP->nb_elements + 1;
|
||||
|
||||
// almost one element
|
||||
if (head == NULL) {
|
||||
listP->head = elementP;
|
||||
listP->tail = elementP;
|
||||
} else {
|
||||
elementP->next = head;
|
||||
listP->head = elementP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void event_list_add_head (Event_elt_t *elementP, Event_List_t *listP) {
|
||||
// access optimisation;
|
||||
Event_elt_t *head;
|
||||
|
||||
if (elementP != NULL) {
|
||||
head = listP->head;
|
||||
listP->nb_elements = listP->nb_elements + 1;
|
||||
|
||||
// almost one element
|
||||
if (head == NULL) {
|
||||
listP->head = elementP;
|
||||
listP->tail = elementP;
|
||||
} else {
|
||||
elementP->next = head;
|
||||
listP->head = elementP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pkt_list_add_head (Packet_otg_elt_t *elementP, Packet_OTG_List_t *listP) {
|
||||
// access optimisation;
|
||||
Packet_otg_elt_t *head;
|
||||
|
||||
if (elementP != NULL) {
|
||||
head = listP->head;
|
||||
listP->nb_elements = listP->nb_elements + 1;
|
||||
|
||||
// almost one element
|
||||
if (head == NULL) {
|
||||
listP->head = elementP;
|
||||
listP->tail = elementP;
|
||||
} else {
|
||||
elementP->next = head;
|
||||
listP->head = elementP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void event_list_add_element (Event_elt_t *elementP, Event_elt_t *previous, Event_List_t *listP) {
|
||||
// access optimisation;
|
||||
Event_elt_t *next;
|
||||
|
||||
if (elementP != NULL && previous != NULL) {
|
||||
elementP->next = NULL;
|
||||
next = previous->next;
|
||||
listP->nb_elements = listP->nb_elements + 1;
|
||||
|
||||
// almost one element
|
||||
if (next == NULL) {
|
||||
previous->next = elementP;
|
||||
listP->tail = elementP;
|
||||
} else {
|
||||
elementP->next = previous->next;
|
||||
previous->next = elementP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/*
|
||||
* add an element to the end of a list
|
||||
* @param pointer on targeted list
|
||||
* @return pointer on removed Job_elt_t
|
||||
*/
|
||||
void job_list_add_tail_eurecom (Job_elt_t *elementP, Job_List_t *listP) {
|
||||
Job_elt_t *tail;
|
||||
|
||||
if (elementP != NULL) {
|
||||
// access optimisation
|
||||
listP->nb_elements = listP->nb_elements + 1;
|
||||
elementP->next = NULL;
|
||||
tail = listP->tail;
|
||||
|
||||
// almost one element
|
||||
if (tail == NULL) {
|
||||
listP->head = elementP;
|
||||
} else {
|
||||
tail->next = elementP;
|
||||
}
|
||||
|
||||
listP->tail = elementP;
|
||||
} else {
|
||||
//msg("[CNT_LIST][ERROR] add_cnt_tail() element NULL\n");
|
||||
}
|
||||
}
|
||||
|
||||
void event_list_add_tail_eurecom (Event_elt_t *elementP, Event_List_t *listP) {
|
||||
Event_elt_t *tail;
|
||||
|
||||
if (elementP != NULL) {
|
||||
// access optimisation
|
||||
listP->nb_elements = listP->nb_elements + 1;
|
||||
elementP->next = NULL;
|
||||
tail = listP->tail;
|
||||
|
||||
// almost one element
|
||||
if (tail == NULL) {
|
||||
listP->head = elementP;
|
||||
} else {
|
||||
tail->next = elementP;
|
||||
}
|
||||
|
||||
listP->tail = elementP;
|
||||
} else {
|
||||
//msg("[CNT_LIST][ERROR] add_cnt_tail() element NULL\n");
|
||||
}
|
||||
}
|
||||
|
||||
void pkt_list_add_tail_eurecom (Packet_otg_elt_t *elementP, Packet_OTG_List_t *listP) {
|
||||
Packet_otg_elt_t *tail;
|
||||
|
||||
if (elementP != NULL) {
|
||||
// access optimisation
|
||||
listP->nb_elements = listP->nb_elements + 1;
|
||||
elementP->next = NULL;
|
||||
tail = listP->tail;
|
||||
|
||||
// almost one element
|
||||
if (tail == NULL) {
|
||||
listP->head = elementP;
|
||||
} else {
|
||||
tail->next = elementP;
|
||||
}
|
||||
|
||||
listP->tail = elementP;
|
||||
} else {
|
||||
//msg("[CNT_LIST][ERROR] add_cnt_tail() element NULL\n");
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void job_list_add_list (Job_List_t *sublistP, Job_List_t *listP) {
|
||||
if (sublistP) {
|
||||
if (sublistP->head) {
|
||||
// access optimisation
|
||||
Job_elt_t *tail;
|
||||
tail = listP->tail;
|
||||
|
||||
// almost one element
|
||||
if (tail == NULL) {
|
||||
listP->head = sublistP->head;
|
||||
} else {
|
||||
tail->next = sublistP->head;
|
||||
}
|
||||
|
||||
listP->tail = sublistP->tail;
|
||||
// clear sublist
|
||||
sublistP->head = NULL;
|
||||
sublistP->tail = NULL;
|
||||
listP->nb_elements = listP->nb_elements + sublistP->nb_elements;
|
||||
sublistP->nb_elements = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void event_list_add_list (Event_List_t *sublistP, Event_List_t *listP) {
|
||||
if (sublistP) {
|
||||
if (sublistP->head) {
|
||||
// access optimisation
|
||||
Event_elt_t *tail;
|
||||
tail = listP->tail;
|
||||
|
||||
// almost one element
|
||||
if (tail == NULL) {
|
||||
listP->head = sublistP->head;
|
||||
} else {
|
||||
tail->next = sublistP->head;
|
||||
}
|
||||
|
||||
listP->tail = sublistP->tail;
|
||||
// clear sublist
|
||||
sublistP->head = NULL;
|
||||
sublistP->tail = NULL;
|
||||
listP->nb_elements = listP->nb_elements + sublistP->nb_elements;
|
||||
sublistP->nb_elements = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pkt_list_add_list (Packet_OTG_List_t *sublistP, Packet_OTG_List_t *listP) {
|
||||
if (sublistP) {
|
||||
if (sublistP->head) {
|
||||
// access optimisation
|
||||
Packet_otg_elt_t *tail;
|
||||
tail = listP->tail;
|
||||
|
||||
// almost one element
|
||||
if (tail == NULL) {
|
||||
listP->head = sublistP->head;
|
||||
} else {
|
||||
tail->next = sublistP->head;
|
||||
}
|
||||
|
||||
listP->tail = sublistP->tail;
|
||||
// clear sublist
|
||||
sublistP->head = NULL;
|
||||
sublistP->tail = NULL;
|
||||
listP->nb_elements = listP->nb_elements + sublistP->nb_elements;
|
||||
sublistP->nb_elements = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void job_list_display (Job_List_t *listP) {
|
||||
//Correct the output once the content of struct Job is fixed
|
||||
/*Job_elt_t *cursor;
|
||||
unsigned short nb_elements = 0;
|
||||
|
||||
if (listP) {
|
||||
cursor = listP->head;
|
||||
if (cursor) {
|
||||
while (cursor != NULL) {
|
||||
if (cursor->job.type == eNB_DL)
|
||||
printf ("DL eNB From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
|
||||
else if (cursor->job.type == UE_DL)
|
||||
printf ("DL UE From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
|
||||
else if (cursor->job.type == UE_UL)
|
||||
printf ("UL UE From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
|
||||
else if (cursor->job.type == eNB_UL)
|
||||
printf ("UL eNB From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
|
||||
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
|
||||
cursor = cursor->next;
|
||||
nb_elements++;
|
||||
}
|
||||
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
|
||||
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
|
||||
}
|
||||
} else {
|
||||
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
|
||||
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
|
||||
}*/
|
||||
}
|
||||
|
||||
void event_list_display (Event_List_t *listP) {
|
||||
Event_elt_t *cursor;
|
||||
unsigned short nb_elements = 0;
|
||||
|
||||
if (listP) {
|
||||
cursor = listP->head;
|
||||
|
||||
if (cursor) {
|
||||
while (cursor != NULL) {
|
||||
printf ("Ev (%d,%d)\n", (cursor->event).type, (cursor->event).frame);
|
||||
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
|
||||
cursor = cursor->next;
|
||||
nb_elements++;
|
||||
}
|
||||
|
||||
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
|
||||
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
|
||||
}
|
||||
} else {
|
||||
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
|
||||
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
|
||||
}
|
||||
}
|
||||
|
||||
void pkt_list_display (Packet_OTG_List_t *listP) {
|
||||
Packet_otg_elt_t *cursor;
|
||||
unsigned short nb_elements = 0;
|
||||
|
||||
if (listP) {
|
||||
cursor = listP->head;
|
||||
|
||||
if (cursor) {
|
||||
while (cursor != NULL) {
|
||||
printf ("Pkt (DST %d, RB %ld)\n", (cursor->otg_pkt).dst_id, (cursor->otg_pkt).rb_id);
|
||||
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
|
||||
cursor = cursor->next;
|
||||
nb_elements++;
|
||||
}
|
||||
|
||||
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
|
||||
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
|
||||
}
|
||||
} else {
|
||||
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
|
||||
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
|
||||
}
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file pad_list.c
|
||||
* \brief list management primimtives
|
||||
* \author Mohamed Said MOSLI BOUKSIAA, Lionel GAUTHIER, Navid Nikaein
|
||||
* \date 2012 - 2014
|
||||
* \version 0.5
|
||||
* @ingroup util
|
||||
*/
|
||||
|
||||
#ifndef __list_H__
|
||||
#define __list_H__
|
||||
|
||||
#include "types.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
typedef struct Job_List_s {
|
||||
Job_elt_t *head;
|
||||
Job_elt_t *tail;
|
||||
int nb_elements;
|
||||
} Job_List_t;
|
||||
|
||||
typedef struct Event_List_s {
|
||||
Event_elt_t *head;
|
||||
Event_elt_t *tail;
|
||||
int nb_elements;
|
||||
} Event_List_t;
|
||||
|
||||
typedef struct Packet_OTG_List_s {
|
||||
Packet_otg_elt_t *head;
|
||||
Packet_otg_elt_t *tail;
|
||||
int nb_elements;
|
||||
} Packet_OTG_List_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void job_list_init (Job_List_t*);
|
||||
void job_list_free (Job_List_t* listP);
|
||||
Job_elt_t* job_list_get_head (Job_List_t*);
|
||||
Job_elt_t* job_list_remove_head (Job_List_t* );
|
||||
Job_elt_t* job_list_remove_element (Job_elt_t*, Job_List_t*);
|
||||
void job_list_add_head (Job_elt_t* , Job_List_t* );
|
||||
void job_list_add_tail_eurecom (Job_elt_t* , Job_List_t* );
|
||||
void job_list_add_list (Job_List_t* , Job_List_t* );
|
||||
void job_list_display (Job_List_t* );
|
||||
|
||||
void event_list_init (Event_List_t*);
|
||||
void event_list_free (Event_List_t* listP);
|
||||
Event_elt_t* event_list_get_head (Event_List_t*);
|
||||
Event_elt_t* event_list_remove_head (Event_List_t* );
|
||||
Event_elt_t* event_list_remove_element (Event_elt_t*, Event_List_t*);
|
||||
void event_list_add_head (Event_elt_t* , Event_List_t* );
|
||||
void event_list_add_element (Event_elt_t* , Event_elt_t* , Event_List_t* );
|
||||
void event_list_add_tail_eurecom (Event_elt_t* , Event_List_t* );
|
||||
void event_list_add_list (Event_List_t* , Event_List_t* );
|
||||
void event_list_display (Event_List_t* );
|
||||
|
||||
void pkt_list_init (Packet_OTG_List_t*);
|
||||
void pkt_list_free (Packet_OTG_List_t* listP);
|
||||
Packet_otg_elt_t* pkt_list_get_head (Packet_OTG_List_t*);
|
||||
Packet_otg_elt_t* pkt_list_remove_head (Packet_OTG_List_t* );
|
||||
Packet_otg_elt_t* pkt_list_remove_element (Packet_otg_elt_t*, Packet_OTG_List_t*);
|
||||
void pkt_list_add_head (Packet_otg_elt_t* , Packet_OTG_List_t* );
|
||||
void pkt_list_add_element (Packet_otg_elt_t* , Packet_otg_elt_t* , Packet_OTG_List_t* );
|
||||
void pkt_list_add_tail_eurecom (Packet_otg_elt_t* , Packet_OTG_List_t* );
|
||||
void pkt_list_add_list (Packet_OTG_List_t* , Packet_OTG_List_t* );
|
||||
void pkt_list_display (Packet_OTG_List_t* );
|
||||
|
||||
#endif
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*! \file pad_list.c
|
||||
* \brief list management primimtives
|
||||
* \author Mohamed Said MOSLI BOUKSIAA, Lionel GAUTHIER, Navid Nikaein
|
||||
* \date 2012 - 2014
|
||||
* \version 0.5
|
||||
* @ingroup util
|
||||
*/
|
||||
|
||||
#ifndef __FIFO_TYPES_H__
|
||||
#define __FIFO_TYPES_H__
|
||||
#include "platform_types.h"
|
||||
|
||||
/* Types regrouping both user-defined and regular events */
|
||||
typedef enum {
|
||||
MIN_ET=0,
|
||||
OAI_ET=MIN_ET, // config events
|
||||
SYS_ET,
|
||||
TOPO_ET,
|
||||
APP_ET,
|
||||
EMU_ET,
|
||||
DL_ET, // frame events
|
||||
UL_ET,
|
||||
S_ET,
|
||||
PHY_ET, // protocol events
|
||||
MAC_ET,
|
||||
RLC_ET,
|
||||
PDCP_ET,
|
||||
RRC_ET,
|
||||
MAX_ET
|
||||
} Event_Type_t;
|
||||
|
||||
/* decomposition of node functions into jobs for a given event */
|
||||
typedef enum Job_type_e { JT_OTG, JT_PDCP, JT_PHY_MAC, JT_INIT_SYNC, JT_DL, JT_UL, RN_DL, RN_UL, JT_END} Job_Type_t;
|
||||
|
||||
typedef enum Operation_Type_e { READ, WRITE, RESET} Operation_Type_t;
|
||||
|
||||
typedef struct Job_s {
|
||||
enum Job_type_e type;
|
||||
int exe_time; /* execution time at the worker*/
|
||||
int nid; /* node id*/
|
||||
eNB_flag_t eNB_flag;
|
||||
frame_t frame;
|
||||
int last_slot;
|
||||
int next_slot;
|
||||
int ctime;
|
||||
} Job_t;
|
||||
|
||||
typedef struct Signal_buffers_s { // (s = transmit, r,r0 = receive)
|
||||
double **s_re;
|
||||
double **s_im;
|
||||
double **r_re;
|
||||
double **r_im;
|
||||
double **r_re0;
|
||||
double **r_im0;
|
||||
} Signal_buffers_t;
|
||||
|
||||
/*!\brief sybframe type : DL, UL, SF, */
|
||||
|
||||
typedef struct Packet_otg_s {
|
||||
unsigned int sdu_buffer_size;
|
||||
unsigned char *sdu_buffer;
|
||||
module_id_t module_id;
|
||||
rb_id_t rb_id;
|
||||
module_id_t dst_id;
|
||||
boolean_t is_ue;
|
||||
pdcp_transmission_mode_t mode;
|
||||
} Packet_otg_t;
|
||||
|
||||
typedef struct {
|
||||
Event_Type_t type;
|
||||
enum Operation_Type_e optype; //op
|
||||
char *key;
|
||||
void *value;
|
||||
frame_t frame;
|
||||
int ue;
|
||||
int lcid;
|
||||
} Event_t;
|
||||
|
||||
/*typedef struct Global_Time {
|
||||
uint32_t frame;
|
||||
int32_t slot;
|
||||
int32_t last_slot;
|
||||
int32_t next_slot;
|
||||
double time_s;
|
||||
double time_ms;
|
||||
};*/
|
||||
|
||||
|
||||
|
||||
typedef struct Packet_otg_elt_s {
|
||||
struct Packet_otg_elt_s *next;
|
||||
struct Packet_otg_elt_s *previous;
|
||||
Packet_otg_t otg_pkt;
|
||||
} Packet_otg_elt_t;
|
||||
|
||||
typedef struct Job_element_s {
|
||||
struct Job_element_s *next;
|
||||
Job_t job;
|
||||
} Job_elt_t;
|
||||
|
||||
typedef struct Event_element_s {
|
||||
struct Event_element_s *next;
|
||||
struct Event_element_s *previous;
|
||||
Event_t event;
|
||||
} Event_elt_t;
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
-162
@@ -1,162 +0,0 @@
|
||||
Active_eNBs = ( "eNB_Eurecom_LTEBox");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
eNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
eNB_ID = 0xe00;
|
||||
|
||||
cell_type = "CELL_MACRO_ENB";
|
||||
|
||||
eNB_name = "eNB_Eurecom_LTEBox";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } );
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
component_carriers = (
|
||||
{
|
||||
frame_type = "FDD";
|
||||
tdd_config = 3;
|
||||
tdd_config_s = 0;
|
||||
prefix_type = "NORMAL";
|
||||
eutra_band = 7;
|
||||
downlink_frequency = 2660000000L;
|
||||
uplink_frequency_offset = -120000000;
|
||||
Nid_cell = 0;
|
||||
N_RB_DL = 25;
|
||||
Nid_cell_mbsfn = 0;
|
||||
nb_antennas_tx = 1;
|
||||
nb_antennas_rx = 1;
|
||||
tx_gain = 90;
|
||||
rx_gain = 120;
|
||||
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 = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 0;
|
||||
pdsch_referenceSignalPower = -26;
|
||||
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 = -90;
|
||||
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;
|
||||
}
|
||||
);
|
||||
|
||||
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.188.2.2";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
ENB_INTERFACE_NAME_FOR_S1_MME = "tun2";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.188.2.2/24";
|
||||
|
||||
ENB_INTERFACE_NAME_FOR_S1U = "lo";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "127.0.0.1/24";
|
||||
ENB_PORT_FOR_S1U = 2153; # Spec 2152
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
gtpu_log_level ="info";
|
||||
udp_log_level ="info";
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
@@ -1,159 +0,0 @@
|
||||
Active_eNBs = ( "eNB_Eurecom_LTEBox");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
|
||||
eNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
eNB_ID = 0xe00;
|
||||
|
||||
cell_type = "CELL_MACRO_ENB";
|
||||
|
||||
eNB_name = "eNB_Eurecom_LTEBox";
|
||||
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1;
|
||||
plmn_list = ( { mcc = 208; mnc = 95; mnc_length = 2; } );
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
component_carriers = (
|
||||
{
|
||||
frame_type = "FDD";
|
||||
tdd_config = 3;
|
||||
tdd_config_s = 0;
|
||||
prefix_type = "NORMAL";
|
||||
eutra_band = 7;
|
||||
downlink_frequency = 2660000000L;
|
||||
uplink_frequency_offset = -120000000;
|
||||
Nid_cell = 0;
|
||||
N_RB_DL = 25;
|
||||
Nid_cell_mbsfn = 0;
|
||||
nb_antennas_tx = 1;
|
||||
nb_antennas_rx = 1;
|
||||
tx_gain = 90;
|
||||
rx_gain = 120;
|
||||
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 = 1;
|
||||
pucch_nCS_AN = 0;
|
||||
pucch_n1_AN = 0;
|
||||
pdsch_referenceSignalPower = -26;
|
||||
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 = -90;
|
||||
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;
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
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.12.17";
|
||||
ipv6 = "192:168:30::17";
|
||||
active = "yes";
|
||||
preference = "ipv4";
|
||||
}
|
||||
);
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
ENB_INTERFACE_NAME_FOR_S1_MME = "eth0";
|
||||
ENB_IPV4_ADDRESS_FOR_S1_MME = "192.168.12.213/24";
|
||||
|
||||
ENB_INTERFACE_NAME_FOR_S1U = "eth0";
|
||||
ENB_IPV4_ADDRESS_FOR_S1U = "192.168.12.213/24";
|
||||
ENB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="debug";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
};
|
||||
|
||||
}
|
||||
);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,684 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
generate_scenario.c
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <libconfig.h>
|
||||
#include <inttypes.h>
|
||||
#include <getopt.h>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/debugXML.h>
|
||||
#include <libxml/HTMLtree.h>
|
||||
#include <libxml/xmlIO.h>
|
||||
#include <libxml/DOCBparser.h>
|
||||
#include <libxml/xinclude.h>
|
||||
#include <libxml/catalog.h>
|
||||
#include <libxslt/xslt.h>
|
||||
#include <libxslt/xsltInternals.h>
|
||||
#include <libxslt/transform.h>
|
||||
#include <libxslt/xsltutils.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "generate_scenario.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs"
|
||||
|
||||
#define ENB_CONFIG_STRING_ENB_LIST "eNBs"
|
||||
#define ENB_CONFIG_STRING_ENB_ID "eNB_ID"
|
||||
#define ENB_CONFIG_STRING_CELL_TYPE "cell_type"
|
||||
#define ENB_CONFIG_STRING_ENB_NAME "eNB_name"
|
||||
|
||||
#define ENB_CONFIG_STRING_TRACKING_AREA_CODE "tracking_area_code"
|
||||
#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE "mobile_country_code"
|
||||
#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE "mobile_network_code"
|
||||
|
||||
|
||||
#define ENB_CONFIG_STRING_MME_IP_ADDRESS "mme_ip_address"
|
||||
#define ENB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4"
|
||||
#define ENB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6"
|
||||
#define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active"
|
||||
#define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference"
|
||||
|
||||
#define ENB_CONFIG_STRING_SCTP_CONFIG "SCTP"
|
||||
#define ENB_CONFIG_STRING_SCTP_INSTREAMS "SCTP_INSTREAMS"
|
||||
#define ENB_CONFIG_STRING_SCTP_OUTSTREAMS "SCTP_OUTSTREAMS"
|
||||
|
||||
#define ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES"
|
||||
#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME"
|
||||
#define ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME "ENB_IPV4_ADDRESS_FOR_S1_MME"
|
||||
#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U "ENB_INTERFACE_NAME_FOR_S1U"
|
||||
#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U"
|
||||
#define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U"
|
||||
|
||||
|
||||
#define ENB_CONFIG_MAX_XSLT_PARAMS 32
|
||||
|
||||
Enb_properties_array_t g_enb_properties;
|
||||
char *g_test_dir = NULL;
|
||||
char *g_pdml_in_origin = NULL;
|
||||
extern int xmlLoadExtDtdDefaultValue;
|
||||
|
||||
#define GENERATE_PDML_FILE 1
|
||||
#define GENERATE_SCENARIO 2
|
||||
|
||||
#define GS_IS_FILE 1
|
||||
#define GS_IS_DIR 2
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// test if file exist in current directory
|
||||
int is_file_exists( const char const * file_nameP, const char const *file_roleP)
|
||||
{
|
||||
struct stat s;
|
||||
int err = stat(file_nameP, &s);
|
||||
if(-1 == err) {
|
||||
if(ENOENT == errno) {
|
||||
fprintf(stderr, "Please provide a valid %s, %s does not exist\n", file_roleP, file_nameP);
|
||||
} else {
|
||||
perror("stat");
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
if(S_ISREG(s.st_mode)) {
|
||||
return GS_IS_FILE;
|
||||
} else if(S_ISDIR(s.st_mode)) {
|
||||
return GS_IS_DIR;
|
||||
} else {
|
||||
fprintf(stderr, "Please provide a valid test %s, %s exists but is not found valid\n", file_roleP, file_nameP);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int strip_extension(char *in_filename)
|
||||
{
|
||||
static const uint8_t name_min_len = 1;
|
||||
static const uint8_t max_ext_len = 5; // .pdml !
|
||||
fprintf(stdout, "strip_extension %s\n", in_filename);
|
||||
|
||||
if (NULL != in_filename) {
|
||||
/* Check chars starting at end of string to find last '.' */
|
||||
for (ssize_t i = strlen(in_filename); i >= name_min_len; i--) {
|
||||
if (in_filename[i] == '.') {
|
||||
in_filename[i] = '\0';
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
// return number of splitted items
|
||||
int split_path( char * pathP, char *** resP)
|
||||
{
|
||||
char * saveptr1;
|
||||
char * p = strtok_r (pathP, "/", &saveptr1);
|
||||
int n_spaces = 0;
|
||||
|
||||
/// split string and append tokens to 'res'
|
||||
while (p) {
|
||||
*resP = realloc (*resP, sizeof (char*) * ++n_spaces);
|
||||
AssertFatal (*resP, "realloc failed");
|
||||
(*resP)[n_spaces-1] = p;
|
||||
p = strtok_r (NULL, "/", &saveptr1);
|
||||
}
|
||||
return n_spaces;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int generate_test_scenario(const char const * test_nameP, const char const * pdml_in_basenameP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
//int fd_pdml_in;
|
||||
xsltStylesheetPtr cur = NULL;
|
||||
xmlDocPtr doc, res;
|
||||
FILE *test_scenario_file = NULL;
|
||||
const char test_scenario_filename[NAME_MAX];
|
||||
const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS];
|
||||
int nb_params = 0;
|
||||
int i,j;
|
||||
char astring[1024];
|
||||
char *astring2 = NULL;
|
||||
struct in_addr addr;
|
||||
|
||||
memset(test_scenario_filename, 0, sizeof(test_scenario_filename));
|
||||
memset(astring, 0, sizeof(astring));
|
||||
if (getcwd(astring, sizeof(astring)) != NULL) {
|
||||
fprintf(stdout, "working in %s directory\n", astring);
|
||||
} else {
|
||||
perror("getcwd() error");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
xmlSubstituteEntitiesDefault(1);
|
||||
xmlLoadExtDtdDefaultValue = 1;
|
||||
cur = xsltParseStylesheetFile("/usr/share/oai/xsl/generic_scenario.xsl");
|
||||
if (NULL == cur) {
|
||||
AssertFatal (0, "Could not parse stylesheet file /usr/share/oai/xsl/generic_scenario.xsl!\n");
|
||||
} else {
|
||||
fprintf(stdout, "XSLT style sheet: /usr/share/oai/xsl/generic_scenario.xsl\n");
|
||||
}
|
||||
|
||||
doc = xmlParseFile(pdml_in_basenameP);
|
||||
if (NULL == doc) {
|
||||
AssertFatal (0, "Could not parse pdml file %s!\n", pdml_in_basenameP);
|
||||
} else {
|
||||
fprintf(stdout, "pdml file: %s\n", pdml_in_basenameP);
|
||||
}
|
||||
params[nb_params++] = "test_name";
|
||||
sprintf(astring, "%s", pdml_in_basenameP);
|
||||
if (strip_extension(astring) > 0) {
|
||||
astring2 = strdup(astring);
|
||||
sprintf(astring, "\"%s\"", astring2);
|
||||
free(astring2);
|
||||
astring2 = NULL;
|
||||
} else {
|
||||
fprintf(stderr, "Assigning test name failed: %s\n", astring);
|
||||
}
|
||||
params[nb_params++] = strdup(astring);
|
||||
|
||||
for (i = 0; i < g_enb_properties.number; i++) {
|
||||
// eNB S1-C IPv4 address
|
||||
sprintf(astring, "enb%d_s1c", i);
|
||||
params[nb_params++] = strdup(astring);
|
||||
addr.s_addr = g_enb_properties.properties[i]->enb_ipv4_address_for_S1_MME;
|
||||
sprintf(astring, "\"%s\"", inet_ntoa(addr));
|
||||
params[nb_params++] = strdup(astring);
|
||||
|
||||
// MME S1-C IPv4 address
|
||||
for (j = 0; j < g_enb_properties.properties[i]->nb_mme; j++) {
|
||||
sprintf(astring, "mme%d_s1c_%d", i, j);
|
||||
params[nb_params++] = strdup(astring);
|
||||
AssertFatal (g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address,
|
||||
"Only support MME IPv4 address\n");
|
||||
sprintf(astring, "\"%s\"", g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address);
|
||||
params[nb_params++] = strdup(astring);
|
||||
}
|
||||
}
|
||||
params[nb_params] = NULL;
|
||||
res = xsltApplyStylesheet(cur, doc, params);
|
||||
if (NULL != res) {
|
||||
// since pdml filename is not relative (no path), just filename in current directory we can safely remove
|
||||
sprintf(test_scenario_filename,"%s",pdml_in_basenameP);
|
||||
if (strip_extension(test_scenario_filename) > 0) {
|
||||
strcat(test_scenario_filename, ".xml");
|
||||
test_scenario_file = fopen( test_scenario_filename, "w+");
|
||||
if (NULL != test_scenario_file) {
|
||||
xsltSaveResultToFile(test_scenario_file, res, cur);
|
||||
fclose(test_scenario_file);
|
||||
fprintf(stdout, "Wrote test scenario to %s\n", test_scenario_filename);
|
||||
} else {
|
||||
fprintf(stderr, "Error in fopen(%s)\n", test_scenario_filename);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error in strip_extension()\n");
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error in xsltApplyStylesheet()\n");
|
||||
}
|
||||
xsltFreeStylesheet(cur);
|
||||
xmlFreeDoc(res);
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
xsltCleanupGlobals();
|
||||
xmlCleanupParser();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void enb_config_display(void)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int i;
|
||||
|
||||
printf( "\n----------------------------------------------------------------------\n");
|
||||
printf( " ENB CONFIG FILE CONTENT LOADED:\n");
|
||||
printf( "----------------------------------------------------------------------\n");
|
||||
for (i = 0; i < g_enb_properties.number; i++) {
|
||||
printf( "ENB CONFIG for instance %d:\n\n", i);
|
||||
printf( "\teNB name: \t%s\n",g_enb_properties.properties[i]->eNB_name);
|
||||
printf( "\teNB ID: \t%"PRIu32"\n",g_enb_properties.properties[i]->eNB_id);
|
||||
printf( "\tCell type: \t%s\n",g_enb_properties.properties[i]->cell_type == CELL_MACRO_ENB ? "CELL_MACRO_ENB":"CELL_HOME_ENB");
|
||||
printf( "\tTAC: \t%"PRIu16"\n",g_enb_properties.properties[i]->tac);
|
||||
printf( "\tMCC: \t%"PRIu16"\n",g_enb_properties.properties[i]->mcc);
|
||||
|
||||
if (g_enb_properties.properties[i]->mnc_digit_length == 3) {
|
||||
printf( "\tMNC: \t%03"PRIu16"\n",g_enb_properties.properties[i]->mnc);
|
||||
} else {
|
||||
printf( "\tMNC: \t%02"PRIu16"\n",g_enb_properties.properties[i]->mnc);
|
||||
}
|
||||
printf( "\n--------------------------------------------------------\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef LIBCONFIG_LONG
|
||||
#define libconfig_int long
|
||||
#else
|
||||
#define libconfig_int int
|
||||
#endif
|
||||
//------------------------------------------------------------------------------
|
||||
void enb_config_init(const char const * lib_config_file_name_pP)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
config_t cfg;
|
||||
config_setting_t *setting = NULL;
|
||||
config_setting_t *subsetting = NULL;
|
||||
config_setting_t *setting_mme_addresses = NULL;
|
||||
config_setting_t *setting_mme_address = NULL;
|
||||
config_setting_t *setting_enb = NULL;
|
||||
int num_enb_properties = 0;
|
||||
int enb_properties_index = 0;
|
||||
int num_enbs = 0;
|
||||
int num_mme_address = 0;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int parse_errors = 0;
|
||||
libconfig_int enb_id = 0;
|
||||
const char* cell_type = NULL;
|
||||
const char* tac = 0;
|
||||
const char* enb_name = NULL;
|
||||
const char* mcc = 0;
|
||||
const char* mnc = 0;
|
||||
char* ipv4 = NULL;
|
||||
char* ipv6 = NULL;
|
||||
char* active = NULL;
|
||||
char* preference = NULL;
|
||||
const char* active_enb[EPC_TEST_SCENARIO_MAX_ENB];
|
||||
char* enb_interface_name_for_S1U = NULL;
|
||||
char* enb_ipv4_address_for_S1U = NULL;
|
||||
libconfig_int enb_port_for_S1U = 0;
|
||||
char* enb_interface_name_for_S1_MME = NULL;
|
||||
char* enb_ipv4_address_for_S1_MME = NULL;
|
||||
char *address = NULL;
|
||||
char *cidr = NULL;
|
||||
|
||||
|
||||
AssertFatal (lib_config_file_name_pP != NULL,
|
||||
"Bad parameter lib_config_file_name_pP %s , must reference a valid eNB config file\n",
|
||||
lib_config_file_name_pP);
|
||||
|
||||
memset((char*)active_enb, 0 , EPC_TEST_SCENARIO_MAX_ENB * sizeof(char*));
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
/* Read the file. If there is an error, report it and exit. */
|
||||
if (! config_read_file(&cfg, lib_config_file_name_pP)) {
|
||||
config_destroy(&cfg);
|
||||
AssertFatal (0, "Failed to parse eNB configuration file %s!\n", lib_config_file_name_pP);
|
||||
}
|
||||
|
||||
// Get list of active eNBs, (only these will be configured)
|
||||
setting = config_lookup(&cfg, ENB_CONFIG_STRING_ACTIVE_ENBS);
|
||||
|
||||
if (setting != NULL) {
|
||||
num_enbs = config_setting_length(setting);
|
||||
|
||||
for (i = 0; i < num_enbs; i++) {
|
||||
setting_enb = config_setting_get_elem(setting, i);
|
||||
active_enb[i] = config_setting_get_string (setting_enb);
|
||||
AssertFatal (active_enb[i] != NULL,
|
||||
"Failed to parse config file %s, %dth attribute %s \n",
|
||||
lib_config_file_name_pP, i, ENB_CONFIG_STRING_ACTIVE_ENBS);
|
||||
active_enb[i] = strdup(active_enb[i]);
|
||||
num_enb_properties += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a list of all eNBs. */
|
||||
setting = config_lookup(&cfg, ENB_CONFIG_STRING_ENB_LIST);
|
||||
|
||||
if (setting != NULL) {
|
||||
enb_properties_index = g_enb_properties.number;
|
||||
parse_errors = 0;
|
||||
num_enbs = config_setting_length(setting);
|
||||
|
||||
for (i = 0; i < num_enbs; i++) {
|
||||
setting_enb = config_setting_get_elem(setting, i);
|
||||
|
||||
if (! config_setting_lookup_int(setting_enb, ENB_CONFIG_STRING_ENB_ID, &enb_id)) {
|
||||
/* Calculate a default eNB ID */
|
||||
# if defined(ENABLE_USE_MME)
|
||||
uint32_t hash;
|
||||
|
||||
hash = s1ap_generate_eNB_id ();
|
||||
enb_id = i + (hash & 0xFFFF8);
|
||||
# else
|
||||
enb_id = i;
|
||||
# endif
|
||||
}
|
||||
|
||||
if ( !( config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_CELL_TYPE, &cell_type)
|
||||
&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_ENB_NAME, &enb_name)
|
||||
&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_TRACKING_AREA_CODE, &tac)
|
||||
&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE, &mcc)
|
||||
&& config_setting_lookup_string(setting_enb, ENB_CONFIG_STRING_MOBILE_NETWORK_CODE, &mnc)
|
||||
|
||||
|
||||
)
|
||||
) {
|
||||
AssertError (0, parse_errors ++,
|
||||
"Failed to parse eNB configuration file %s, %d th enb\n",
|
||||
lib_config_file_name_pP, i);
|
||||
continue; // FIXME this prevents segfaults below, not sure what happens after function exit
|
||||
}
|
||||
|
||||
// search if in active list
|
||||
for (j=0; j < num_enb_properties; j++) {
|
||||
if (strcmp(active_enb[j], enb_name) == 0) {
|
||||
g_enb_properties.properties[enb_properties_index] = calloc(1, sizeof(Enb_properties_t));
|
||||
|
||||
g_enb_properties.properties[enb_properties_index]->eNB_id = enb_id;
|
||||
|
||||
if (strcmp(cell_type, "CELL_MACRO_ENB") == 0) {
|
||||
g_enb_properties.properties[enb_properties_index]->cell_type = CELL_MACRO_ENB;
|
||||
} else if (strcmp(cell_type, "CELL_HOME_ENB") == 0) {
|
||||
g_enb_properties.properties[enb_properties_index]->cell_type = CELL_HOME_ENB;
|
||||
} else {
|
||||
AssertError (0, parse_errors ++,
|
||||
"Failed to parse eNB configuration file %s, enb %d unknown value \"%s\" for cell_type choice: CELL_MACRO_ENB or CELL_HOME_ENB !\n",
|
||||
lib_config_file_name_pP, i, cell_type);
|
||||
}
|
||||
|
||||
g_enb_properties.properties[enb_properties_index]->eNB_name = strdup(enb_name);
|
||||
g_enb_properties.properties[enb_properties_index]->tac = (uint16_t)atoi(tac);
|
||||
g_enb_properties.properties[enb_properties_index]->mcc = (uint16_t)atoi(mcc);
|
||||
g_enb_properties.properties[enb_properties_index]->mnc = (uint16_t)atoi(mnc);
|
||||
g_enb_properties.properties[enb_properties_index]->mnc_digit_length = strlen(mnc);
|
||||
AssertFatal((g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 2) ||
|
||||
(g_enb_properties.properties[enb_properties_index]->mnc_digit_length == 3),
|
||||
"BAD MNC DIGIT LENGTH %d",
|
||||
g_enb_properties.properties[i]->mnc_digit_length);
|
||||
|
||||
|
||||
setting_mme_addresses = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_MME_IP_ADDRESS);
|
||||
num_mme_address = config_setting_length(setting_mme_addresses);
|
||||
g_enb_properties.properties[enb_properties_index]->nb_mme = 0;
|
||||
|
||||
for (j = 0; j < num_mme_address; j++) {
|
||||
setting_mme_address = config_setting_get_elem(setting_mme_addresses, j);
|
||||
|
||||
if ( !(
|
||||
config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV4_ADDRESS, (const char **)&ipv4)
|
||||
&& config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IPV6_ADDRESS, (const char **)&ipv6)
|
||||
&& config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE, (const char **)&active)
|
||||
&& config_setting_lookup_string(setting_mme_address, ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE, (const char **)&preference)
|
||||
)
|
||||
) {
|
||||
AssertError (0, parse_errors ++,
|
||||
"Failed to parse eNB configuration file %s, %d th enb %d th mme address !\n",
|
||||
lib_config_file_name_pP, i, j);
|
||||
continue; // FIXME will prevent segfaults below, not sure what happens at function exit...
|
||||
}
|
||||
|
||||
g_enb_properties.properties[enb_properties_index]->nb_mme += 1;
|
||||
|
||||
g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4_address = strdup(ipv4);
|
||||
g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6_address = strdup(ipv6);
|
||||
|
||||
if (strcmp(active, "yes") == 0) {
|
||||
g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].active = 1;
|
||||
} // else { (calloc)
|
||||
|
||||
if (strcmp(preference, "ipv4") == 0) {
|
||||
g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1;
|
||||
} else if (strcmp(preference, "ipv6") == 0) {
|
||||
g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1;
|
||||
} else if (strcmp(preference, "no") == 0) {
|
||||
g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv4 = 1;
|
||||
g_enb_properties.properties[enb_properties_index]->mme_ip_address[j].ipv6 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NETWORK_INTERFACES
|
||||
subsetting = config_setting_get_member (setting_enb, ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG);
|
||||
|
||||
if (subsetting != NULL) {
|
||||
if ( (
|
||||
config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME,
|
||||
(const char **)&enb_interface_name_for_S1_MME)
|
||||
&& config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME,
|
||||
(const char **)&enb_ipv4_address_for_S1_MME)
|
||||
&& config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U,
|
||||
(const char **)&enb_interface_name_for_S1U)
|
||||
&& config_setting_lookup_string( subsetting, ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U,
|
||||
(const char **)&enb_ipv4_address_for_S1U)
|
||||
&& config_setting_lookup_int(subsetting, ENB_CONFIG_STRING_ENB_PORT_FOR_S1U,
|
||||
&enb_port_for_S1U)
|
||||
)
|
||||
) {
|
||||
g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1U = strdup(enb_interface_name_for_S1U);
|
||||
cidr = enb_ipv4_address_for_S1U;
|
||||
address = strtok(cidr, "/");
|
||||
|
||||
if (address) {
|
||||
IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1U, "BAD IP ADDRESS FORMAT FOR eNB S1_U !\n" );
|
||||
}
|
||||
|
||||
g_enb_properties.properties[enb_properties_index]->enb_port_for_S1U = enb_port_for_S1U;
|
||||
|
||||
g_enb_properties.properties[enb_properties_index]->enb_interface_name_for_S1_MME = strdup(enb_interface_name_for_S1_MME);
|
||||
cidr = enb_ipv4_address_for_S1_MME;
|
||||
address = strtok(cidr, "/");
|
||||
|
||||
if (address) {
|
||||
IPV4_STR_ADDR_TO_INT_NWBO ( address, g_enb_properties.properties[enb_properties_index]->enb_ipv4_address_for_S1_MME, "BAD IP ADDRESS FORMAT FOR eNB S1_MME !\n" );
|
||||
}
|
||||
}
|
||||
} // if (subsetting != NULL) {
|
||||
enb_properties_index += 1;
|
||||
} // if (strcmp(active_enb[j], enb_name) == 0)
|
||||
} // for (j=0; j < num_enb_properties; j++)
|
||||
} // for (i = 0; i < num_enbs; i++)
|
||||
} // if (setting != NULL) {
|
||||
|
||||
g_enb_properties.number += num_enb_properties;
|
||||
|
||||
|
||||
AssertFatal (parse_errors == 0,
|
||||
"Failed to parse eNB configuration file %s, found %d error%s !\n",
|
||||
lib_config_file_name_pP, parse_errors, parse_errors > 1 ? "s" : "");
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void usage (
|
||||
int argc,
|
||||
char *argv[])
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
fprintf (stdout, "Please report any bug to: %s\n",PACKAGE_BUGREPORT);
|
||||
fprintf (stdout, "Usage: %s [options]\n\n", argv[0]);
|
||||
fprintf (stdout, "\n");
|
||||
fprintf (stdout, "Mandatory options:\n");
|
||||
fprintf (stdout, "\t-c | --enb-conf-file <file> Provide the old eNB config file for generating a copy of the original test\n");
|
||||
fprintf (stdout, "\t-d | --test-dir <dir> Directory where a set of files related to a particular test are located\n");
|
||||
fprintf (stdout, "\t-p | --pdml <file> File name (with no path) in 'test-dir' directory of an original scenario that has to be reworked (IP addresses) with new testbed\n");
|
||||
fprintf (stdout, "\n");
|
||||
fprintf (stdout, "Other options:\n");
|
||||
fprintf (stdout, "\t-h | --help Print this help and return\n");
|
||||
fprintf (stdout, "\t-v | --version Print informations about the version of this executable\n");
|
||||
fprintf (stdout, "\n");
|
||||
fprintf (stdout, "Example of generate_scenario use case: \n");
|
||||
fprintf (stdout, "\n");
|
||||
fprintf (stdout, " Generate a generix xml scenario from a captured pcap file: \n");
|
||||
fprintf (stdout, " +---------------------+ \n");
|
||||
fprintf (stdout, " |captured pcap-ng file| \n");
|
||||
fprintf (stdout, " +----------+----------+ \n");
|
||||
fprintf (stdout, " |\n");
|
||||
fprintf (stdout, " mme_test_s1_pcap2pdml --pcap_file <`captured pcap-ng file`>\n");
|
||||
fprintf (stdout, " |\n");
|
||||
fprintf (stdout, " +--------V----------+ +--------------------+\n");
|
||||
fprintf (stdout, " |'pdml-in-orig' file| |'enb-conf-file' file|\n");
|
||||
fprintf (stdout, " +--------+----------+ +--------------------+\n");
|
||||
fprintf (stdout, " | |\n");
|
||||
fprintf (stdout, " +----------------------------+\n");
|
||||
fprintf (stdout, " |\n");
|
||||
fprintf (stdout, " generate_scenario -d <dir> -p <'pdml-in-orig' file> -c <'enb-conf-file' file> \n");
|
||||
fprintf (stdout, " |\n");
|
||||
fprintf (stdout, " +------------V--------------+\n");
|
||||
fprintf (stdout, " +'xml-test-scenario' file |\n");
|
||||
fprintf (stdout, " +---------------------------+\n");
|
||||
fprintf (stdout, "\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
config_parse_opt_line (
|
||||
int argc,
|
||||
char *argv[])
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int option;
|
||||
int rv = 0;
|
||||
char *enb_config_file_name = NULL;
|
||||
char *pdml_in_file_name = NULL;
|
||||
char *test_dir_name = NULL;
|
||||
|
||||
enum long_option_e {
|
||||
LONG_OPTION_START = 0x100, /* Start after regular single char options */
|
||||
LONG_OPTION_ENB_CONF_FILE,
|
||||
LONG_OPTION_PDML,
|
||||
LONG_OPTION_TEST_DIR,
|
||||
LONG_OPTION_HELP,
|
||||
LONG_OPTION_VERSION,
|
||||
};
|
||||
|
||||
static struct option long_options[] = {
|
||||
{"enb-conf-file", required_argument, 0, LONG_OPTION_ENB_CONF_FILE},
|
||||
{"pdml ", required_argument, 0, LONG_OPTION_PDML},
|
||||
{"test-dir", required_argument, 0, LONG_OPTION_TEST_DIR},
|
||||
{"help", no_argument, 0, LONG_OPTION_HELP},
|
||||
{"version", no_argument, 0, LONG_OPTION_VERSION},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Parsing command line
|
||||
*/
|
||||
while ((option = getopt_long (argc, argv, "vhp:n:c:s:d:", long_options, NULL)) != -1) {
|
||||
switch (option) {
|
||||
case LONG_OPTION_ENB_CONF_FILE:
|
||||
case 'c':
|
||||
if (optarg) {
|
||||
enb_config_file_name = optarg;
|
||||
printf("eNB config file name is %s\n", enb_config_file_name);
|
||||
rv |= GENERATE_SCENARIO;
|
||||
}
|
||||
break;
|
||||
|
||||
case LONG_OPTION_PDML:
|
||||
case 'p':
|
||||
if (optarg) {
|
||||
pdml_in_file_name = strdup(optarg);
|
||||
printf("PDML input file name is %s\n", pdml_in_file_name);
|
||||
rv |= GENERATE_SCENARIO;
|
||||
}
|
||||
break;
|
||||
|
||||
case LONG_OPTION_TEST_DIR:
|
||||
case 'd':
|
||||
if (optarg) {
|
||||
test_dir_name = strdup(optarg);
|
||||
if (is_file_exists(test_dir_name, "test dirname") != GS_IS_DIR) {
|
||||
fprintf(stderr, "Please provide a valid test dirname, %s is not a valid directory name\n", test_dir_name);
|
||||
exit(1);
|
||||
}
|
||||
printf("Test dir name is %s\n", test_dir_name);
|
||||
}
|
||||
break;
|
||||
|
||||
case LONG_OPTION_VERSION:
|
||||
case 'v':
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
exit (0);
|
||||
break;
|
||||
|
||||
case LONG_OPTION_HELP:
|
||||
case 'h':
|
||||
default:
|
||||
usage (argc, argv);
|
||||
exit (0);
|
||||
}
|
||||
}
|
||||
if (NULL == test_dir_name) {
|
||||
fprintf(stderr, "Please provide a valid test dirname\n");
|
||||
exit(1);
|
||||
}
|
||||
g_test_dir = test_dir_name; test_dir_name = NULL;
|
||||
if (chdir(g_test_dir) != 0) {
|
||||
fprintf(stderr, "Error: chdir %s returned %s\n", g_test_dir, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (rv & GENERATE_SCENARIO) {
|
||||
if (NULL == enb_config_file_name) {
|
||||
fprintf(stderr, "Error: please provide the original eNB config file name that should be in %s\n", g_test_dir);
|
||||
}
|
||||
if (is_file_exists(enb_config_file_name, "ENB config file") != GS_IS_FILE) {
|
||||
fprintf(stderr, "Error: eNB config file name %s is not found in dir %s\n", enb_config_file_name, g_test_dir);
|
||||
}
|
||||
enb_config_init(enb_config_file_name);
|
||||
//enb_config_display();
|
||||
|
||||
if (NULL == pdml_in_file_name) {
|
||||
fprintf(stderr, "Error: please provide the PDML file name that should be in %s\n", g_test_dir);
|
||||
}
|
||||
if (is_file_exists(pdml_in_file_name, "PDML file") != GS_IS_FILE) {
|
||||
fprintf(stderr, "Error: PDML file name %s is not found in dir %s\n", pdml_in_file_name, g_test_dir);
|
||||
}
|
||||
g_pdml_in_origin = pdml_in_file_name; pdml_in_file_name = NULL;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int main( int argc, char **argv )
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int actions = 0;
|
||||
|
||||
memset((char*) &g_enb_properties, 0 , sizeof(g_enb_properties));
|
||||
|
||||
actions = config_parse_opt_line (argc, argv); //Command-line options
|
||||
if (actions & GENERATE_SCENARIO) {
|
||||
generate_test_scenario(g_test_dir, g_pdml_in_origin);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
generate_scenario.h
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
#ifndef GENERATE_SCENARIO_H_
|
||||
#define GENERATE_SCENARIO_H_
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "commonDef.h"
|
||||
#include "platform_types.h"
|
||||
#include "platform_constants.h"
|
||||
#include "s1ap_messages_types.h"
|
||||
#include "SystemInformationBlockType2.h"
|
||||
|
||||
#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\
|
||||
struct in_addr inp;\
|
||||
if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\
|
||||
AssertFatal (0, MeSsAgE);\
|
||||
} else {\
|
||||
NwBo = inp.s_addr;\
|
||||
}\
|
||||
} while (0);
|
||||
|
||||
/** @defgroup _enb_app ENB APP
|
||||
* @ingroup _oai2
|
||||
* @{
|
||||
*/
|
||||
|
||||
// Hard to find a defined value for max enb...
|
||||
#define EPC_TEST_SCENARIO_MAX_ENB 4
|
||||
|
||||
|
||||
typedef struct mme_ip_address_s {
|
||||
unsigned ipv4:1;
|
||||
unsigned ipv6:1;
|
||||
unsigned active:1;
|
||||
char *ipv4_address;
|
||||
char *ipv6_address;
|
||||
} mme_ip_address_t;
|
||||
|
||||
typedef struct Enb_properties_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;
|
||||
|
||||
/* Nb of MME to connect to */
|
||||
uint8_t nb_mme;
|
||||
/* List of MME to connect to */
|
||||
mme_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
|
||||
|
||||
int sctp_in_streams;
|
||||
int sctp_out_streams;
|
||||
|
||||
char *enb_interface_name_for_S1U;
|
||||
in_addr_t enb_ipv4_address_for_S1U;
|
||||
tcp_udp_port_t enb_port_for_S1U;
|
||||
|
||||
char *enb_interface_name_for_S1_MME;
|
||||
in_addr_t enb_ipv4_address_for_S1_MME;
|
||||
|
||||
} Enb_properties_t;
|
||||
|
||||
typedef struct Enb_properties_array_s {
|
||||
int number;
|
||||
Enb_properties_t *properties[EPC_TEST_SCENARIO_MAX_ENB];
|
||||
} Enb_properties_array_t;
|
||||
|
||||
void enb_config_init(const char const * lib_config_file_name_pP);
|
||||
|
||||
#endif /* ENB_CONFIG_H_ */
|
||||
/** @} */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
play_scenario.h
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
#ifndef PLAY_SCENARIO_H_
|
||||
#define PLAY_SCENARIO_H_
|
||||
# include <time.h>
|
||||
# include <stdint.h>
|
||||
# include <libxml/tree.h>
|
||||
# include <libxml/xpath.h>
|
||||
# include <netinet/in.h>
|
||||
|
||||
#include "S1AP-PDU.h"
|
||||
#include "s1ap_ies_defs.h"
|
||||
#include "play_scenario_s1ap_eNB_defs.h"
|
||||
#include "hashtable.h"
|
||||
#include "asn_compare.h"
|
||||
|
||||
#define ET_XPATH_EXPRESSION_MAX_LENGTH 400
|
||||
|
||||
|
||||
// powers of 2
|
||||
#define ET_BIT_MASK_MATCH_SCTP_STREAM 1
|
||||
#define ET_BIT_MASK_MATCH_SCTP_SSN 2
|
||||
//#define ET_BIT_MASK_MATCH_S1AP_ 2
|
||||
|
||||
#define MAX_ENB 16
|
||||
|
||||
#define ENB_CONFIG_STRING_ACTIVE_ENBS "Active_eNBs"
|
||||
|
||||
#define ENB_CONFIG_STRING_ENB_LIST "eNBs"
|
||||
#define ENB_CONFIG_STRING_ENB_ID "eNB_ID"
|
||||
#define ENB_CONFIG_STRING_CELL_TYPE "cell_type"
|
||||
#define ENB_CONFIG_STRING_ENB_NAME "eNB_name"
|
||||
|
||||
#define ENB_CONFIG_STRING_TRACKING_AREA_CODE "tracking_area_code"
|
||||
#define ENB_CONFIG_STRING_MOBILE_COUNTRY_CODE "mobile_country_code"
|
||||
#define ENB_CONFIG_STRING_MOBILE_NETWORK_CODE "mobile_network_code"
|
||||
|
||||
|
||||
#define ENB_CONFIG_STRING_MME_IP_ADDRESS "mme_ip_address"
|
||||
#define ENB_CONFIG_STRING_MME_IPV4_ADDRESS "ipv4"
|
||||
#define ENB_CONFIG_STRING_MME_IPV6_ADDRESS "ipv6"
|
||||
#define ENB_CONFIG_STRING_MME_IP_ADDRESS_ACTIVE "active"
|
||||
#define ENB_CONFIG_STRING_MME_IP_ADDRESS_PREFERENCE "preference"
|
||||
|
||||
#define ENB_CONFIG_STRING_SCTP_CONFIG "SCTP"
|
||||
#define ENB_CONFIG_STRING_SCTP_INSTREAMS "SCTP_INSTREAMS"
|
||||
#define ENB_CONFIG_STRING_SCTP_OUTSTREAMS "SCTP_OUTSTREAMS"
|
||||
|
||||
#define ENB_CONFIG_STRING_NETWORK_INTERFACES_CONFIG "NETWORK_INTERFACES"
|
||||
#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1_MME "ENB_INTERFACE_NAME_FOR_S1_MME"
|
||||
#define ENB_CONFIG_STRING_ENB_IPV4_ADDRESS_FOR_S1_MME "ENB_IPV4_ADDRESS_FOR_S1_MME"
|
||||
#define ENB_CONFIG_STRING_ENB_INTERFACE_NAME_FOR_S1U "ENB_INTERFACE_NAME_FOR_S1U"
|
||||
#define ENB_CONFIG_STRING_ENB_IPV4_ADDR_FOR_S1U "ENB_IPV4_ADDRESS_FOR_S1U"
|
||||
#define ENB_CONFIG_STRING_ENB_PORT_FOR_S1U "ENB_PORT_FOR_S1U"
|
||||
|
||||
|
||||
typedef struct shift_packet_s {
|
||||
unsigned int frame_number; // original frame number
|
||||
int shift_seconds;
|
||||
int shift_microseconds;
|
||||
int single; // shift timing only for this packet (not also following packets)
|
||||
struct shift_packet_s *next;
|
||||
} shift_packet_t;
|
||||
|
||||
|
||||
typedef struct mme_ip_address_s {
|
||||
unsigned ipv4:1;
|
||||
unsigned ipv6:1;
|
||||
unsigned active:1;
|
||||
char *ipv4_address;
|
||||
char *ipv6_address;
|
||||
} mme_ip_address_t;
|
||||
|
||||
#define IPV4_STR_ADDR_TO_INT_NWBO(AdDr_StR,NwBo,MeSsAgE ) do {\
|
||||
struct in_addr inp;\
|
||||
if ( inet_aton(AdDr_StR, &inp ) < 0 ) {\
|
||||
AssertFatal (0, MeSsAgE);\
|
||||
} else {\
|
||||
NwBo = inp.s_addr;\
|
||||
}\
|
||||
} while (0);
|
||||
|
||||
|
||||
typedef struct Enb_properties_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;
|
||||
|
||||
|
||||
|
||||
/* Physical parameters */
|
||||
|
||||
int16_t Nid_cell[1+MAX_NUM_CCs];// for testing, change later
|
||||
/* Nb of MME to connect to */
|
||||
uint8_t nb_mme;
|
||||
/* List of MME to connect to */
|
||||
mme_ip_address_t mme_ip_address[S1AP_MAX_NB_MME_IP_ADDRESS];
|
||||
|
||||
int sctp_in_streams;
|
||||
int sctp_out_streams;
|
||||
|
||||
char *enb_interface_name_for_S1U;
|
||||
in_addr_t enb_ipv4_address_for_S1U;
|
||||
tcp_udp_port_t enb_port_for_S1U;
|
||||
|
||||
char *enb_interface_name_for_S1_MME;
|
||||
in_addr_t enb_ipv4_address_for_S1_MME;
|
||||
|
||||
} Enb_properties_t;
|
||||
|
||||
typedef struct Enb_properties_array_s {
|
||||
int number;
|
||||
Enb_properties_t *properties[MAX_ENB];
|
||||
} Enb_properties_array_t;
|
||||
|
||||
# define ET_ENB_REGISTER_RETRY_DELAY 3
|
||||
# define ET_FSM_STATE_WAITING_RX_EVENT_DELAY_SEC 15
|
||||
|
||||
typedef enum {
|
||||
ET_PACKET_STATUS_START = 0,
|
||||
ET_PACKET_STATUS_NONE = ET_PACKET_STATUS_START,
|
||||
ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT,
|
||||
ET_PACKET_STATUS_SCHEDULED_FOR_SENDING,
|
||||
ET_PACKET_STATUS_SENT,
|
||||
ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING,
|
||||
ET_PACKET_STATUS_RECEIVED,
|
||||
ET_PACKET_STATUS_END
|
||||
} et_packet_status_t;
|
||||
|
||||
typedef enum {
|
||||
ET_FSM_STATE_START = 0,
|
||||
ET_FSM_STATE_NULL = ET_FSM_STATE_START,
|
||||
ET_FSM_STATE_CONNECTING_S1C,
|
||||
ET_FSM_STATE_WAITING_RX_EVENT,
|
||||
ET_FSM_STATE_WAITING_TX_EVENT,
|
||||
ET_FSM_STATE_RUNNING,
|
||||
ET_FSM_STATE_END
|
||||
} et_fsm_state_t;
|
||||
|
||||
enum COMPARE_ERR_CODE_e;
|
||||
|
||||
typedef enum {
|
||||
ET_ERROR_MATCH_START = COMPARE_ERR_CODE_END,
|
||||
ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE = ET_ERROR_MATCH_START,
|
||||
ET_ERROR_MATCH_PACKET_SCTP_PPID,
|
||||
ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID,
|
||||
ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID,
|
||||
ET_ERROR_MATCH_PACKET_SCTP_SSN,
|
||||
ET_ERROR_MATCH_PACKET_S1AP_PRESENT,
|
||||
ET_ERROR_MATCH_PACKET_S1AP_PROCEDURE_CODE,
|
||||
ET_ERROR_MATCH_PACKET_S1AP_CRITICALITY,
|
||||
ET_ERROR_MATCH_END
|
||||
} et_error_match_code_t;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
ET_PACKET_ACTION_S1C_START = 0,
|
||||
ET_PACKET_ACTION_S1C_NULL = ET_PACKET_ACTION_S1C_START,
|
||||
ET_PACKET_ACTION_S1C_SEND,
|
||||
ET_PACKET_ACTION_S1C_RECEIVE,
|
||||
ET_PACKET_ACTION_S1C_END
|
||||
} et_packet_action_t;
|
||||
|
||||
// from kernel source file 3.19/include/linux/sctp.h
|
||||
typedef enum {
|
||||
SCTP_CID_DATA = 0,
|
||||
SCTP_CID_INIT = 1,
|
||||
SCTP_CID_INIT_ACK = 2,
|
||||
SCTP_CID_SACK = 3,
|
||||
SCTP_CID_HEARTBEAT = 4,
|
||||
SCTP_CID_HEARTBEAT_ACK = 5,
|
||||
SCTP_CID_ABORT = 6,
|
||||
SCTP_CID_SHUTDOWN = 7,
|
||||
SCTP_CID_SHUTDOWN_ACK = 8,
|
||||
SCTP_CID_ERROR = 9,
|
||||
SCTP_CID_COOKIE_ECHO = 10,
|
||||
SCTP_CID_COOKIE_ACK = 11,
|
||||
SCTP_CID_ECN_ECNE = 12,
|
||||
SCTP_CID_ECN_CWR = 13,
|
||||
SCTP_CID_SHUTDOWN_COMPLETE = 14,
|
||||
|
||||
/* AUTH Extension Section 4.1 */
|
||||
SCTP_CID_AUTH = 0x0F,
|
||||
|
||||
/* PR-SCTP Sec 3.2 */
|
||||
SCTP_CID_FWD_TSN = 0xC0,
|
||||
|
||||
/* Use hex, as defined in ADDIP sec. 3.1 */
|
||||
SCTP_CID_ASCONF = 0xC1,
|
||||
SCTP_CID_ASCONF_ACK = 0x80,
|
||||
} sctp_cid_t; /* enum */
|
||||
|
||||
typedef enum {
|
||||
TEST_S1AP_PDU_TYPE_START = 0,
|
||||
TEST_S1AP_PDU_TYPE_UNKNOWN = TEST_S1AP_PDU_TYPE_START,
|
||||
TEST_S1AP_PDU_TYPE_INITIATING,
|
||||
TEST_S1AP_PDU_TYPE_SUCCESSFUL_OUTCOME,
|
||||
TEST_S1AP_PDU_TYPE_UNSUCCESSFUL_OUTCOME,
|
||||
TEST_S1AP_PDU_TYPE_END
|
||||
} et_s1ap_pdu_type_t;
|
||||
|
||||
|
||||
typedef struct et_s1ap_s {
|
||||
//et_s1ap_pdu_type_t pdu_type;
|
||||
S1AP_S1AP_PDU_t pdu; // decoded ASN1 C type: choice of initiatingMessage, successfulOutcome, unsuccessfulOutcome
|
||||
uint16_t xml_stream_pos_offset;
|
||||
uint16_t binary_stream_pos;
|
||||
uint16_t binary_stream_allocated_size;
|
||||
uint8_t *binary_stream;
|
||||
xmlDocPtr doc; // XML representation of the S1AP PDU
|
||||
} et_s1ap_t;
|
||||
|
||||
|
||||
// from kernel source file 3.19/include/linux/sctp.h, Big Endians
|
||||
typedef struct sctp_datahdr_s {
|
||||
uint32_t tsn;
|
||||
uint16_t stream;
|
||||
uint16_t ssn;
|
||||
uint32_t ppid;
|
||||
uint32_t assoc_id; // filled when running scenario
|
||||
et_s1ap_t payload;
|
||||
} sctp_datahdr_t;
|
||||
|
||||
// from kernel source file 3.19/include/linux/sctp.h, Big Endians
|
||||
typedef struct sctp_inithdr {
|
||||
uint32_t init_tag;
|
||||
uint32_t a_rwnd;
|
||||
uint16_t num_outbound_streams;
|
||||
uint16_t num_inbound_streams;
|
||||
uint32_t initial_tsn;
|
||||
uint8_t params[0];
|
||||
} sctp_inithdr_t;
|
||||
|
||||
typedef sctp_inithdr_t sctp_initackhdr_t;
|
||||
|
||||
typedef struct et_sctp_hdr_s {
|
||||
unsigned int src_port;
|
||||
unsigned int dst_port;
|
||||
sctp_cid_t chunk_type;
|
||||
union {
|
||||
sctp_datahdr_t data_hdr;
|
||||
sctp_inithdr_t init_hdr;
|
||||
sctp_initackhdr_t init_ack_hdr;
|
||||
} u;
|
||||
} et_sctp_hdr_t;
|
||||
|
||||
typedef struct et_ip_s {
|
||||
unsigned int address_family; // AF_INET, AF_INET6
|
||||
union {
|
||||
struct in6_addr ipv6;
|
||||
in_addr_t ipv4;
|
||||
} address;
|
||||
char str[INET6_ADDRSTRLEN+1];
|
||||
} et_ip_t;
|
||||
|
||||
typedef struct et_ip_hdr_s {
|
||||
et_ip_t src;
|
||||
et_ip_t dst;
|
||||
} et_ip_hdr_t;
|
||||
|
||||
typedef struct et_packet_s {
|
||||
et_packet_action_t action;
|
||||
struct timeval time_relative_to_first_packet;
|
||||
struct timeval time_relative_to_last_sent_packet;
|
||||
struct timeval time_relative_to_last_received_packet;
|
||||
unsigned int original_frame_number;
|
||||
unsigned int packet_number;
|
||||
instance_t enb_instance;
|
||||
et_ip_hdr_t ip_hdr;
|
||||
et_sctp_hdr_t sctp_hdr;
|
||||
struct et_packet_s *next;
|
||||
|
||||
//scenario running vars
|
||||
et_packet_status_t status;
|
||||
long timer_id; // ITTI timer id for waiting rx packets
|
||||
struct timeval timestamp_packet; // timestamp when rx or tx packet
|
||||
} et_packet_t;
|
||||
|
||||
|
||||
typedef struct sctp_epoll_s {
|
||||
/* Array of events monitored by the task.
|
||||
* By default only one fd is monitored (the one used to received messages
|
||||
* from other tasks).
|
||||
* More events can be suscribed later by the task itself.
|
||||
*/
|
||||
struct epoll_event *events;
|
||||
|
||||
int epoll_nb_events;
|
||||
|
||||
} thread_desc_t;
|
||||
|
||||
typedef struct et_scenario_s {
|
||||
xmlChar *name;
|
||||
et_packet_t *list_packet;
|
||||
//--------------------------
|
||||
// playing scenario
|
||||
//--------------------------
|
||||
Enb_properties_array_t *enb_properties;
|
||||
uint32_t register_enb_pending;
|
||||
uint32_t registered_enb;
|
||||
long enb_register_retry_timer_id;
|
||||
|
||||
|
||||
hash_table_t *hash_mme2association_id;
|
||||
hash_table_t *hash_old_ue_mme_id2ue_mme_id;
|
||||
struct timeval time_last_tx_packet; // Time last sent packet
|
||||
struct timeval time_last_rx_packet; // Time last packet received with all previous scenario RX packet received.
|
||||
et_packet_t *last_rx_packet; // Last packet received with all previous scenario RX packet received.
|
||||
et_packet_t *last_tx_packet; // Last sent packet
|
||||
et_packet_t *next_packet; // Next packet to be handled in the scenario (RX or TX packet)
|
||||
|
||||
int timer_count;
|
||||
} et_scenario_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
ET_EVENT_START = 0,
|
||||
ET_EVENT_INIT = ET_EVENT_START,
|
||||
ET_EVENT_S1C_CONNECTED,
|
||||
ET_EVENT_RX_SCTP_EVENT,
|
||||
ET_EVENT_RX_S1AP,
|
||||
ET_EVENT_RX_PACKET_TIME_OUT,
|
||||
ET_EVENT_TX_TIMED_PACKET,
|
||||
ET_EVENT_TICK,
|
||||
ET_EVENT_END
|
||||
} et_event_code_t;
|
||||
|
||||
typedef struct et_event_init_s {
|
||||
et_scenario_t *scenario;
|
||||
} et_event_init_t;
|
||||
|
||||
typedef struct et_event_s1ap_data_ind_s {
|
||||
sctp_datahdr_t sctp_datahdr;
|
||||
} et_event_s1ap_data_ind_t;
|
||||
|
||||
typedef struct et_event_s1ap_data_req_s {
|
||||
|
||||
} et_event_s1ap_data_req_t;
|
||||
|
||||
typedef struct et_event_s {
|
||||
et_event_code_t code;
|
||||
union {
|
||||
et_event_init_t init;
|
||||
et_event_s1ap_data_ind_t s1ap_data_ind;
|
||||
et_packet_t *tx_timed_packet;
|
||||
et_packet_t *rx_packet_time_out;
|
||||
} u;
|
||||
} et_event_t;
|
||||
|
||||
inline void et_free_pointer(void *p) {if (NULL != p) {free(p);}};
|
||||
|
||||
//-------------------------
|
||||
void et_free_packet(et_packet_t *packet);
|
||||
void et_free_scenario(et_scenario_t *scenario);
|
||||
//-------------------------
|
||||
void et_display_packet_s1ap_data(const et_s1ap_t *const s1ap);
|
||||
void et_display_packet_sctp_init(const sctp_inithdr_t *const sctp);
|
||||
void et_display_packet_sctp_initack(const sctp_initackhdr_t *const sctp);
|
||||
void et_display_packet_sctp_data(const sctp_datahdr_t *const sctp);
|
||||
void et_display_packet_sctp(const et_sctp_hdr_t *const sctp);
|
||||
void et_display_packet_ip(const et_ip_hdr_t *const ip);
|
||||
void et_display_packet(const et_packet_t *const packet);
|
||||
void et_display_scenario(const et_scenario_t *const scenario);
|
||||
//-------------------------
|
||||
int et_s1ap_decode_initiating_message(s1ap_message *message, S1AP_InitiatingMessage_t *initiating_p);
|
||||
int et_s1ap_decode_successful_outcome(s1ap_message *message, S1AP_SuccessfulOutcome_t *successfullOutcome_p);
|
||||
int et_s1ap_decode_unsuccessful_outcome(s1ap_message *message, S1AP_UnsuccessfulOutcome_t *unSuccessfullOutcome_p);
|
||||
int et_s1ap_decode_pdu(S1AP_PDU_t *const pdu, s1ap_message *const message, const uint8_t *const buffer, const uint32_t length);
|
||||
void et_decode_s1ap(et_s1ap_t *const s1ap);
|
||||
//-------------------------
|
||||
int et_s1ap_eNB_compare_assoc_id( struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2);
|
||||
uint32_t et_s1ap_generate_eNB_id(void);
|
||||
uint16_t et_s1ap_eNB_fetch_add_global_cnx_id(void);
|
||||
void et_s1ap_eNB_prepare_internal_data(void);
|
||||
void et_s1ap_eNB_insert_new_instance(s1ap_eNB_instance_t *new_instance_p);
|
||||
struct s1ap_eNB_mme_data_s *et_s1ap_eNB_get_MME(s1ap_eNB_instance_t *instance_p,int32_t assoc_id, uint16_t cnx_id);
|
||||
s1ap_eNB_instance_t *et_s1ap_eNB_get_instance(instance_t instance);
|
||||
void et_s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,uint32_t buffer_length, uint16_t stream);
|
||||
int et_handle_s1ap_mismatch_mme_ue_s1ap_id(et_packet_t *const spacket, et_packet_t *const rx_packet);
|
||||
asn_comp_rval_t *et_s1ap_is_matching(et_s1ap_t *const s1ap1, et_s1ap_t *const s1ap2, const uint32_t constraints);
|
||||
et_packet_t *et_build_packet_from_s1ap_data_ind(et_event_s1ap_data_ind_t *const s1ap_data_ind);
|
||||
int et_scenario_set_packet_received(et_packet_t *const packet);
|
||||
int et_s1ap_process_rx_packet(et_event_s1ap_data_ind_t *const sctp_data_ind);
|
||||
void et_s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *const sctp_data_ind);
|
||||
void et_s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
net_ip_address_t *mme_ip_address,
|
||||
net_ip_address_t *local_ip_addr,
|
||||
uint16_t in_streams,
|
||||
uint16_t out_streams);
|
||||
void et_s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown);
|
||||
void et_s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB);
|
||||
void et_s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||
void *et_s1ap_eNB_task(void *arg);
|
||||
//-------------------------
|
||||
int et_generate_xml_scenario(
|
||||
const char const *xml_in_dir_name,
|
||||
const char const *xml_in_scenario_filename,
|
||||
const char const *enb_config_filename,
|
||||
char const *tsml_out_scenario_filename);
|
||||
//-------------------------
|
||||
void timeval_add (struct timeval *const result, const struct timeval *const a, const struct timeval *const b);
|
||||
int timeval_subtract (struct timeval *const result, struct timeval *const a, struct timeval *const b);
|
||||
void et_scenario_wait_rx_packet(et_packet_t *const packet);
|
||||
void et_scenario_schedule_tx_packet(et_packet_t *packet);
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event);
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event);
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event);
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t event);
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event);
|
||||
et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event);
|
||||
//-------------------------
|
||||
void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t *const s1ap);
|
||||
void et_parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t *const sctp_hdr);
|
||||
void et_parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t *const sctp_hdr);
|
||||
void et_parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t *const sctp_hdr);
|
||||
void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t *const sctp_hdr);
|
||||
et_packet_t *et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node);
|
||||
et_scenario_t *et_generate_scenario(const char *const et_scenario_filename);
|
||||
//-------------------------
|
||||
asn_comp_rval_t *et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message *const m1, s1ap_message *const m2, const uint32_t constraints);
|
||||
void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t *const s1ap, xmlNode *node, const S1AP_MME_UE_S1AP_ID_t new_id);
|
||||
void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t *const s1ap_payload, xmlNodeSetPtr nodes, const S1AP_MME_UE_S1AP_ID_t new_id);
|
||||
int et_s1ap_update_mme_ue_s1ap_id(et_packet_t *const packet, const S1AP_MME_UE_S1AP_ID_t old_id, const S1AP_MME_UE_S1AP_ID_t new_id);
|
||||
//-------------------------
|
||||
asn_comp_rval_t *et_sctp_data_is_matching(sctp_datahdr_t *const sctp1, sctp_datahdr_t *const sctp2, const uint32_t constraints);
|
||||
asn_comp_rval_t *et_sctp_is_matching(et_sctp_hdr_t *const sctp1, et_sctp_hdr_t *const sctp2, const uint32_t constraints);
|
||||
//------------------------------------------------------------------------------
|
||||
void et_print_hex_octets(const unsigned char *const byte_stream, const unsigned long int num);
|
||||
int et_is_file_exists ( const char const *file_nameP, const char const *file_roleP);
|
||||
int et_strip_extension( char *in_filename);
|
||||
void et_get_shift_arg( char *line_argument, shift_packet_t *const shift);
|
||||
int et_split_path ( char *pathP, char *** resP);
|
||||
void et_display_node ( xmlNodePtr node, unsigned int indent);
|
||||
void et_display_tree ( xmlNodePtr node, unsigned int indent);
|
||||
char *et_ip2ip_str(const et_ip_t *const ip);
|
||||
int et_compare_et_ip_to_net_ip_address(const et_ip_t *const ip, const net_ip_address_t *const net_ip);
|
||||
int et_hex2data(unsigned char *const data, const unsigned char *const hexstring, const unsigned int len);
|
||||
sctp_cid_t et_chunk_type_str2cid(const xmlChar *const chunk_type_str);
|
||||
const char *const et_chunk_type_cid2str(const sctp_cid_t chunk_type);
|
||||
const char *const et_error_match2str(const int err);
|
||||
et_packet_action_t et_action_str2et_action_t(const xmlChar *const action);
|
||||
void et_ip_str2et_ip(const xmlChar *const ip_str, et_ip_t *const ip);
|
||||
void et_enb_config_init(const char const *lib_config_file_name_pP);
|
||||
const Enb_properties_array_t *et_enb_config_get(void);
|
||||
void et_eNB_app_register(const Enb_properties_array_t *enb_properties);
|
||||
void *et_eNB_app_task(void *args_p);
|
||||
int et_play_scenario(et_scenario_t *const scenario, const struct shift_packet_s *shifts);
|
||||
|
||||
#endif /* PLAY_SCENARIO_H_ */
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
play_scenario_decode.c
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "platform_types.h"
|
||||
#include "s1ap_eNB_decoder.h"
|
||||
#include "assertions.h"
|
||||
#include "play_scenario.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int et_s1ap_decode_pdu(S1AP_PDU_t *const pdu, const uint8_t *const buffer, const uint32_t length)
|
||||
{
|
||||
asn_dec_rval_t dec_ret;
|
||||
|
||||
DevAssert(buffer != NULL);
|
||||
|
||||
memset((void *)pdu, 0, sizeof(S1AP_S1AP_PDU_t));
|
||||
dec_ret = aper_decode(NULL,
|
||||
&asn_DEF_S1AP_S1AP_PDU,
|
||||
(void **)&pdu,
|
||||
buffer,
|
||||
length,
|
||||
0,
|
||||
0);
|
||||
|
||||
if (dec_ret.code != RC_OK) {
|
||||
S1AP_ERROR("Failed to decode pdu\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return dec_ret.code;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void et_decode_s1ap(et_s1ap_t *const s1ap)
|
||||
{
|
||||
if (NULL != s1ap) {
|
||||
if (et_s1ap_decode_pdu(&s1ap->pdu, s1ap->binary_stream, s1ap->binary_stream_allocated_size) < 0) {
|
||||
AssertFatal (0, "ERROR %s() Cannot decode S1AP message!\n", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,348 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
play_scenario_display.c
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "platform_types.h"
|
||||
#include "assertions.h"
|
||||
#include "s1ap_eNB_decoder.h"
|
||||
#include "play_scenario.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
void et_print_hex_octets(const unsigned char *const byte_stream, const unsigned long int num)
|
||||
{
|
||||
unsigned long octet_index = 0;
|
||||
|
||||
if (byte_stream == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stdout, "+-----+-------------------------------------------------+\n");
|
||||
fprintf(stdout, "| | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n");
|
||||
fprintf(stdout, "+-----+-------------------------------------------------+\n");
|
||||
|
||||
for (octet_index = 0; octet_index < num; octet_index++) {
|
||||
if ((octet_index % 16) == 0) {
|
||||
if (octet_index != 0) {
|
||||
fprintf(stdout, " |\n");
|
||||
}
|
||||
|
||||
fprintf(stdout, " %04lu |", octet_index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print every single octet in hexadecimal form
|
||||
*/
|
||||
fprintf(stdout, " %02x", byte_stream[octet_index]);
|
||||
/*
|
||||
* Align newline and pipes according to the octets in groups of 2
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Append enough spaces and put final pipe
|
||||
*/
|
||||
unsigned char index;
|
||||
|
||||
for (index = octet_index; index < 16; ++index) {
|
||||
fprintf(stdout, " ");
|
||||
}
|
||||
|
||||
fprintf(stdout, " |\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_node(xmlNodePtr node, unsigned int indent)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if (node->type == XML_ELEMENT_NODE) {
|
||||
xmlChar *path = xmlGetNodePath(node);
|
||||
|
||||
for (i=0; i<indent; i++) {
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
if (node->children != NULL && node->children->type == XML_TEXT_NODE) {
|
||||
xmlChar *content = xmlNodeGetContent(node);
|
||||
printf("%s -> %s\n", path, content);
|
||||
xmlFree(content);
|
||||
} else {
|
||||
printf("%s\n", path);
|
||||
}
|
||||
|
||||
xmlFree(path);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_tree(xmlNodePtr node, unsigned int indent)
|
||||
{
|
||||
xmlNode *cur_node = NULL;
|
||||
|
||||
for (cur_node = node; cur_node; cur_node = cur_node->next) {
|
||||
if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
et_display_node(cur_node, indent);
|
||||
}
|
||||
|
||||
et_display_tree(cur_node->children, indent++);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_packet_S1AP_data(const et_S1AP_t *const s1ap)
|
||||
{
|
||||
char *message_string = NULL;
|
||||
|
||||
if (s1ap) {
|
||||
message_string = calloc(20000, sizeof(char));
|
||||
AssertFatal (NULL != message_string, "ERROR malloc()failed!\n");
|
||||
|
||||
switch(s1ap->pdu.present) {
|
||||
case S1AP_S1AP_PDU_PR_initiatingMessage:
|
||||
switch(s1ap->pdu.choice.initiatingMessage.procedureCode) {
|
||||
case S1AP_ProcedureCode_id_downlinkNASTransport: s1ap_xer_print_s1ap_downlinknastransport(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetuprequest(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_UEContextRelease: s1ap_xer_print_s1ap_uecontextreleasecommand(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_Paging: s1ap_xer_print_s1ap_paging(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_uplinkNASTransport: s1ap_xer_print_s1ap_uplinknastransport(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setuprequest(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_initialUEMessage: s1ap_xer_print_s1ap_initialuemessage(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_UEContextReleaseRequest: s1ap_xer_print_s1ap_uecontextreleaserequest(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_UECapabilityInfoIndication:s1ap_xer_print_s1ap_uecapabilityinfoindication(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_NASNonDeliveryIndication: s1ap_xer_print_s1ap_nasnondeliveryindication_(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
default:
|
||||
AssertFatal( 0, "Unknown procedure ID (%d) for initiating message\n",
|
||||
(int)s1ap->pdu.choice.initiatingMessage.procedureCode);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case S1AP_S1AP_PDU_PR_successfulOutcome:
|
||||
switch(s1ap->pdu.choice.successfulOutcome.procedureCode) {
|
||||
case S1AP_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setupresponse(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_UEContextRelease: s1ap_xer_print_s1ap_uecontextreleasecomplete(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Unknown procedure ID (%d) for successfull outcome message\n",
|
||||
(int)s1ap->pdu.choice.successfulOutcome.procedureCode);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case S1AP_S1AP_PDU_PR_unsuccessfulOutcome:
|
||||
switch(s1ap->pdu.choice.unsuccessfulOutcome.procedureCode) {
|
||||
case S1AP_ProcedureCode_id_S1Setup: s1ap_xer_print_s1ap_s1setupfailure(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
case S1AP_ProcedureCode_id_InitialContextSetup: s1ap_xer_print_s1ap_initialcontextsetupfailure(s1ap_xer__print2sp, message_string, (S1AP_message *)&s1ap->message); break;
|
||||
|
||||
default:
|
||||
et_free_pointer(message_string);
|
||||
AssertFatal(0,"Unknown procedure ID (%d) for unsuccessfull outcome message\n",
|
||||
(int)s1ap->pdu.choice.unsuccessfulOutcome.procedureCode);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Unknown presence (%d) or not implemented\n", (int)s1ap->pdu.present);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(stdout, "\t\tSCTP.data XML dump:\n%s\n", message_string);
|
||||
et_free_pointer(message_string);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_packet_sctp_init(const sctp_inithdr_t *const sctp)
|
||||
{
|
||||
if (sctp) {
|
||||
fprintf(stdout, "\t\tSCTP.init.init_tag : %u\n", sctp->init_tag);
|
||||
fprintf(stdout, "\t\tSCTP.init.a_rwnd : %u\n", sctp->a_rwnd);
|
||||
fprintf(stdout, "\t\tSCTP.init.num_inbound_streams : %u\n", sctp->num_inbound_streams);
|
||||
fprintf(stdout, "\t\tSCTP.init.num_outbound_streams : %u\n", sctp->num_outbound_streams);
|
||||
fprintf(stdout, "\t\tSCTP.init.initial_tsn : %u\n", sctp->initial_tsn);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_packet_sctp_initack(const sctp_initackhdr_t *const sctp)
|
||||
{
|
||||
if (sctp) {
|
||||
fprintf(stdout, "\t\tSCTP.initack.init_tag : %u\n", sctp->init_tag);
|
||||
fprintf(stdout, "\t\tSCTP.initack.a_rwnd : %u\n", sctp->a_rwnd);
|
||||
fprintf(stdout, "\t\tSCTP.initack.num_inbound_streams : %u\n", sctp->num_inbound_streams);
|
||||
fprintf(stdout, "\t\tSCTP.initack.num_outbound_streams : %u\n", sctp->num_outbound_streams);
|
||||
fprintf(stdout, "\t\tSCTP.initack.initial_tsn : %u\n", sctp->initial_tsn);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_packet_sctp_data(const sctp_datahdr_t *const sctp)
|
||||
{
|
||||
if (sctp) {
|
||||
fprintf(stdout, "\t\tSCTP.data.tsn : %u\n", sctp->tsn);
|
||||
fprintf(stdout, "\t\tSCTP.data.stream : %u\n", sctp->stream);
|
||||
fprintf(stdout, "\t\tSCTP.data.ssn : %u\n", sctp->ssn);
|
||||
fprintf(stdout, "\t\tSCTP.data.ppid : %u\n", sctp->ppid);
|
||||
|
||||
if (sctp->ppid == 18) {
|
||||
et_display_packet_s1ap_data(&sctp->payload);
|
||||
}
|
||||
|
||||
fprintf(stdout, "\t\tSCTP.data.binary_stream_allocated_size : %u\n", sctp->payload.binary_stream_allocated_size);
|
||||
|
||||
if (NULL != sctp->payload.binary_stream) {
|
||||
fprintf(stdout, "\t\tSCTP.data.binary_stream :\n");
|
||||
et_print_hex_octets(sctp->payload.binary_stream, sctp->payload.binary_stream_allocated_size);
|
||||
} else {
|
||||
fprintf(stdout, "\t\tSCTP.data.binary_stream : NULL\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_packet_sctp(const et_sctp_hdr_t *const sctp)
|
||||
{
|
||||
if (sctp) {
|
||||
fprintf(stdout, "\t\tSCTP.src_port : %u\n", sctp->src_port);
|
||||
fprintf(stdout, "\t\tSCTP.dst_port : %u\n", sctp->dst_port);
|
||||
fprintf(stdout, "\t\tSCTP.chunk_type : %s\n", et_chunk_type_cid2str(sctp->chunk_type));
|
||||
|
||||
switch (sctp->chunk_type) {
|
||||
case SCTP_CID_DATA:
|
||||
et_display_packet_sctp_data(&sctp->u.data_hdr);
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT:
|
||||
et_display_packet_sctp_initack(&sctp->u.init_hdr);
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT_ACK:
|
||||
et_display_packet_sctp_initack(&sctp->u.init_ack_hdr);
|
||||
break;
|
||||
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_packet_ip(const et_ip_hdr_t *const ip)
|
||||
{
|
||||
if (ip) {
|
||||
fprintf(stdout, "\t\tSource address : %s\n", et_ip2ip_str(&ip->src));
|
||||
fprintf(stdout, "\t\tDestination address : %s\n", et_ip2ip_str(&ip->dst));
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_packet(const et_packet_t *const packet)
|
||||
{
|
||||
if (packet) {
|
||||
fprintf(stdout, "-------------------------------------------------------------------------------\n");
|
||||
fprintf(stdout, "\tPacket:\tnum %u | original frame number %u \n", packet->packet_number, packet->original_frame_number);
|
||||
fprintf(stdout, "\tPacket:\ttime relative to 1st packet %ld.%06lu\n",
|
||||
packet->time_relative_to_first_packet.tv_sec, packet->time_relative_to_first_packet.tv_usec);
|
||||
fprintf(stdout, "\tPacket:\ttime relative to last tx packet %ld.%06lu\n",
|
||||
packet->time_relative_to_last_sent_packet.tv_sec, packet->time_relative_to_last_sent_packet.tv_usec);
|
||||
fprintf(stdout, "\tPacket:\ttime relative to last_received packet %ld.%06lu\n",
|
||||
packet->time_relative_to_last_received_packet.tv_sec, packet->time_relative_to_last_received_packet.tv_usec);
|
||||
|
||||
switch(packet->action) {
|
||||
case ET_PACKET_ACTION_S1C_SEND:
|
||||
fprintf(stdout, "\tPacket:\tAction SEND\n");
|
||||
break;
|
||||
|
||||
case ET_PACKET_ACTION_S1C_RECEIVE:
|
||||
fprintf(stdout, "\tPacket:\tAction RECEIVE\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stdout, "\tPacket:\tAction UNKNOWN\n");
|
||||
}
|
||||
|
||||
switch(packet->status) {
|
||||
case ET_PACKET_STATUS_NONE:
|
||||
fprintf(stdout, "\tPacket:\tStatus NONE\n");
|
||||
break;
|
||||
|
||||
case ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT:
|
||||
fprintf(stdout, "\tPacket:\tStatus NOT_TAKEN_IN_ACCOUNT\n");
|
||||
break;
|
||||
|
||||
case ET_PACKET_STATUS_SCHEDULED_FOR_SENDING:
|
||||
fprintf(stdout, "\tPacket:\tStatus SCHEDULED_FOR_SENDING\n");
|
||||
break;
|
||||
|
||||
case ET_PACKET_STATUS_SENT:
|
||||
fprintf(stdout, "\tPacket:\tStatus SENT\n");
|
||||
break;
|
||||
|
||||
case ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING:
|
||||
fprintf(stdout, "\tPacket:\tStatus SCHEDULED_FOR_RECEIVING\n");
|
||||
break;
|
||||
|
||||
case ET_PACKET_STATUS_RECEIVED:
|
||||
fprintf(stdout, "\tPacket:\tStatus RECEIVED\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stdout, "\tPacket:\tStatus UNKNOWN\n");
|
||||
}
|
||||
|
||||
et_display_packet_ip(&packet->ip_hdr);
|
||||
et_display_packet_sctp(&packet->sctp_hdr);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_display_scenario(const et_scenario_t *const scenario)
|
||||
{
|
||||
et_packet_t *packet = NULL;
|
||||
|
||||
if (scenario) {
|
||||
fprintf(stdout, "Scenario: %s\n", (scenario->name != NULL) ? (char *)scenario->name:"UNKNOWN NAME");
|
||||
packet = scenario->list_packet;
|
||||
|
||||
while (packet) {
|
||||
et_display_packet(packet);
|
||||
packet = packet->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,586 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
play_scenario_fsm.c
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "platform_types.h"
|
||||
#include "assertions.h"
|
||||
#include "play_scenario.h"
|
||||
#include "play_scenario_s1ap_eNB_defs.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
extern int g_max_speed;
|
||||
//------------------------------------------------------------------------------
|
||||
et_scenario_t *g_scenario = NULL;
|
||||
pthread_mutex_t g_fsm_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
et_fsm_state_t g_fsm_state = ET_FSM_STATE_NULL;
|
||||
uint32_t g_constraints = ET_BIT_MASK_MATCH_SCTP_STREAM | ET_BIT_MASK_MATCH_SCTP_SSN;
|
||||
//------------------------------------------------------------------------------
|
||||
// it is assumed that if a time is negative tv_sec and tv_usec are both negative
|
||||
void timeval_add (struct timeval *const result, const struct timeval *const a, const struct timeval *const b)
|
||||
{
|
||||
AssertFatal(((a->tv_sec <= 0) && (a->tv_usec <= 0)) || ((a->tv_sec >= 0) && (a->tv_usec >= 0)), " Bad time format arg a\n");
|
||||
AssertFatal(((b->tv_sec <= 0) && (b->tv_usec <= 0)) || ((b->tv_sec >= 0) && (b->tv_usec >= 0)), " Bad time format arg b\n");
|
||||
// may happen overflows but were are not dealing with very large timings
|
||||
long long int r = a->tv_usec + b->tv_usec + (a->tv_sec + b->tv_sec) * 1000000;
|
||||
result->tv_sec = r / (long long int)1000000;
|
||||
result->tv_usec = r % (long long int)1000000;
|
||||
|
||||
if ((result != a) && (result != b)) {
|
||||
LOG_D(ENB_APP, "timeval_add(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// it is assumed that if a time is negative tv_sec and tv_usec are both negative
|
||||
// return true if result is positive
|
||||
int timeval_subtract (struct timeval *const result, struct timeval *const a, struct timeval *const b)
|
||||
{
|
||||
AssertFatal(((a->tv_sec <= 0) && (a->tv_usec <= 0)) || ((a->tv_sec >= 0) && (a->tv_usec >= 0)), " Bad time format arg a\n");
|
||||
AssertFatal(((b->tv_sec <= 0) && (b->tv_usec <= 0)) || ((b->tv_sec >= 0) && (b->tv_usec >= 0)), " Bad time format arg b\n");
|
||||
// may happen overflows but were are not dealing with very large timings
|
||||
long long int r = a->tv_usec - b->tv_usec + (a->tv_sec - b->tv_sec) * 1000000;
|
||||
result->tv_sec = r / (long long int)1000000;
|
||||
result->tv_usec = r % (long long int)1000000;
|
||||
|
||||
if ((result != a) && (result != b)) {
|
||||
LOG_D(ENB_APP, "timeval_subtract(%ld.%06d, %ld.%06d)=%ld.%06d\n", a->tv_sec, a->tv_usec, b->tv_sec, b->tv_usec, result->tv_sec, result->tv_usec);
|
||||
}
|
||||
|
||||
return (result->tv_sec >= 0) && (result->tv_usec >= 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void et_scenario_wait_rx_packet(et_packet_t *const packet)
|
||||
{
|
||||
packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_RECEIVING;
|
||||
g_fsm_state = ET_FSM_STATE_WAITING_RX_EVENT;
|
||||
|
||||
if (timer_setup (ET_FSM_STATE_WAITING_RX_EVENT_DELAY_SEC, 0, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,
|
||||
packet, &packet->timer_id) < 0) {
|
||||
AssertFatal(0, " Can not start waiting RX event timer\n");
|
||||
}
|
||||
|
||||
g_scenario->timer_count++;
|
||||
LOG_D(ENB_APP, "Waiting RX packet num %d original frame number %u\n", packet->packet_number, packet->original_frame_number);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_scenario_schedule_tx_packet(et_packet_t *packet)
|
||||
{
|
||||
s1ap_eNB_instance_t *s1ap_eNB_instance = NULL;
|
||||
struct timeval now = { .tv_sec = 0, .tv_usec = 0 };
|
||||
struct timeval offset_last_tx_packet = { .tv_sec = 0, .tv_usec = 0 };
|
||||
struct timeval offset_last_rx_packet = { .tv_sec = 0, .tv_usec = 0 };
|
||||
struct timeval offset_tx_rx = { .tv_sec = 0, .tv_usec = 0 };
|
||||
struct timeval offset = { .tv_sec = 0, .tv_usec = 0 };
|
||||
int last_packet_was_rx = 0;
|
||||
int we_are_too_late = 0;
|
||||
int original_frame_number = -1;
|
||||
AssertFatal(NULL != packet, "packet argument is NULL");
|
||||
s1ap_eNB_instance = et_s1ap_eNB_get_instance(packet->enb_instance);
|
||||
AssertFatal(NULL != s1ap_eNB_instance, "Cannot get s1ap_eNB_instance_t for eNB instance %d", packet->enb_instance);
|
||||
LOG_D(ENB_APP, "%s\n", __FUNCTION__);
|
||||
g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT;
|
||||
|
||||
switch (packet->sctp_hdr.chunk_type) {
|
||||
case SCTP_CID_DATA:
|
||||
// check if we can send it now
|
||||
// TODO: BUG we have to discard in scenario all packets that cannot be processed (SACK, COOKIEs, etc)
|
||||
AssertFatal(gettimeofday(&now, NULL) == 0, "gettimeofday failed");
|
||||
timeval_subtract(&offset_last_tx_packet,&now,&g_scenario->time_last_tx_packet);
|
||||
timeval_subtract(&offset_last_rx_packet,&now,&g_scenario->time_last_rx_packet);
|
||||
LOG_D(ENB_APP, "offset_last_tx_packet=%ld.%06d\n", offset_last_tx_packet.tv_sec, offset_last_tx_packet.tv_usec);
|
||||
LOG_D(ENB_APP, "offset_last_rx_packet=%ld.%06d\n", offset_last_rx_packet.tv_sec, offset_last_rx_packet.tv_usec);
|
||||
last_packet_was_rx = timeval_subtract(&offset_tx_rx,&offset_last_tx_packet,&offset_last_rx_packet);
|
||||
|
||||
if (last_packet_was_rx) {
|
||||
LOG_D(ENB_APP, "last_packet_was_rx\n");
|
||||
we_are_too_late = timeval_subtract(&offset,&offset_last_rx_packet,&packet->time_relative_to_last_received_packet);
|
||||
LOG_D(ENB_APP, "we_are_too_late=%d, offset=%ld.%06d\n", we_are_too_late, offset.tv_sec, offset.tv_usec);
|
||||
} else {
|
||||
LOG_D(ENB_APP, "last_packet_was_tx\n");
|
||||
we_are_too_late = timeval_subtract(&offset,&offset_last_tx_packet,&packet->time_relative_to_last_sent_packet);
|
||||
LOG_D(ENB_APP, "we_are_too_late=%d, offset=%ld.%06d\n", we_are_too_late, offset.tv_sec, offset.tv_usec);
|
||||
}
|
||||
|
||||
if ((0 == we_are_too_late) && (0 == g_max_speed)) {
|
||||
// set timer
|
||||
if ((offset.tv_sec <= 0) || (offset.tv_usec <= 0)) {
|
||||
offset.tv_sec = -offset.tv_sec;
|
||||
offset.tv_usec = -offset.tv_usec;
|
||||
}
|
||||
|
||||
LOG_D(ENB_APP, "Send packet num %u original frame number %u in %ld.%06d sec\n",
|
||||
packet->packet_number, packet->original_frame_number, offset.tv_sec, offset.tv_usec);
|
||||
packet->status = ET_PACKET_STATUS_SCHEDULED_FOR_SENDING;
|
||||
|
||||
if (timer_setup (offset.tv_sec, offset.tv_usec, TASK_S1AP, INSTANCE_DEFAULT, TIMER_ONE_SHOT,packet, &packet->timer_id) < 0) {
|
||||
AssertFatal(0, " Can not start TX event timer\n");
|
||||
}
|
||||
|
||||
g_scenario->timer_count++;
|
||||
// Done g_fsm_state = ET_FSM_STATE_WAITING_TX_EVENT;
|
||||
} else {
|
||||
// send immediately
|
||||
AssertFatal(0 == gettimeofday(&packet->timestamp_packet, NULL), "gettimeofday() Failed");
|
||||
original_frame_number = packet->original_frame_number;
|
||||
|
||||
do {
|
||||
g_scenario->time_last_tx_packet.tv_sec = packet->timestamp_packet.tv_sec;
|
||||
g_scenario->time_last_tx_packet.tv_usec = packet->timestamp_packet.tv_usec;
|
||||
LOG_D(ENB_APP, "Sending packet num %d original frame number %u immediately\n",packet->packet_number, packet->original_frame_number);
|
||||
et_s1ap_eNB_itti_send_sctp_data_req(
|
||||
packet->enb_instance,
|
||||
packet->sctp_hdr.u.data_hdr.assoc_id,
|
||||
packet->sctp_hdr.u.data_hdr.payload.binary_stream,
|
||||
packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size,
|
||||
packet->sctp_hdr.u.data_hdr.stream);
|
||||
packet->status = ET_PACKET_STATUS_SENT;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
packet = packet->next;
|
||||
} while ((NULL != packet) && (packet->original_frame_number == original_frame_number));
|
||||
|
||||
g_fsm_state = ET_FSM_STATE_RUNNING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT:
|
||||
case SCTP_CID_INIT_ACK:
|
||||
AssertFatal(0, "Invalid case TX packet SCTP_CID_INIT or SCTP_CID_INIT_ACK");
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Invalid case TX packet SCTP_CID %d", packet->sctp_hdr.chunk_type);
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_running(et_event_t event)
|
||||
{
|
||||
switch (event.code) {
|
||||
case ET_EVENT_TICK:
|
||||
while (NULL != g_scenario->next_packet) {
|
||||
LOG_D(ENB_APP, "EVENT_TICK: Considering packet num %d original frame number %u\n", g_scenario->next_packet->packet_number, g_scenario->next_packet->original_frame_number);
|
||||
|
||||
switch (g_scenario->next_packet->sctp_hdr.chunk_type) {
|
||||
case SCTP_CID_DATA :
|
||||
|
||||
// no init in this scenario, may be sub-scenario
|
||||
if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) {
|
||||
if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) {
|
||||
et_scenario_schedule_tx_packet(g_scenario->next_packet);
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
et_event_t continue_event;
|
||||
continue_event.code = ET_EVENT_TICK;
|
||||
et_scenario_fsm_notify_event(continue_event);
|
||||
return g_fsm_state;
|
||||
} else if (g_scenario->next_packet->status != ET_PACKET_STATUS_SCHEDULED_FOR_SENDING) {
|
||||
AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status);
|
||||
}
|
||||
} else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) {
|
||||
if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) {
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
} else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) {
|
||||
et_scenario_wait_rx_packet(g_scenario->next_packet);
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return g_fsm_state;
|
||||
} else {
|
||||
AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status);
|
||||
}
|
||||
} else {
|
||||
AssertFatal(0, "Invalid packet action %d", g_scenario->next_packet->action);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT:
|
||||
case SCTP_CID_INIT_ACK:
|
||||
case SCTP_CID_HEARTBEAT:
|
||||
case SCTP_CID_HEARTBEAT_ACK:
|
||||
case SCTP_CID_COOKIE_ECHO:
|
||||
case SCTP_CID_COOKIE_ACK:
|
||||
case SCTP_CID_ECN_ECNE:
|
||||
case SCTP_CID_ECN_CWR:
|
||||
LOG_D(ENB_APP, "EVENT_TICK: Ignoring packet num %d SCTP CID %s\n",
|
||||
g_scenario->next_packet->packet_number,
|
||||
et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type));
|
||||
g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
break;
|
||||
|
||||
case SCTP_CID_ABORT:
|
||||
case SCTP_CID_SHUTDOWN:
|
||||
case SCTP_CID_SHUTDOWN_ACK:
|
||||
case SCTP_CID_ERROR:
|
||||
case SCTP_CID_SHUTDOWN_COMPLETE:
|
||||
AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)",
|
||||
et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type));
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_D(ENB_APP, "EVENT_TICK: Ignoring packet num %d SCTP CID %s\n",
|
||||
g_scenario->next_packet->packet_number,
|
||||
et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type));
|
||||
g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name);
|
||||
g_fsm_state = ET_FSM_STATE_NULL;
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
|
||||
if (0 == g_scenario->timer_count) {
|
||||
fprintf(stderr, "End of scenario: %s\n", g_scenario->name);
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
return 0;
|
||||
//exit(0);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Remaining timers running: %d\n", g_scenario->timer_count);
|
||||
return g_fsm_state;
|
||||
break;
|
||||
|
||||
case ET_EVENT_RX_PACKET_TIME_OUT:
|
||||
AssertFatal(0, "Event ET_EVENT_RX_PACKET_TIME_OUT not handled in FSM state ET_FSM_STATE_RUNNING");
|
||||
break;
|
||||
|
||||
case ET_EVENT_TX_TIMED_PACKET:
|
||||
AssertFatal(0, "Event ET_EVENT_TX_TIMED_PACKET not handled in FSM state ET_FSM_STATE_RUNNING");
|
||||
break;
|
||||
|
||||
case ET_EVENT_RX_S1AP:
|
||||
et_s1ap_process_rx_packet(&event.u.s1ap_data_ind);
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_RUNNING", event.code);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_tx(et_event_t event)
|
||||
{
|
||||
int rv = 0;
|
||||
int original_frame_number = -1;
|
||||
et_packet_t *packet = NULL;
|
||||
|
||||
switch (event.code) {
|
||||
case ET_EVENT_TICK:
|
||||
fprintf(stdout, "EVENT_TICK: waiting for tx event\n");
|
||||
break;
|
||||
|
||||
case ET_EVENT_RX_S1AP:
|
||||
rv = et_s1ap_process_rx_packet(&event.u.s1ap_data_ind);
|
||||
break;
|
||||
|
||||
case ET_EVENT_TX_TIMED_PACKET:
|
||||
// send immediately
|
||||
packet = event.u.tx_timed_packet;
|
||||
AssertFatal(0 == gettimeofday(&packet->timestamp_packet, NULL), "gettimeofday() Failed");
|
||||
original_frame_number = packet->original_frame_number;
|
||||
|
||||
do {
|
||||
g_scenario->time_last_tx_packet.tv_sec = packet->timestamp_packet.tv_sec;
|
||||
g_scenario->time_last_tx_packet.tv_usec = packet->timestamp_packet.tv_usec;
|
||||
LOG_D(ENB_APP, "Sending packet num %d original frame number %u immediately\n",packet->packet_number, packet->original_frame_number);
|
||||
et_s1ap_eNB_itti_send_sctp_data_req(
|
||||
packet->enb_instance,
|
||||
packet->sctp_hdr.u.data_hdr.assoc_id,
|
||||
packet->sctp_hdr.u.data_hdr.payload.binary_stream,
|
||||
packet->sctp_hdr.u.data_hdr.payload.binary_stream_allocated_size,
|
||||
packet->sctp_hdr.u.data_hdr.stream);
|
||||
packet->status = ET_PACKET_STATUS_SENT;
|
||||
packet = packet->next;
|
||||
g_scenario->next_packet = packet;
|
||||
} while ( (NULL != packet) && (packet->original_frame_number == original_frame_number));
|
||||
|
||||
g_fsm_state = ET_FSM_STATE_RUNNING;
|
||||
break;
|
||||
|
||||
case ET_EVENT_RX_PACKET_TIME_OUT:
|
||||
default:
|
||||
AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING_TX", event.code);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_waiting_rx(et_event_t event)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
switch (event.code) {
|
||||
case ET_EVENT_TICK:
|
||||
fprintf(stdout, "EVENT_TICK: waiting for rx event\n");
|
||||
break;
|
||||
|
||||
case ET_EVENT_RX_PACKET_TIME_OUT:
|
||||
fprintf(stderr, "Error The following packet is not received:\n");
|
||||
//et_display_packet(event.u.rx_packet_time_out);
|
||||
AssertFatal(0, "Waited packet not received");
|
||||
break;
|
||||
|
||||
case ET_EVENT_RX_S1AP:
|
||||
rv = et_s1ap_process_rx_packet(&event.u.s1ap_data_ind);
|
||||
|
||||
// waited packet
|
||||
if (rv == 0) {
|
||||
g_fsm_state = ET_FSM_STATE_RUNNING;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ET_EVENT_TX_TIMED_PACKET:
|
||||
default:
|
||||
AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_WAITING_RX", event.code);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_connecting_s1c(et_event_t event)
|
||||
{
|
||||
switch (event.code) {
|
||||
case ET_EVENT_TICK:
|
||||
break;
|
||||
|
||||
case ET_EVENT_S1C_CONNECTED:
|
||||
// hack simulate we have been able to get the right timing values for STCP connect
|
||||
AssertFatal(gettimeofday(&g_scenario->time_last_rx_packet, NULL) == 0, "gettimeofday failed");
|
||||
|
||||
while (NULL != g_scenario->next_packet) {
|
||||
switch (g_scenario->next_packet->sctp_hdr.chunk_type) {
|
||||
case SCTP_CID_DATA :
|
||||
|
||||
// no init in this scenario, may be sub-scenario
|
||||
if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) {
|
||||
et_scenario_schedule_tx_packet(g_scenario->next_packet);
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
et_event_t continue_event;
|
||||
continue_event.code = ET_EVENT_TICK;
|
||||
et_scenario_fsm_notify_event(continue_event);
|
||||
return g_fsm_state;
|
||||
} else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) {
|
||||
if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) {
|
||||
g_scenario->last_rx_packet = g_scenario->next_packet;
|
||||
g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
} else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) {
|
||||
et_scenario_wait_rx_packet(g_scenario->next_packet);
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return g_fsm_state;
|
||||
} else {
|
||||
AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status);
|
||||
}
|
||||
} else {
|
||||
AssertFatal(0, "Invalid packet action %d", g_scenario->next_packet->action);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT:
|
||||
case SCTP_CID_INIT_ACK:
|
||||
case SCTP_CID_HEARTBEAT:
|
||||
case SCTP_CID_HEARTBEAT_ACK:
|
||||
case SCTP_CID_COOKIE_ECHO:
|
||||
case SCTP_CID_COOKIE_ACK:
|
||||
case SCTP_CID_ECN_ECNE:
|
||||
case SCTP_CID_ECN_CWR:
|
||||
g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
break;
|
||||
|
||||
case SCTP_CID_ABORT:
|
||||
case SCTP_CID_SHUTDOWN:
|
||||
case SCTP_CID_SHUTDOWN_ACK:
|
||||
case SCTP_CID_ERROR:
|
||||
case SCTP_CID_SHUTDOWN_COMPLETE:
|
||||
AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)",
|
||||
et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type));
|
||||
break;
|
||||
|
||||
default:
|
||||
g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "No Packet found in this scenario: %s\n", g_scenario->name);
|
||||
g_fsm_state = ET_FSM_STATE_NULL;
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
|
||||
if (0 == g_scenario->timer_count) {
|
||||
fprintf(stderr, "End of scenario: %s\n", g_scenario->name);
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Remaining timers running: %d\n", g_scenario->timer_count);
|
||||
return g_fsm_state;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_CONNECTING_S1C", event.code);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return 0;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
et_fsm_state_t et_scenario_fsm_notify_event_state_null(et_event_t event)
|
||||
{
|
||||
switch (event.code) {
|
||||
case ET_EVENT_TICK:
|
||||
break;
|
||||
|
||||
case ET_EVENT_INIT:
|
||||
AssertFatal(NULL == g_scenario, "Current scenario not ended");
|
||||
g_scenario = event.u.init.scenario;
|
||||
g_scenario->next_packet = g_scenario->list_packet;
|
||||
g_scenario->last_rx_packet = NULL;
|
||||
g_scenario->last_tx_packet = NULL;
|
||||
|
||||
while (NULL != g_scenario->next_packet) {
|
||||
switch (g_scenario->next_packet->sctp_hdr.chunk_type) {
|
||||
case SCTP_CID_DATA :
|
||||
|
||||
// no init in this scenario, may be sub-scenario, ...
|
||||
if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_SEND) {
|
||||
et_scenario_schedule_tx_packet(g_scenario->next_packet);
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
et_event_t continue_event;
|
||||
continue_event.code = ET_EVENT_TICK;
|
||||
et_scenario_fsm_notify_event(continue_event);
|
||||
return g_fsm_state;
|
||||
} else if (g_scenario->next_packet->action == ET_PACKET_ACTION_S1C_RECEIVE) {
|
||||
if (g_scenario->next_packet->status == ET_PACKET_STATUS_RECEIVED) {
|
||||
g_scenario->last_rx_packet = g_scenario->next_packet;
|
||||
g_scenario->time_last_rx_packet = g_scenario->last_rx_packet->timestamp_packet;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
} else if (g_scenario->next_packet->status == ET_PACKET_STATUS_NONE) {
|
||||
et_scenario_wait_rx_packet(g_scenario->next_packet);
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return g_fsm_state;
|
||||
} else {
|
||||
AssertFatal(0, "Invalid packet status %d", g_scenario->next_packet->status);
|
||||
}
|
||||
} else {
|
||||
AssertFatal(0, "Invalid packet action %d", g_scenario->next_packet->action);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT:
|
||||
case SCTP_CID_INIT_ACK:
|
||||
g_scenario->enb_properties = (Enb_properties_array_t *)et_enb_config_get();
|
||||
g_scenario->hash_old_ue_mme_id2ue_mme_id = hashtable_create (256,NULL,NULL);
|
||||
g_scenario->hash_mme2association_id = hashtable_create (256,NULL,NULL);
|
||||
// Try to register each eNB
|
||||
g_scenario->registered_enb = 0;
|
||||
g_fsm_state = ET_FSM_STATE_CONNECTING_S1C;
|
||||
AssertFatal(gettimeofday(&g_scenario->time_last_tx_packet, NULL) == 0, "gettimeofday failed");
|
||||
et_eNB_app_register (g_scenario->enb_properties);
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return g_fsm_state;
|
||||
break;
|
||||
|
||||
case SCTP_CID_HEARTBEAT:
|
||||
case SCTP_CID_HEARTBEAT_ACK:
|
||||
case SCTP_CID_COOKIE_ECHO:
|
||||
case SCTP_CID_COOKIE_ACK:
|
||||
case SCTP_CID_ECN_ECNE:
|
||||
case SCTP_CID_ECN_CWR:
|
||||
g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
break;
|
||||
|
||||
case SCTP_CID_ABORT:
|
||||
case SCTP_CID_SHUTDOWN:
|
||||
case SCTP_CID_SHUTDOWN_ACK:
|
||||
case SCTP_CID_ERROR:
|
||||
case SCTP_CID_SHUTDOWN_COMPLETE:
|
||||
AssertFatal(0, "The scenario should be cleaned (packet %s cannot be processed at this time)",
|
||||
et_chunk_type_cid2str(g_scenario->next_packet->sctp_hdr.chunk_type));
|
||||
break;
|
||||
|
||||
default:
|
||||
g_scenario->next_packet->status = ET_PACKET_STATUS_NOT_TAKEN_IN_ACCOUNT;
|
||||
g_scenario->next_packet = g_scenario->next_packet->next;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "No Useful packet found in this scenario: %s\n", g_scenario->name);
|
||||
g_fsm_state = ET_FSM_STATE_NULL;
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return g_fsm_state;
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Case event %d not handled in ET_FSM_STATE_NULL", event.code);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
et_fsm_state_t et_scenario_fsm_notify_event(et_event_t event)
|
||||
{
|
||||
AssertFatal((event.code >= ET_EVENT_START) && (event.code < ET_EVENT_END), "Unknown et_event_t.code %d", event.code);
|
||||
pthread_mutex_lock(&g_fsm_lock);
|
||||
|
||||
switch (g_fsm_state) {
|
||||
case ET_FSM_STATE_NULL: return et_scenario_fsm_notify_event_state_null(event); break;
|
||||
|
||||
case ET_FSM_STATE_CONNECTING_S1C: return et_scenario_fsm_notify_event_state_connecting_s1c(event); break;
|
||||
|
||||
case ET_FSM_STATE_WAITING_TX_EVENT: return et_scenario_fsm_notify_event_state_waiting_tx(event); break;
|
||||
|
||||
case ET_FSM_STATE_WAITING_RX_EVENT: return et_scenario_fsm_notify_event_state_waiting_rx(event); break;
|
||||
|
||||
case ET_FSM_STATE_RUNNING: return et_scenario_fsm_notify_event_state_running(event); break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Case fsm_state %d not handled", g_fsm_state);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&g_fsm_lock);
|
||||
return g_fsm_state;
|
||||
}
|
||||
@@ -1,592 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
play_scenario_parse.c
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/debugXML.h>
|
||||
#include <libxml/xmlIO.h>
|
||||
#include <libxml/DOCBparser.h>
|
||||
#include <libxml/xinclude.h>
|
||||
#include <libxml/catalog.h>
|
||||
#include <libxml/xmlreader.h>
|
||||
#include <libxslt/xslt.h>
|
||||
#include <libxslt/xsltInternals.h>
|
||||
#include <libxslt/transform.h>
|
||||
#include <libxslt/xsltutils.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "platform_types.h"
|
||||
#include "assertions.h"
|
||||
#include "play_scenario.h"
|
||||
//------------------------------------------------------------------------------
|
||||
#define ENB_CONFIG_MAX_XSLT_PARAMS 32
|
||||
//------------------------------------------------------------------------------
|
||||
extern Enb_properties_array_t g_enb_properties;
|
||||
//------------------------------------------------------------------------------
|
||||
void et_parse_s1ap(xmlDocPtr doc, const xmlNode const *s1ap_node, et_s1ap_t * const s1ap)
|
||||
{
|
||||
xmlNodePtr cur_node = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
xmlChar *xml_char2 = NULL;
|
||||
unsigned int size = 0;
|
||||
int rc = 0;
|
||||
unsigned int go_deeper_in_tree = 1;
|
||||
|
||||
if ((NULL != s1ap_node) && (NULL != s1ap)) {
|
||||
// see http://www.xmlsoft.org/html/libxml-tree.html#xmlCopyNode
|
||||
if (NULL == s1ap->doc) {
|
||||
xmlUnlinkNode(s1ap_node);
|
||||
//cur_node = xmlCopyNodeList(s1ap_node);
|
||||
// arg2: if 1 do a recursive copy (properties, namespaces and children when applicable) if 2 copy properties and namespaces (when applicable)
|
||||
//cur_node = xmlCopyNode(s1ap_node, 1);
|
||||
//AssertFatal(NULL != cur_node, "xmlCopyNode Failed");
|
||||
s1ap->doc = xmlNewDoc(BAD_CAST "1.0");
|
||||
xmlDocSetRootElement(s1ap->doc, s1ap_node);
|
||||
}
|
||||
|
||||
for (cur_node = (xmlNode *)s1ap_node; cur_node; cur_node = cur_node->next) {
|
||||
go_deeper_in_tree = 1;
|
||||
if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) {
|
||||
// do not get hidden fields
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) {
|
||||
go_deeper_in_tree = 0;
|
||||
}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
if (0 < go_deeper_in_tree) {
|
||||
// first get size
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size");
|
||||
if (NULL != xml_char) {
|
||||
size = strtoul((const char *)xml_char, NULL, 0);
|
||||
xmlFree(xml_char);
|
||||
// second: try to get value (always hex)
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name");
|
||||
fprintf(stdout, "s1ap %p field name %s size %u value %s\n",s1ap, xml_char2, size, xml_char);
|
||||
xmlFree(xml_char2);
|
||||
// if success to get value, do not parse children
|
||||
//AssertFatal ((xmlStrlen(xml_char) == size), "ERROR %s() mismatch in size %d and strlen %d\n", __FUNCTION__, size, xmlStrlen(xml_char));
|
||||
//if (xmlStrlen(xml_char) == size) {
|
||||
AssertFatal ((s1ap->binary_stream_pos+xmlStrlen(xml_char)/2) <= s1ap->binary_stream_allocated_size,
|
||||
"ERROR in buffer size: binary_stream_pos %d xmlStrlen(xml_char)/2=%d\n", s1ap->binary_stream_pos, xmlStrlen(xml_char)/2);
|
||||
rc = et_hex2data( &s1ap->binary_stream[s1ap->binary_stream_pos], xml_char, xmlStrlen(xml_char));
|
||||
s1ap->binary_stream_pos += xmlStrlen(xml_char)/2;
|
||||
//et_display_node(cur_node, 0);
|
||||
AssertFatal (rc >= 0, "ERROR in converting hex string %s len %d size %u rc %d\n", xml_char, xmlStrlen(xml_char), size, rc);
|
||||
go_deeper_in_tree = 0;
|
||||
//}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 < go_deeper_in_tree) {
|
||||
et_parse_s1ap(doc, cur_node->children, s1ap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void et_parse_sctp_data_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_datahdr_t * const sctp_hdr)
|
||||
{
|
||||
xmlNode *cur_node = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
xmlChar *xml_char2 = NULL;
|
||||
|
||||
if ((NULL != sctp_node) && (NULL != sctp_hdr)) {
|
||||
xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_payload_proto_id"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->ppid = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_sid"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->stream = strtoul((const char *)xml_char2, NULL, 16);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_tsn"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->tsn = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.data_ssn"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->ssn = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) {
|
||||
et_parse_sctp_data_chunk(doc, cur_node, sctp_hdr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_parse_sctp_init_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_inithdr_t * const sctp_hdr)
|
||||
{
|
||||
xmlNode *cur_node = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
xmlChar *xml_char2 = NULL;
|
||||
|
||||
if ((NULL != sctp_node) && (NULL != sctp_hdr)) {
|
||||
xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_out_streams"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_nr_in_streams"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_credit"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initial_tsn"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.init_initiate_tag"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) {
|
||||
et_parse_sctp_init_chunk(doc, cur_node, sctp_hdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_parse_sctp_init_ack_chunk(xmlDocPtr doc, const xmlNode const *sctp_node, sctp_initackhdr_t * const sctp_hdr)
|
||||
{
|
||||
xmlNode *cur_node = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
xmlChar *xml_char2 = NULL;
|
||||
|
||||
if ((NULL != sctp_node) && (NULL != sctp_hdr)) {
|
||||
xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_out_streams"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->num_outbound_streams = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_nr_in_streams"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)(xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->num_inbound_streams = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_credit"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->a_rwnd = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initial_tsn"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->initial_tsn = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.initack_initiate_tag"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"show");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->init_tag = strtoul((const char *)xml_char2, NULL, 16);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) {
|
||||
et_parse_sctp_init_ack_chunk(doc, cur_node, sctp_hdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_parse_sctp(xmlDocPtr doc, const xmlNode const *sctp_node, et_sctp_hdr_t * const sctp_hdr)
|
||||
{
|
||||
xmlNode *cur_node = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
xmlChar *xml_char2 = NULL;
|
||||
|
||||
if ((NULL != sctp_node) && (NULL != sctp_hdr)) {
|
||||
if ((!xmlStrcmp(sctp_node->name, (const xmlChar *)"proto"))) {
|
||||
xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"s1ap"))) {
|
||||
xmlFree(xml_char);
|
||||
xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"pos");
|
||||
if (NULL != xml_char) {
|
||||
sctp_hdr->u.data_hdr.payload.xml_stream_pos_offset = strtoul((const char *)xml_char, NULL, 0);
|
||||
xmlFree(xml_char);
|
||||
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"size");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size = strtoul((const char *)xml_char2, NULL, 0);
|
||||
sctp_hdr->u.data_hdr.payload.binary_stream = calloc(1, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size);
|
||||
sctp_hdr->u.data_hdr.payload.binary_stream_pos = 0;
|
||||
fprintf(stdout, "Allocating payload of sctp_hdr %p %u bytes\n", sctp_hdr, sctp_hdr->u.data_hdr.payload.binary_stream_allocated_size);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
et_parse_s1ap(doc, sctp_node, &sctp_hdr->u.data_hdr.payload);
|
||||
et_decode_s1ap(&sctp_hdr->u.data_hdr.payload);
|
||||
return;
|
||||
}
|
||||
}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
}
|
||||
//if ((cur_node->type == XML_ATTRIBUTE_NODE) || (cur_node->type == XML_ELEMENT_NODE)) {
|
||||
xml_char = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"name");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.srcport"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->src_port = strtoul((const char *)xml_char2, NULL, 16);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.dstport"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->dst_port = strtoul((const char *)xml_char2, NULL, 16);
|
||||
xmlFree(xml_char2);
|
||||
}
|
||||
} else if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp.chunk_type"))) {
|
||||
xml_char2 = xmlGetProp((xmlNode *)sctp_node, (const xmlChar *)"value");
|
||||
if (NULL != xml_char2) {
|
||||
sctp_hdr->chunk_type = strtoul((const char *)xml_char2, NULL, 0);
|
||||
xmlFree(xml_char2);
|
||||
switch (sctp_hdr->chunk_type) {
|
||||
case SCTP_CID_DATA:
|
||||
et_parse_sctp_data_chunk(doc, sctp_node->parent, &sctp_hdr->u.data_hdr);
|
||||
break;
|
||||
case SCTP_CID_INIT:
|
||||
et_parse_sctp_init_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_hdr);
|
||||
break;
|
||||
case SCTP_CID_INIT_ACK:
|
||||
et_parse_sctp_init_ack_chunk(doc, sctp_node->parent, &sctp_hdr->u.init_ack_hdr);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (cur_node = sctp_node->children; cur_node; cur_node = cur_node->next) {
|
||||
et_parse_sctp(doc, cur_node, sctp_hdr);
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
void et_packet_shift_timing(et_packet_t * const packet, const struct timeval * const shift)
|
||||
{
|
||||
timeval_add(&packet->time_relative_to_first_packet, &packet->time_relative_to_first_packet, shift);
|
||||
AssertFatal((packet->time_relative_to_first_packet.tv_sec >= 0) && (packet->time_relative_to_first_packet.tv_usec >= 0),
|
||||
"Bad timing result time_relative_to_first_packet=%d.%d packet num %u, original frame number %u",
|
||||
packet->time_relative_to_first_packet.tv_sec,
|
||||
packet->time_relative_to_first_packet.tv_usec,
|
||||
packet->packet_number,
|
||||
packet->original_frame_number);
|
||||
|
||||
timeval_add(&packet->time_relative_to_last_received_packet, &packet->time_relative_to_last_received_packet, shift);
|
||||
AssertFatal((packet->time_relative_to_last_received_packet.tv_sec >= 0) && (packet->time_relative_to_last_received_packet.tv_usec >= 0),
|
||||
"Bad timing result time_relative_to_last_received_packet=%d.%d packet num %u, original frame number %u",
|
||||
packet->time_relative_to_last_received_packet.tv_sec,
|
||||
packet->time_relative_to_last_received_packet.tv_usec,
|
||||
packet->packet_number,
|
||||
packet->original_frame_number);
|
||||
|
||||
timeval_add(&packet->time_relative_to_last_sent_packet, &packet->time_relative_to_last_sent_packet, shift);
|
||||
AssertFatal((packet->time_relative_to_last_sent_packet.tv_sec >= 0) && (packet->time_relative_to_last_sent_packet.tv_usec >= 0),
|
||||
"Bad timing result time_relative_to_last_sent_packet=%d.%d packet num %u, original frame number %u",
|
||||
packet->time_relative_to_last_sent_packet.tv_sec,
|
||||
packet->time_relative_to_last_sent_packet.tv_usec,
|
||||
packet->packet_number,
|
||||
packet->original_frame_number);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
et_packet_t* et_parse_xml_packet(xmlDocPtr doc, xmlNodePtr node)
|
||||
{
|
||||
|
||||
et_packet_t *packet = NULL;
|
||||
xmlNode *cur_node = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
float afloat = (float)0.0;
|
||||
static struct timeval initial_time = { .tv_sec = 0, .tv_usec = 0 };
|
||||
static struct timeval relative_last_sent_packet = { .tv_sec = 0, .tv_usec = 0 };
|
||||
static struct timeval relative_last_received_packet = { .tv_sec = 0, .tv_usec = 0 };
|
||||
static char first_packet = 1;
|
||||
static char first_sent_packet = 1;
|
||||
static char first_received_packet = 1;
|
||||
static unsigned int packet_number = 1;
|
||||
|
||||
|
||||
if (NULL != node) {
|
||||
packet = calloc(1, sizeof(*packet));
|
||||
|
||||
xml_char = xmlGetProp(node, (const xmlChar *)"action");
|
||||
packet->action = et_action_str2et_action_t(xml_char);
|
||||
packet->status = ET_PACKET_STATUS_NONE;
|
||||
xmlFree(xml_char);
|
||||
packet->packet_number = packet_number++;
|
||||
|
||||
for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
|
||||
//if (cur_node->type == XML_ELEMENT_NODE) {
|
||||
if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.time_relative"))) {
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value");
|
||||
afloat = atof((const char*)xml_char);
|
||||
xmlFree(xml_char);
|
||||
fprintf(stdout, "Parsing packet frame.time_relative: %f\n", afloat);
|
||||
packet->time_relative_to_first_packet.tv_sec = (int)afloat;
|
||||
packet->time_relative_to_first_packet.tv_usec = (int)((afloat - packet->time_relative_to_first_packet.tv_sec)*1000000.0);
|
||||
|
||||
if (first_packet > 0) {
|
||||
initial_time = packet->time_relative_to_first_packet;
|
||||
packet->time_relative_to_first_packet.tv_sec = 0;
|
||||
packet->time_relative_to_first_packet.tv_usec = 0;
|
||||
first_packet = 0;
|
||||
} else {
|
||||
timersub(&packet->time_relative_to_first_packet, &initial_time,
|
||||
&packet->time_relative_to_first_packet);
|
||||
}
|
||||
} else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"frame.number"))) {
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value");
|
||||
packet->original_frame_number = strtoul((const char *)xml_char, NULL, 0);
|
||||
fprintf(stdout, "Parsing packet frame.number: %u\n", packet->original_frame_number);
|
||||
xmlFree(xml_char);
|
||||
} else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.src"))) {
|
||||
xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
|
||||
et_ip_str2et_ip(xml_char, &packet->ip_hdr.src);
|
||||
xmlFree(xml_char);
|
||||
} else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"ip.dst"))) {
|
||||
xml_char = xmlNodeListGetString(doc, cur_node->xmlChildrenNode, 1);
|
||||
et_ip_str2et_ip(xml_char, &packet->ip_hdr.dst);
|
||||
xmlFree(xml_char);
|
||||
} else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"proto"))) {
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"name");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"sctp"))) {
|
||||
et_parse_sctp(doc, cur_node, &packet->sctp_hdr);
|
||||
}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
} else if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"eNB.instance"))) {
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"value");
|
||||
packet->enb_instance = strtoul((const char *)xml_char, NULL, 0);
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
//}
|
||||
}
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
et_scenario_t* et_generate_scenario(
|
||||
const char * const tsml_out_scenario_filename)
|
||||
{
|
||||
xmlDocPtr doc = NULL;
|
||||
xmlNodePtr root = NULL;
|
||||
xmlNodePtr node = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
et_scenario_t *scenario = NULL;
|
||||
et_packet_t *last_packet = NULL;
|
||||
et_packet_t *packet = NULL;
|
||||
et_packet_t **next_packet = NULL;
|
||||
|
||||
doc = xmlParseFile(tsml_out_scenario_filename);
|
||||
if (NULL == doc) {
|
||||
AssertFatal (0, "Could not parse scenario xml file %s!\n", tsml_out_scenario_filename);
|
||||
} else {
|
||||
fprintf(stdout, "Test scenario file to play: %s\n", tsml_out_scenario_filename);
|
||||
//xmlDebugDumpDocument(NULL, doc);
|
||||
}
|
||||
|
||||
// Get root
|
||||
root = xmlDocGetRootElement(doc);
|
||||
if (NULL != root) {
|
||||
if ((!xmlStrcmp(root->name, (const xmlChar *)"scenario"))) {
|
||||
xml_char = xmlGetProp(root, (const xmlChar *)"name");
|
||||
printf("scenario name: %s\n", xml_char);
|
||||
scenario = calloc(1, sizeof(*scenario));
|
||||
scenario->name = xml_char; // nodup nofree
|
||||
|
||||
next_packet = &scenario->list_packet;
|
||||
for (node = root->children; node != NULL; node = node->next) {
|
||||
if ((!xmlStrcmp(node->name, (const xmlChar *)"packet"))) {
|
||||
packet = et_parse_xml_packet(doc, node);
|
||||
if (NULL != packet) {
|
||||
// special case: S1AP same frame for 2 packets
|
||||
if (NULL != last_packet) {
|
||||
if (last_packet->original_frame_number == packet->original_frame_number) {
|
||||
// updating because these informations are not in 2nd sctp header (same IP packet)
|
||||
packet->sctp_hdr.dst_port = last_packet->sctp_hdr.dst_port;
|
||||
packet->sctp_hdr.src_port = last_packet->sctp_hdr.src_port;
|
||||
}
|
||||
}
|
||||
*next_packet = packet;
|
||||
next_packet = &packet->next;
|
||||
} else {
|
||||
fprintf(stdout, "WARNING omitted packet\n");
|
||||
}
|
||||
}
|
||||
last_packet = packet;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Empty xml document\n");
|
||||
}
|
||||
xmlFreeDoc(doc);
|
||||
xmlCleanupParser();
|
||||
return scenario;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int et_generate_xml_scenario(
|
||||
const char const * xml_in_dir_name,
|
||||
const char const * xml_in_scenario_filename,
|
||||
const char const * enb_config_filename,
|
||||
char const * tsml_out_scenario_filename)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
//int fd_pdml_in;
|
||||
xsltStylesheetPtr cur = NULL;
|
||||
xmlDocPtr doc, res;
|
||||
FILE *play_scenario_file = NULL;
|
||||
const char *params[2*ENB_CONFIG_MAX_XSLT_PARAMS];
|
||||
int nb_params = 0;
|
||||
int i,j;
|
||||
char astring[1024];
|
||||
struct in_addr addr;
|
||||
int ret = 0;
|
||||
|
||||
memset(astring, 0, sizeof(astring));
|
||||
if (getcwd(astring, sizeof(astring)) != NULL) {
|
||||
fprintf(stdout, "working in %s directory\n", astring);
|
||||
} else {
|
||||
perror("getcwd() ERROR");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
xmlSubstituteEntitiesDefault(1);
|
||||
xmlLoadExtDtdDefaultValue = 1;
|
||||
cur = xsltParseStylesheetFile((const xmlChar *)"/usr/share/oai/xsl/play_scenario.xsl");
|
||||
if (NULL == cur) {
|
||||
AssertFatal (0, "Could not parse stylesheet file /usr/share/oai/xsl/play_scenario.xsl!\n");
|
||||
} else {
|
||||
fprintf(stdout, "XSLT style sheet: /usr/share/oai/xsl/play_scenario.xsl\n");
|
||||
}
|
||||
|
||||
doc = xmlParseFile(xml_in_scenario_filename);
|
||||
if (NULL == doc) {
|
||||
AssertFatal (0, "Could not parse scenario xml file %s!\n", xml_in_scenario_filename);
|
||||
} else {
|
||||
fprintf(stdout, "Test scenario file: %s\n", xml_in_scenario_filename);
|
||||
}
|
||||
|
||||
for (i = 0; i < g_enb_properties.number; i++) {
|
||||
// eNB S1-C IPv4 address
|
||||
sprintf(astring, "enb%d_s1c", i);
|
||||
params[nb_params++] = strdup(astring);
|
||||
addr.s_addr = g_enb_properties.properties[i]->enb_ipv4_address_for_S1_MME;
|
||||
sprintf(astring, "\"%s\"", inet_ntoa(addr));
|
||||
params[nb_params++] = strdup(astring);
|
||||
|
||||
// MME S1-C IPv4 address
|
||||
for (j = 0; j < g_enb_properties.properties[i]->nb_mme; j++) {
|
||||
sprintf(astring, "mme%d_s1c_%d", i, j);
|
||||
params[nb_params++] = strdup(astring);
|
||||
AssertFatal (g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address,
|
||||
"Only support MME IPv4 address\n");
|
||||
sprintf(astring, "\"%s\"", g_enb_properties.properties[i]->mme_ip_address[j].ipv4_address);
|
||||
params[nb_params++] = strdup(astring);
|
||||
}
|
||||
}
|
||||
params[nb_params] = NULL;
|
||||
res = xsltApplyStylesheet(cur, doc, params);
|
||||
if (NULL != res) {
|
||||
sprintf((char *)tsml_out_scenario_filename,"%s",xml_in_scenario_filename);
|
||||
if (et_strip_extension((char *)tsml_out_scenario_filename) > 0) {
|
||||
strcat((char *)tsml_out_scenario_filename, ".tsml");
|
||||
play_scenario_file = fopen( tsml_out_scenario_filename, "w+");
|
||||
if (NULL != play_scenario_file) {
|
||||
xsltSaveResultToFile(play_scenario_file, res, cur);
|
||||
fclose(play_scenario_file);
|
||||
fprintf(stdout, "Wrote test scenario to %s\n", tsml_out_scenario_filename);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR in fopen(%s)\n", tsml_out_scenario_filename);
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "ERROR in strip_extension()\n");
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "ERROR in xsltApplyStylesheet()\n");
|
||||
ret = -1;
|
||||
}
|
||||
xsltFreeStylesheet(cur);
|
||||
xmlFreeDoc(doc);
|
||||
xmlFreeDoc(res);
|
||||
|
||||
xsltCleanupGlobals();
|
||||
xmlCleanupParser();
|
||||
return ret;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
play_scenario_s1ap_compare_ie.c
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <crypt.h>
|
||||
#include <errno.h>
|
||||
#include <libxml/tree.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/xpathInternals.h>
|
||||
#include "tree.h"
|
||||
#include "queue.h"
|
||||
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "platform_types.h"
|
||||
#include "assertions.h"
|
||||
#include "conversions.h"
|
||||
#include "s1ap_common.h"
|
||||
#include "play_scenario_s1ap_eNB_defs.h"
|
||||
#include "play_scenario.h"
|
||||
//------------------------------------------------------------------------------
|
||||
extern et_scenario_t *g_scenario;
|
||||
extern uint32_t g_constraints;
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//asn_comp_rval_t * et_s1ap_ies_is_matching(const S1AP_PDU_PR present, s1ap_message * const m1, s1ap_message * const m2, const uint32_t constraints)
|
||||
//{
|
||||
//}
|
||||
|
||||
void update_xpath_node_mme_ue_s1ap_id(et_s1ap_t * const s1ap, xmlNode *node, const S1ap_MME_UE_S1AP_ID_t new_id)
|
||||
{
|
||||
xmlNode *cur_node = NULL;
|
||||
xmlAttrPtr attr = NULL;
|
||||
xmlChar *xml_char = NULL;
|
||||
int size = 0;
|
||||
int pos = 0;
|
||||
int go_deeper_in_tree = 1;
|
||||
//S1AP_INFO("%s() mme_ue_s1ap_id %u\n", __FUNCTION__, new_id);
|
||||
|
||||
// modify
|
||||
for (cur_node = (xmlNode *)node; cur_node; cur_node = cur_node->next) {
|
||||
go_deeper_in_tree = 1;
|
||||
if ((!xmlStrcmp(cur_node->name, (const xmlChar *)"field"))) {
|
||||
// do not get hidden fields
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"hide");
|
||||
if (NULL != xml_char) {
|
||||
if ((!xmlStrcmp(xml_char, (const xmlChar *)"yes"))) {
|
||||
go_deeper_in_tree = 0;
|
||||
}
|
||||
xmlFree(xml_char);
|
||||
}
|
||||
if (0 < go_deeper_in_tree) {
|
||||
// first get size
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"pos");
|
||||
if (NULL != xml_char) {
|
||||
pos = strtoul((const char *)xml_char, NULL, 0);
|
||||
pos -= s1ap->xml_stream_pos_offset;
|
||||
AssertFatal(pos >= 0, "Bad pos %d xml_stream_pos_offset %d", pos, s1ap->xml_stream_pos_offset);
|
||||
xmlFree(xml_char);
|
||||
xml_char = xmlGetProp((xmlNode *)cur_node, (const xmlChar *)"size");
|
||||
if (NULL != xml_char) {
|
||||
const xmlChar value_d[32];
|
||||
const xmlChar value_h[20];
|
||||
const xmlChar showname[64];
|
||||
int ret = 0;
|
||||
int pos2 = 0;
|
||||
unsigned long int uli = 0;
|
||||
char hex[3] = {0,0,0};
|
||||
char *end_ptr = NULL;
|
||||
|
||||
size = strtoul((const char *)xml_char, NULL, 0);
|
||||
xmlFree(xml_char);
|
||||
// second: try to set value (always hex)
|
||||
ret = snprintf((char *)value_d, 32, "%ld", new_id);
|
||||
AssertFatal((ret > 0) && (ret < 32), "Could not convert int to dec str");
|
||||
ret = snprintf((char *)value_h, 20, "C0%08X", new_id);
|
||||
AssertFatal((ret > 0) && (ret < 20), "Could not convert int to hex str");
|
||||
ret = snprintf((char *)showname, 64, "MME-UE-S1AP-ID: %d", new_id);
|
||||
AssertFatal((ret > 0) && (ret < 64), "Could not convert int to dec str");
|
||||
|
||||
attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"value", value_h);
|
||||
attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"show", value_d);
|
||||
attr = xmlSetProp((xmlNode *)cur_node, (const xmlChar *)"showname", showname);
|
||||
//TODO update s1ap->binary_stream @pos with new_id_hex, size
|
||||
AssertFatal((pos+size) < s1ap->binary_stream_allocated_size, "Rewrite of mme_ue_s1ap_id out of bounds of binary_stream");
|
||||
//avoid endianess issues
|
||||
do {
|
||||
hex[0] = value_h[pos2++];
|
||||
hex[1] = value_h[pos2++];
|
||||
hex[2] = '\0';
|
||||
end_ptr = hex;
|
||||
uli = strtoul(hex, &end_ptr, 16);
|
||||
AssertFatal((uli != ULONG_MAX) && (end_ptr != NULL) && (*end_ptr == '\0'), "Conversion of hexstring %s failed returned %lu errno %d", hex, uli, errno);
|
||||
s1ap->binary_stream[pos++] = (unsigned char)uli;
|
||||
} while (pos2 < (2*5));
|
||||
// update ASN1
|
||||
et_decode_s1ap(s1ap);
|
||||
//S1AP_INFO("Updated ASN1 for %s\n", showname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0 < go_deeper_in_tree) {
|
||||
update_xpath_node_mme_ue_s1ap_id(s1ap, cur_node->children, new_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* update_xpath_nodes:
|
||||
* @nodes: the nodes set.
|
||||
* @value: the new value for the node(s)
|
||||
*
|
||||
* Prints the @nodes content to @output.
|
||||
* From http://www.xmlsoft.org/examples/#xpath2.c
|
||||
*/
|
||||
void update_xpath_nodes_mme_ue_s1ap_id(et_s1ap_t * const s1ap_payload, xmlNodeSetPtr nodes, const S1ap_MME_UE_S1AP_ID_t new_id)
|
||||
{
|
||||
int size = 0;
|
||||
int i = 0;
|
||||
xmlNode *s1ap_node = NULL;
|
||||
|
||||
size = (nodes) ? nodes->nodeNr : 0;
|
||||
//S1AP_DEBUG("%s() num nodes %u\n", __FUNCTION__, size);
|
||||
|
||||
/*
|
||||
* NOTE: the nodes are processed in reverse order, i.e. reverse document
|
||||
* order because xmlNodeSetContent can actually free up descendant
|
||||
* of the node and such nodes may have been selected too ! Handling
|
||||
* in reverse order ensure that descendant are accessed first, before
|
||||
* they get removed. Mixing XPath and modifications on a tree must be
|
||||
* done carefully !
|
||||
*/
|
||||
for(i = size - 1; i >= 0; i--) {
|
||||
s1ap_node = nodes->nodeTab[i];
|
||||
AssertFatal(NULL != s1ap_node, "One element of resultset of XPATH expression is NULL\n");
|
||||
update_xpath_node_mme_ue_s1ap_id(s1ap_payload, s1ap_node, new_id);
|
||||
/*
|
||||
* All the elements returned by an XPath query are pointers to
|
||||
* elements from the tree *except* namespace nodes where the XPath
|
||||
* semantic is different from the implementation in libxml2 tree.
|
||||
* As a result when a returned node set is freed when
|
||||
* xmlXPathFreeObject() is called, that routine must check the
|
||||
* element type. But node from the returned set may have been removed
|
||||
* by xmlNodeSetContent() resulting in access to freed data.
|
||||
* This can be exercised by running valgrind
|
||||
* There is 2 ways around it:
|
||||
* - make a copy of the pointers to the nodes from the result set
|
||||
* then call xmlXPathFreeObject() and then modify the nodes
|
||||
* or
|
||||
* - remove the reference to the modified nodes from the node set
|
||||
* as they are processed, if they are not namespace nodes.
|
||||
*/
|
||||
if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL) {
|
||||
nodes->nodeTab[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
int et_s1ap_update_mme_ue_s1ap_id(et_packet_t * const packet, const S1ap_MME_UE_S1AP_ID_t old_id, const S1ap_MME_UE_S1AP_ID_t new_id)
|
||||
{
|
||||
xmlChar xpath_expression[ET_XPATH_EXPRESSION_MAX_LENGTH];
|
||||
int ret = 0;
|
||||
xmlDocPtr doc = NULL;
|
||||
xmlXPathContextPtr xpath_ctx = NULL;
|
||||
xmlXPathObjectPtr xpath_obj = NULL;
|
||||
|
||||
//S1AP_DEBUG("%s() packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n", __FUNCTION__, packet->packet_number, packet->original_frame_number, old_id, new_id);
|
||||
|
||||
ret = snprintf(xpath_expression, ET_XPATH_EXPRESSION_MAX_LENGTH, "//field[@name=\"s1ap.MME_UE_S1AP_ID\"][@show=\"%u\"]", old_id);
|
||||
AssertFatal((ret > 0) && (ret < ET_XPATH_EXPRESSION_MAX_LENGTH), "Could not build XPATH expression err=%d", ret);
|
||||
|
||||
doc = packet->sctp_hdr.u.data_hdr.payload.doc;
|
||||
// Create xpath evaluation context
|
||||
xpath_ctx = xmlXPathNewContext(doc);
|
||||
if(xpath_ctx == NULL) {
|
||||
fprintf(stderr,"Error: unable to create new XPath context\n");
|
||||
xmlFreeDoc(doc);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
// Evaluate xpath expression
|
||||
xpath_obj = xmlXPathEvalExpression(xpath_expression, xpath_ctx);
|
||||
xmlXPathFreeContext(xpath_ctx);
|
||||
AssertFatal(xpath_obj != NULL, "Unable to evaluate XPATH expression \"%s\"\n", xpath_expression);
|
||||
|
||||
if(xmlXPathNodeSetIsEmpty(xpath_obj->nodesetval)){
|
||||
xmlXPathFreeObject(xpath_obj);
|
||||
S1AP_DEBUG("%s() No match \"%s\"packet num %u original frame number %u, mme_ue_s1ap_id %u -> %u\n",
|
||||
__FUNCTION__, xpath_expression, packet->packet_number, packet->original_frame_number, old_id, new_id);
|
||||
return -1;
|
||||
}
|
||||
// update selected nodes
|
||||
update_xpath_nodes_mme_ue_s1ap_id(&packet->sctp_hdr.u.data_hdr.payload, xpath_obj->nodesetval, new_id);
|
||||
|
||||
// Cleanup of XPath data
|
||||
xmlXPathFreeObject(xpath_obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "queue.h"
|
||||
#include "tree.h"
|
||||
|
||||
#include "sctp_eNB_defs.h"
|
||||
|
||||
#ifndef PLAY_SCENARIO_S1AP_ENB_DEFS_H_
|
||||
#define PLAY_SCENARIO_S1AP_ENB_DEFS_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 S1AP_PORT_NUMBER (36412)
|
||||
#define S1AP_SCTP_PPID (18)
|
||||
|
||||
#define X2AP_PORT_NUMBER (36422)
|
||||
#define X2AP_SCTP_PPID (27)
|
||||
|
||||
#define S1AP_ENB_NAME_LENGTH_MAX (150)
|
||||
|
||||
typedef enum {
|
||||
/* Disconnected state: initial state for any association. */
|
||||
S1AP_ENB_STATE_DISCONNECTED = 0x0,
|
||||
/* State waiting for S1 Setup response message if eNB is MME accepted or
|
||||
* S1 Setup failure if MME rejects the eNB.
|
||||
*/
|
||||
S1AP_ENB_STATE_WAITING = 0x1,
|
||||
/* The eNB is successfully connected to MME, UE contexts can be created. */
|
||||
S1AP_ENB_STATE_CONNECTED = 0x2,
|
||||
/* The MME has sent an overload start message. Once the MME disables the
|
||||
* OVERLOAD marker, the state of the association will be
|
||||
* S1AP_ENB_STATE_CONNECTED.
|
||||
*/
|
||||
S1AP_ENB_OVERLOAD = 0x3,
|
||||
/* Max number of states available */
|
||||
S1AP_ENB_STATE_MAX,
|
||||
} s1ap_eNB_state_t;
|
||||
|
||||
|
||||
/* If the Overload Action IE in the OVERLOAD START message is set to
|
||||
* - “reject all RRC connection establishments for non-emergency mobile
|
||||
* originated data transfer “ (i.e. reject traffic corresponding to RRC cause
|
||||
* “mo-data “ (TS 36.331 [16])), or
|
||||
* - “reject all RRC connection establishments for signalling “ (i.e. reject
|
||||
* traffic corresponding to RRC cause “modata” and “mo-signalling”
|
||||
* (TS 36.331 [16])),or
|
||||
* - “only permit RRC connection establishments for emergency sessions and
|
||||
* mobile terminated services” (i.e. only permit traffic corresponding to RRC
|
||||
* cause “emergency” and “mt-Access” (TS 36.331 [16])).
|
||||
*
|
||||
* NOTE: When the Overload Action IE is set to “only permit RRC connection
|
||||
* establishments for emergency sessions and mobile terminated services”,
|
||||
* emergency calls with RRC cause “highPriorityAcess” from high priority users
|
||||
* are rejected (TS 24.301 [24]).
|
||||
*/
|
||||
typedef enum {
|
||||
S1AP_OVERLOAD_REJECT_MO_DATA = 0x0,
|
||||
S1AP_OVERLOAD_REJECT_ALL_SIGNALLING = 0x1,
|
||||
S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT = 0x2,
|
||||
S1AP_NO_OVERLOAD = 0x3,
|
||||
S1AP_OVERLOAD_MAX,
|
||||
} s1ap_overload_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 mme_group_id;
|
||||
STAILQ_ENTRY(served_group_id_s) next;
|
||||
};
|
||||
|
||||
/* Served mme code for a particular MME */
|
||||
struct mme_code_s {
|
||||
uint8_t mme_code;
|
||||
STAILQ_ENTRY(mme_code_s) next;
|
||||
};
|
||||
|
||||
/* Served gummei element */
|
||||
struct served_gummei_s {
|
||||
/* Number of MME served PLMNs */
|
||||
uint8_t nb_served_plmns;
|
||||
/* List of served PLMNs by MME */
|
||||
STAILQ_HEAD(served_plmns_s, plmn_identity_s) served_plmns;
|
||||
|
||||
/* Number of group id in list */
|
||||
uint8_t nb_group_id;
|
||||
/* Served group id list */
|
||||
STAILQ_HEAD(served_group_ids_s, served_group_id_s) served_group_ids;
|
||||
|
||||
/* Number of MME code */
|
||||
uint8_t nb_mme_code;
|
||||
/* MME Code to uniquely identify an MME within an MME pool area */
|
||||
STAILQ_HEAD(mme_codes_s, mme_code_s) mme_codes;
|
||||
|
||||
/* Next GUMMEI element */
|
||||
STAILQ_ENTRY(served_gummei_s) next;
|
||||
};
|
||||
|
||||
struct s1ap_eNB_instance_s;
|
||||
|
||||
/* This structure describes association of a eNB to a MME */
|
||||
typedef struct s1ap_eNB_mme_data_s {
|
||||
/* MME descriptors tree, ordered by sctp assoc id */
|
||||
RB_ENTRY(s1ap_eNB_mme_data_s) entry;
|
||||
|
||||
/* This is the optional name provided by the MME */
|
||||
char *mme_name;
|
||||
net_ip_address_t mme_net_ip_address; // useful for joining assoc_id and ip address of packets
|
||||
|
||||
/* List of served GUMMEI per MME. There is one GUMMEI per RAT with a max
|
||||
* number of 8 RATs but in our case only one is used. The LTE related pool
|
||||
* configuration is included on the first place in the list.
|
||||
*/
|
||||
STAILQ_HEAD(served_gummeis_s, served_gummei_s) served_gummei;
|
||||
|
||||
/* Relative processing capacity of an MME with respect to the other MMEs
|
||||
* in the pool in order to load-balance MMEs within a pool as defined
|
||||
* in TS 23.401.
|
||||
*/
|
||||
uint8_t relative_mme_capacity;
|
||||
|
||||
/* Current MME overload information (if any). */
|
||||
s1ap_overload_state_t overload_state;
|
||||
/* Current eNB->MME S1AP association state */
|
||||
s1ap_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/S1AP */
|
||||
uint16_t cnx_id;
|
||||
|
||||
/* SCTP association id */
|
||||
int32_t assoc_id;
|
||||
|
||||
/* Only meaningfull in virtual mode */
|
||||
struct s1ap_eNB_instance_s *s1ap_eNB_instance;
|
||||
} s1ap_eNB_mme_data_t;
|
||||
|
||||
typedef struct s1ap_eNB_instance_s {
|
||||
/* Next s1ap eNB association.
|
||||
* Only used for virtual mode.
|
||||
*/
|
||||
STAILQ_ENTRY(s1ap_eNB_instance_s) s1ap_eNB_entries;
|
||||
|
||||
/* Number of MME requested by eNB (tree size) */
|
||||
uint32_t s1ap_mme_nb;
|
||||
/* Number of MME for which association is pending */
|
||||
uint32_t s1ap_mme_pending_nb;
|
||||
/* Number of MME successfully associated to eNB */
|
||||
uint32_t s1ap_mme_associated_nb;
|
||||
/* Tree of S1AP MME associations ordered by association ID */
|
||||
RB_HEAD(s1ap_mme_map, s1ap_eNB_mme_data_s) s1ap_mme_head;
|
||||
|
||||
/* TODO: add a map ordered by relative MME capacity */
|
||||
|
||||
/* Tree of UE ordered by eNB_ue_s1ap_id's */
|
||||
RB_HEAD(s1ap_ue_map, s1ap_eNB_ue_context_s) s1ap_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;
|
||||
net_ip_address_t s1c_net_ip_address;
|
||||
|
||||
/* 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 */
|
||||
enum cell_type_e 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;
|
||||
|
||||
} s1ap_eNB_instance_t;
|
||||
|
||||
typedef struct {
|
||||
/* List of served eNBs
|
||||
* Only used for virtual mode
|
||||
*/
|
||||
STAILQ_HEAD(s1ap_eNB_instances_head_s, s1ap_eNB_instance_s) s1ap_eNB_instances_head;
|
||||
/* Nb of registered eNBs */
|
||||
uint8_t nb_registered_eNBs;
|
||||
|
||||
/* Generate a unique connexion id used between S1AP and SCTP */
|
||||
uint16_t global_cnx_id;
|
||||
} s1ap_eNB_internal_data_t;
|
||||
|
||||
int s1ap_eNB_compare_assoc_id(
|
||||
struct s1ap_eNB_mme_data_s *p1, struct s1ap_eNB_mme_data_s *p2);
|
||||
|
||||
/* Generate the tree management functions */
|
||||
RB_PROTOTYPE(s1ap_mme_map, s1ap_eNB_mme_data_s, entry,
|
||||
s1ap_eNB_compare_assoc_id);
|
||||
|
||||
#endif /* PLAY_SCENARIO_S1AP_ENB_DEFS_H_ */
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/*
|
||||
play_scenario_sctp.c
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
*/
|
||||
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "intertask_interface.h"
|
||||
#include "platform_types.h"
|
||||
#include "assertions.h"
|
||||
#include "play_scenario.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
asn_comp_rval_t *et_sctp_data_is_matching(sctp_datahdr_t *const sctp1, sctp_datahdr_t *const sctp2, const uint32_t constraints)
|
||||
{
|
||||
asn_comp_rval_t *rv = NULL;
|
||||
|
||||
// no comparison for ports
|
||||
if (sctp1->ppid != sctp2->ppid) {
|
||||
S1AP_WARN("No Matching SCTP PPID %u %u\n", sctp1->ppid, sctp2->ppid);
|
||||
rv = calloc(1, sizeof(asn_comp_rval_t));
|
||||
rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_PPID;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (sctp1->assoc_id != sctp2->assoc_id) {
|
||||
S1AP_WARN("No Matching SCTP assoc id %u %u\n", sctp1->assoc_id, sctp2->assoc_id);
|
||||
rv = calloc(1, sizeof(asn_comp_rval_t));
|
||||
rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_ASSOC_ID;
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (sctp1->stream != sctp2->stream) {
|
||||
if (constraints & ET_BIT_MASK_MATCH_SCTP_STREAM) {
|
||||
rv = calloc(1, sizeof(asn_comp_rval_t));
|
||||
rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_STREAM_ID;
|
||||
return rv;
|
||||
} else {
|
||||
S1AP_WARN("No Matching SCTP stream %u %u\n", sctp1->stream, sctp2->stream);
|
||||
}
|
||||
}
|
||||
|
||||
// We do not have SSN from lower layers
|
||||
// if (sctp1->ssn != sctp2->ssn) {
|
||||
// if (constraints & ET_BIT_MASK_MATCH_SCTP_SSN) {
|
||||
// rv = calloc(1, sizeof(asn_comp_rval_t));
|
||||
// rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_SSN;
|
||||
// return rv;
|
||||
// } else {
|
||||
// S1AP_WARN("No Matching SCTP STREAM SN %u %u\n", sctp1->ssn, sctp2->ssn);
|
||||
// }
|
||||
// }
|
||||
return et_s1ap_is_matching(&sctp1->payload, &sctp2->payload, constraints);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
asn_comp_rval_t *et_sctp_is_matching(et_sctp_hdr_t *const sctp1, et_sctp_hdr_t *const sctp2, const uint32_t constraints)
|
||||
{
|
||||
// no comparison for ports
|
||||
asn_comp_rval_t *rv = NULL;
|
||||
|
||||
if (sctp1->chunk_type != sctp2->chunk_type) {
|
||||
S1AP_WARN("No Matching chunk_type %u %u\n", sctp1->chunk_type, sctp2->chunk_type);
|
||||
rv = calloc(1, sizeof(asn_comp_rval_t));
|
||||
rv->err_code = ET_ERROR_MATCH_PACKET_SCTP_CHUNK_TYPE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
switch (sctp1->chunk_type) {
|
||||
case SCTP_CID_DATA:
|
||||
return et_sctp_data_is_matching(&sctp1->u.data_hdr, &sctp2->u.data_hdr, constraints);
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT:
|
||||
AssertFatal(0, "Not needed now");
|
||||
break;
|
||||
|
||||
case SCTP_CID_INIT_ACK:
|
||||
AssertFatal(0, "Not needed now");
|
||||
break;
|
||||
|
||||
default:
|
||||
AssertFatal(0, "Not needed now cid %d", sctp1->chunk_type);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "sctp_primitives_client.h"
|
||||
|
||||
#include "s1ap_common.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "s1ap_mme.h"
|
||||
|
||||
char ip_addr[] = "127.0.0.1";
|
||||
|
||||
int assoc[2];
|
||||
uint8_t id[] = { 0x03, 0x56, 0xf0, 0xd8 };
|
||||
char identity[] = { 0x02, 0x08, 0x34 };
|
||||
char tac[] = { 0x00, 0x01 };
|
||||
char infoNAS[] = { 0x07, 0x42, 0x01, 0xE0, 0x06, 0x00, 0x00, 0xF1, 0x10, 0x00, 0x01, 0x00, 0x2C,
|
||||
0x52, 0x01, 0xC1, 0x01, 0x09, 0x10, 0x03, 0x77, 0x77, 0x77, 0x07, 0x61, 0x6E, 0x72, 0x69, 0x74,
|
||||
0x73, 0x75, 0x03, 0x63, 0x6F, 0x6D, 0x05, 0x01, 0x0A, 0x01, 0x20, 0x37, 0x27, 0x0E, 0x80, 0x80,
|
||||
0x21, 0x0A, 0x03, 0x00, 0x00, 0x0A, 0x81, 0x06, 0x0A, 0x00, 0x00, 0x01, 0x50, 0x0B, 0xF6,
|
||||
0x00, 0xF1, 0x10, 0x80, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
|
||||
uint32_t eNB_UE_S1AP_ID = 0;
|
||||
|
||||
int s1ap_eNB_generate_initial_ue_message(uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
|
||||
int s1ap_eNB_generate_initial_ue_message(uint8_t **buffer,
|
||||
uint32_t *length)
|
||||
{
|
||||
InitialUEMessageIEs initialUEmessageIEs;
|
||||
InitialUEMessageIEs *initialUEmessageIEs_p = &initialUEmessageIEs;
|
||||
memset(initialUEmessageIEs_p, 0, sizeof(InitialUEMessageIEs));
|
||||
initialUEmessageIEs.eNB_UE_S1AP_ID = eNB_UE_S1AP_ID;
|
||||
initialUEmessageIEs.nas_pdu.buf = infoNAS;
|
||||
initialUEmessageIEs.nas_pdu.size = sizeof(infoNAS);
|
||||
initialUEmessageIEs.tai.tAC.buf = tac;
|
||||
initialUEmessageIEs.tai.tAC.size = 2;
|
||||
initialUEmessageIEs.tai.pLMNidentity.buf = identity;
|
||||
initialUEmessageIEs.tai.pLMNidentity.size = 3;
|
||||
initialUEmessageIEs.eutran_cgi.pLMNidentity.buf = identity;
|
||||
initialUEmessageIEs.eutran_cgi.pLMNidentity.size = 3;
|
||||
initialUEmessageIEs.eutran_cgi.cell_ID.buf = id;
|
||||
initialUEmessageIEs.eutran_cgi.cell_ID.size = 4;
|
||||
initialUEmessageIEs.eutran_cgi.cell_ID.bits_unused = 4;
|
||||
initialUEmessageIEs.rrC_Establishment_Cause = RRC_Establishment_Cause_mo_Data;
|
||||
return s1ap_eNB_encode_initial_ue_message(initialUEmessageIEs_p, buffer, length);
|
||||
}
|
||||
|
||||
void recv_callback(uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
uint8_t *bufferS;
|
||||
uint32_t len;
|
||||
s1ap_eNB_generate_initial_ue_message(&bufferS, &len);
|
||||
sctp_send_msg(assoc[0], 1, bufferS, len);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
asn_enc_rval_t retVal;
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
SupportedTAs_Item_t ta;
|
||||
PLMNidentity_t plmnIdentity;
|
||||
asn_debug = 0;
|
||||
asn1_xer_print = 0;
|
||||
S1SetupRequestIEs s1SetupRequest;
|
||||
memset(&s1SetupRequest, 0, sizeof(S1SetupRequestIEs));
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.present = ENB_ID_PR_macroENB_ID;
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.buf = id;
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.size = 3;
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.bits_unused = 4;
|
||||
OCTET_STRING_fromBuf(&s1SetupRequest.global_ENB_ID.pLMNidentity, identity, 3);
|
||||
s1SetupRequest.presenceMask |= S1SETUPREQUESTIES_ENBNAME_PRESENT;
|
||||
OCTET_STRING_fromBuf(&s1SetupRequest.eNBname, "ENB 1 eurecom",
|
||||
strlen("ENB 1 eurecom"));
|
||||
memset(&ta, 0, sizeof(SupportedTAs_Item_t));
|
||||
memset(&plmnIdentity, 0, sizeof(PLMNidentity_t));
|
||||
OCTET_STRING_fromBuf(&ta.tAC, tac, 2);
|
||||
OCTET_STRING_fromBuf(&plmnIdentity, identity, 3);
|
||||
ASN_SEQUENCE_ADD(&ta.broadcastPLMNs, &plmnIdentity);
|
||||
ASN_SEQUENCE_ADD(&s1SetupRequest.supportedTAs, &ta);
|
||||
s1SetupRequest.defaultPagingDRX = PagingDRX_v64;
|
||||
s1ap_eNB_encode_s1setuprequest(&s1SetupRequest, &buffer, &len);
|
||||
assoc[0] = sctp_connect_to_remote_host(ip_addr, 36412, &recv_callback);
|
||||
sctp_send_msg(0, 0, buffer, len);
|
||||
free(buffer);
|
||||
// generateUplinkNASTransport(&buffer, &len);
|
||||
// sctp_send_msg(assoc[0], 0, buffer, len);
|
||||
// s1ap_mme_decode_pdu(buffer, len);
|
||||
pthread_join(sctp_get_receiver_thread(assoc[0]), NULL);
|
||||
return(0);
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include <sched.h>
|
||||
|
||||
#include "mme_config.h"
|
||||
#include "gtpv1u_sgw_defs.h"
|
||||
|
||||
#include "intertask_interface.h"
|
||||
|
||||
#include "sctp_primitives_server.h"
|
||||
#include "udp_primitives_server.h"
|
||||
#include "s1ap_mme.h"
|
||||
#include "log.h"
|
||||
#include "sgw_lite_defs.h"
|
||||
#include "ipv4_defs.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i = 0;
|
||||
int prio = 0;
|
||||
mme_config_t mme_config;
|
||||
MessageDef *message_p;
|
||||
struct sched_param param = {
|
||||
.sched_priority = 10,
|
||||
};
|
||||
|
||||
config_parse_opt_line(argc, argv, &mme_config);
|
||||
fprintf(stdout, "Starting %s ITTI test\n", PACKAGE_STRING);
|
||||
|
||||
if (setpriority(PRIO_PROCESS, 0, prio) < 0) {
|
||||
fprintf(stderr, "Cannot assign requested prio: %d\n"
|
||||
"%d:%s\n", prio, errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sched_setscheduler(0, SCHED_RR, ¶m) < 0) {
|
||||
fprintf(stderr, "Cannot assign requested scheduler policy\n"
|
||||
"%d:%s\n", errno, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Calling each layer init function */
|
||||
log_init(&mme_config);
|
||||
itti_init(TASK_MAX, tasks_info);
|
||||
sctp_init(&mme_config);
|
||||
udp_init(&mme_config);
|
||||
s1ap_mme_init(&mme_config);
|
||||
gtpv1u_init(&mme_config);
|
||||
ipv4_init(&mme_config);
|
||||
|
||||
sgw_lite_init(&mme_config);
|
||||
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, MESSAGE_TEST);
|
||||
|
||||
while(i < (1 << 15)) {
|
||||
if (send_broadcast_message(message_p) < 0) {
|
||||
fprintf(stderr, "Failed to send broadcast message %d\n", i);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Successfully sent %lu messages", get_current_message_number());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "sctp_primitives_client.h"
|
||||
|
||||
#include "s1ap_common.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "s1ap_mme.h"
|
||||
|
||||
#include "s1ap_eNB_encoder.h"
|
||||
#include "s1ap_eNB_decoder.h"
|
||||
|
||||
#define NB_OF_ENB 10
|
||||
#define NB_OF_UES 100
|
||||
|
||||
static int connected_eNB = 0;
|
||||
static char ip_addr[] = "127.0.0.1";
|
||||
uint32_t ipv4_local = 0x7F000001;
|
||||
static uint8_t id[] = { 0x03, 0x56, 0xf0, 0xd8 };
|
||||
static char identity[] = { 0x02, 0x08, 0x34 };
|
||||
static char tac[] = { 0x00, 0x01 };
|
||||
static char infoNAS[] = { 0x07, 0x42, 0x01, 0xE0, 0x06, 0x00, 0x00, 0xF1, 0x10, 0x00, 0x01, 0x00, 0x2C,
|
||||
0x52, 0x01, 0xC1, 0x01, 0x09, 0x10, 0x03, 0x77, 0x77, 0x77, 0x07, 0x61, 0x6E, 0x72, 0x69, 0x74,
|
||||
0x73, 0x75, 0x03, 0x63, 0x6F, 0x6D, 0x05, 0x01, 0x0A, 0x01, 0x20, 0x37, 0x27, 0x0E, 0x80, 0x80,
|
||||
0x21, 0x0A, 0x03, 0x00, 0x00, 0x0A, 0x81, 0x06, 0x0A, 0x00, 0x00, 0x01, 0x50, 0x0B, 0xF6,
|
||||
0x00, 0xF1, 0x10, 0x80, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01
|
||||
};
|
||||
uint32_t nb_eNB = NB_OF_ENB;
|
||||
uint32_t nb_ue = NB_OF_UES;
|
||||
|
||||
void s1ap_test_generate_s1_setup_request(uint32_t eNB_id, uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
int s1ap_test_generate_initial_ue_message(uint32_t eNB_UE_S1AP_ID,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length);
|
||||
int recv_callback(uint32_t assocId,
|
||||
uint32_t stream,
|
||||
uint8_t *buffer,
|
||||
uint32_t length);
|
||||
int sctp_connected(void *args,
|
||||
uint32_t assocId,
|
||||
uint32_t instreams,
|
||||
uint32_t outstreams);
|
||||
|
||||
void s1ap_test_generate_s1_setup_request(uint32_t eNB_id, uint8_t **buffer,
|
||||
uint32_t *length)
|
||||
{
|
||||
S1SetupRequestIEs_t s1SetupRequest;
|
||||
SupportedTAs_Item_t ta;
|
||||
PLMNidentity_t plmnIdentity;
|
||||
uint8_t *id_p = (uint8_t *)(&eNB_id + 1);
|
||||
memset(&s1SetupRequest, 0, sizeof(S1SetupRequestIEs_t));
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.present = ENB_ID_PR_macroENB_ID;
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.buf = id_p;
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.size = 3;
|
||||
s1SetupRequest.global_ENB_ID.eNB_ID.choice.macroENB_ID.bits_unused = 4;
|
||||
OCTET_STRING_fromBuf(&s1SetupRequest.global_ENB_ID.pLMNidentity, identity, 3);
|
||||
s1SetupRequest.presenceMask |= S1SETUPREQUESTIES_ENBNAME_PRESENT;
|
||||
OCTET_STRING_fromBuf(&s1SetupRequest.eNBname, "ENB 1 eurecom",
|
||||
strlen("ENB 1 eurecom"));
|
||||
memset(&ta, 0, sizeof(SupportedTAs_Item_t));
|
||||
memset(&plmnIdentity, 0, sizeof(PLMNidentity_t));
|
||||
OCTET_STRING_fromBuf(&ta.tAC, tac, 2);
|
||||
OCTET_STRING_fromBuf(&plmnIdentity, identity, 3);
|
||||
ASN_SEQUENCE_ADD(&ta.broadcastPLMNs, &plmnIdentity);
|
||||
ASN_SEQUENCE_ADD(&s1SetupRequest.supportedTAs, &ta);
|
||||
s1SetupRequest.defaultPagingDRX = PagingDRX_v64;
|
||||
s1ap_eNB_encode_s1_setup_request(&s1SetupRequest, buffer, length);
|
||||
}
|
||||
|
||||
int s1ap_test_generate_initial_ue_message(uint32_t eNB_UE_S1AP_ID,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length)
|
||||
{
|
||||
InitialUEMessageIEs_t initialUEmessageIEs;
|
||||
InitialUEMessageIEs_t *initialUEmessageIEs_p = &initialUEmessageIEs;
|
||||
memset(initialUEmessageIEs_p, 0, sizeof(InitialUEMessageIEs_t));
|
||||
initialUEmessageIEs.eNB_UE_S1AP_ID = eNB_UE_S1AP_ID & 0x00ffffff;
|
||||
initialUEmessageIEs.nas_pdu.buf = (uint8_t *)infoNAS;
|
||||
initialUEmessageIEs.nas_pdu.size = sizeof(infoNAS);
|
||||
initialUEmessageIEs.tai.tAC.buf = (uint8_t *)tac;
|
||||
initialUEmessageIEs.tai.tAC.size = 2;
|
||||
initialUEmessageIEs.tai.pLMNidentity.buf = (uint8_t *)identity;
|
||||
initialUEmessageIEs.tai.pLMNidentity.size = 3;
|
||||
initialUEmessageIEs.eutran_cgi.pLMNidentity.buf = (uint8_t *)identity;
|
||||
initialUEmessageIEs.eutran_cgi.pLMNidentity.size = 3;
|
||||
initialUEmessageIEs.eutran_cgi.cell_ID.buf = (uint8_t *)id;
|
||||
initialUEmessageIEs.eutran_cgi.cell_ID.size = 4;
|
||||
initialUEmessageIEs.eutran_cgi.cell_ID.bits_unused = 4;
|
||||
initialUEmessageIEs.rrC_Establishment_Cause = RRC_Establishment_Cause_mo_Data;
|
||||
return s1ap_eNB_encode_initial_ue_message(initialUEmessageIEs_p, buffer, length);
|
||||
}
|
||||
|
||||
int s1ap_test_generate_initial_setup_resp(uint32_t eNB_UE_S1AP_ID,
|
||||
uint32_t mme_UE_S1AP_ID,
|
||||
uint8_t eRAB_id,
|
||||
uint32_t teid,
|
||||
uint8_t **buffer,
|
||||
uint32_t *length)
|
||||
{
|
||||
InitialContextSetupResponseIEs_t initialResponseIEs;
|
||||
InitialContextSetupResponseIEs_t *initialResponseIEs_p = &initialResponseIEs;
|
||||
E_RABSetupItemCtxtSURes_t e_RABSetupItemCtxtSURes;
|
||||
memset(initialResponseIEs_p, 0, sizeof(InitialContextSetupResponseIEs_t));
|
||||
memset(&e_RABSetupItemCtxtSURes, 0, sizeof(E_RABSetupItemCtxtSURes_t));
|
||||
initialResponseIEs_p->mme_ue_s1ap_id = mme_UE_S1AP_ID;
|
||||
initialResponseIEs_p->eNB_UE_S1AP_ID = eNB_UE_S1AP_ID;
|
||||
e_RABSetupItemCtxtSURes.e_RAB_ID = eRAB_id;
|
||||
e_RABSetupItemCtxtSURes.transportLayerAddress.buf = (uint8_t *)&ipv4_local;
|
||||
e_RABSetupItemCtxtSURes.transportLayerAddress.size = 4;
|
||||
e_RABSetupItemCtxtSURes.gTP_TEID.buf = (uint8_t *)&teid;
|
||||
e_RABSetupItemCtxtSURes.gTP_TEID.size = 4;
|
||||
ASN_SEQUENCE_ADD(
|
||||
&initialResponseIEs_p->e_RABSetupListCtxtSURes.e_RABSetupItemCtxtSURes,
|
||||
&e_RABSetupItemCtxtSURes);
|
||||
return s1ap_eNB_encode_initial_context_setup_response(initialResponseIEs_p,
|
||||
buffer, length);
|
||||
}
|
||||
|
||||
int recv_callback(uint32_t assocId,
|
||||
uint32_t stream,
|
||||
uint8_t *buffer,
|
||||
uint32_t length)
|
||||
{
|
||||
S1AP_S1AP_PDU_t pdu;
|
||||
uint8_t *buffer2;
|
||||
uint32_t len;
|
||||
int j;
|
||||
|
||||
if (s1ap_eNB_decode_pdu(&pdu, buffer, length) < 0) {
|
||||
fprintf(stderr, "s1ap_eNB_decode_pdu returned status < 0\n");
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pdu.initiatingMessage.procedureCode == S1AP_ProcedureCode_id_S1Setup
|
||||
&& pdu.present == S1AP_S1AP_PDU_PR_successfulOutcome) {
|
||||
for (j = 0; j < nb_ue; j++) {
|
||||
s1ap_test_generate_initial_ue_message(j, &buffer2, &len);
|
||||
|
||||
if (sctp_send_msg(assocId, j % 64 + 1, buffer2, len) < 0) {
|
||||
fprintf(stderr,
|
||||
"sctp_send_msg returned status < 0\nSomething bad happened on SCTP layer\n");
|
||||
free(buffer2);
|
||||
break;
|
||||
}
|
||||
|
||||
free(buffer2);
|
||||
}
|
||||
} else if (pdu.initiatingMessage.procedureCode == S1AP_ProcedureCode_id_InitialContextSetup
|
||||
&& pdu.present == S1AP_PDU_PR_initiatingMessage) {
|
||||
fprintf(stdout, "Received InitialContextSetup request\n");
|
||||
s1ap_test_generate_initial_setup_resp(
|
||||
message.msg.initialContextSetupRequestIEs.eNB_UE_S1AP_ID,
|
||||
message.msg.initialContextSetupRequestIEs.mme_ue_s1ap_id,
|
||||
0x5,
|
||||
0x1,
|
||||
&buffer2,
|
||||
&len);
|
||||
|
||||
if (sctp_send_msg(assocId, stream, buffer2, len) < 0) {
|
||||
fprintf(stderr,
|
||||
"sctp_send_msg returned status < 0\nSomething bad happened on SCTP layer\n");
|
||||
free(buffer2);
|
||||
}
|
||||
|
||||
free(buffer2);
|
||||
} else {
|
||||
fprintf(stderr, "Received unexpected message %d %d\n", message.procedureCode,
|
||||
message.direction);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sctp_connected(void *args,
|
||||
uint32_t assocId,
|
||||
uint32_t instreams,
|
||||
uint32_t outstreams)
|
||||
{
|
||||
uint8_t *buffer;
|
||||
uint32_t len;
|
||||
fprintf(stdout, "New association %d\n", assocId);
|
||||
s1ap_test_generate_s1_setup_request(assocId * nb_eNB, &buffer, &len);
|
||||
|
||||
if (sctp_send_msg(assocId, 0, buffer, len) < 0) {
|
||||
free(buffer);
|
||||
fprintf(stderr,
|
||||
"sctp_send_msg returned status < 0. Something bad happened on SCTP layer\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
connected_eNB++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
asn_enc_rval_t retVal;
|
||||
int i;
|
||||
SupportedTAs_Item_t ta;
|
||||
PLMNidentity_t plmnIdentity;
|
||||
asn_debug = 0;
|
||||
asn1_xer_print = 0;
|
||||
|
||||
if (argc > 1) {
|
||||
nb_eNB = atoi(argv[1]);
|
||||
|
||||
if (argc > 2) {
|
||||
nb_ue = atoi(argv[2]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nb_eNB; i++) {
|
||||
sctp_connect_to_remote_host(ip_addr, 36412, 18, NULL, sctp_connected,
|
||||
recv_callback);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
// generateUplinkNASTransport(&buffer, &len);
|
||||
// sctp_send_msg(assoc[0], 0, buffer, len);
|
||||
// s1ap_mme_decode_pdu(buffer, len);
|
||||
sctp_terminate();
|
||||
return(0);
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "s1ap_common.h"
|
||||
#include "s1ap_eNB_decoder.h"
|
||||
#include "s1ap_mme_decoder.h"
|
||||
#include "s1ap_eNB_encoder.h"
|
||||
|
||||
#define MAX_BUF_LENGTH (1024)
|
||||
|
||||
typedef struct {
|
||||
char *procedure_name;
|
||||
uint8_t buffer[MAX_BUF_LENGTH];
|
||||
uint32_t buf_len;
|
||||
} s1ap_test_t;
|
||||
|
||||
s1ap_test_t s1ap_test[] = {
|
||||
// {
|
||||
// .procedure_name = "Downlink NAS transport",
|
||||
// .buffer = {
|
||||
// 0x00, 0x0B, 0x40, 0x21, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
// 0x05, 0xC0, 0x01, 0x10, 0xCE, 0xCC, 0x00, 0x08, 0x00, 0x03,
|
||||
// 0x40, 0x01, 0xB3, 0x00, 0x1A, 0x00, 0x0A, 0x09, 0x27, 0xAB,
|
||||
// 0x1F, 0x7C, 0xEC, 0x01, 0x02, 0x01, 0xD9
|
||||
// },
|
||||
// .buf_len = 37,
|
||||
// },
|
||||
{
|
||||
.procedure_name = "Uplink NAS transport",
|
||||
.buffer = {
|
||||
0x00, 0x0D, 0x40, 0x41, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x05, 0xC0, 0x01, 0x10, 0xCE, 0xCC, 0x00, 0x08, 0x00, 0x03,
|
||||
0x40, 0x01, 0xB3, 0x00, 0x1A, 0x00, 0x14, 0x13, 0x27, 0xD3,
|
||||
0x77, 0xED, 0x4C, 0x01, 0x02, 0x01, 0xDA, 0x28, 0x08, 0x03,
|
||||
0x69, 0x6D, 0x73, 0x03, 0x70, 0x66, 0x74, 0x00, 0x64, 0x40,
|
||||
0x08, 0x00, 0x02, 0xF8, 0x29, 0x00, 0x00, 0x20, 0x40, 0x00,
|
||||
0x43, 0x40, 0x06, 0x00, 0x02, 0xF8, 0x29, 0x00, 0x04,
|
||||
},
|
||||
.buf_len = 69,
|
||||
},
|
||||
{
|
||||
.procedure_name = "UE capability info indication",
|
||||
.buffer = {
|
||||
0x00, 0x16, 0x40, 0x37, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
|
||||
0x05, 0xC0, 0x01, 0x10, 0xCE, 0xCC, 0x00, 0x08, 0x00, 0x03,
|
||||
0x40, 0x01, 0xB3, 0x00, 0x4A, 0x40, 0x20, 0x1F, 0x00, 0xE8,
|
||||
0x01, 0x01, 0xA8, 0x13, 0x80, 0x00, 0x20, 0x83, 0x13, 0x05,
|
||||
0x0B, 0x8B, 0xFC, 0x2E, 0x2F, 0xF0, 0xB8, 0xBF, 0xAF, 0x87,
|
||||
0xFE, 0x40, 0x44, 0x04, 0x07, 0x0C, 0xA7, 0x4A, 0x80,
|
||||
},
|
||||
.buf_len = 59,
|
||||
},
|
||||
{
|
||||
.procedure_name = "Initial Context Setup Request",
|
||||
.buffer = {
|
||||
0x00, 0x09, 0x00, 0x80, 0xD4, 0x00, 0x00, 0x06, 0x00, 0x00,
|
||||
0x00, 0x05, 0xC0, 0x01, 0x10, 0xCE, 0xCC, 0x00, 0x08, 0x00,
|
||||
0x03, 0x40, 0x01, 0xB3, 0x00, 0x42, 0x00, 0x0A, 0x18, 0x08,
|
||||
0xF0, 0xD1, 0x80, 0x60, 0x02, 0xFA, 0xF0, 0x80, 0x00, 0x18,
|
||||
0x00, 0x80, 0x81, 0x00, 0x00, 0x34, 0x00, 0x7C, 0x45, 0x00,
|
||||
0x09, 0x3D, 0x0F, 0x80, 0x0A, 0x05, 0x00, 0x02, 0x03, 0x78,
|
||||
0x48, 0x86, 0x6D, 0x27, 0xC7, 0x97, 0x8E, 0xA1, 0x02, 0x07,
|
||||
0x42, 0x01, 0x49, 0x06, 0x00, 0x02, 0xF8, 0x29, 0x00, 0x04,
|
||||
0x00, 0x48, 0x52, 0x01, 0xC1, 0x01, 0x09, 0x1B, 0x03, 0x69,
|
||||
0x6D, 0x73, 0x03, 0x70, 0x66, 0x74, 0x06, 0x6D, 0x6E, 0x63,
|
||||
0x30, 0x39, 0x32, 0x06, 0x6D, 0x63, 0x63, 0x32, 0x30, 0x38,
|
||||
0x04, 0x67, 0x70, 0x72, 0x73, 0x05, 0x01, 0x0A, 0x80, 0x00,
|
||||
0x24, 0x5D, 0x01, 0x00, 0x30, 0x10, 0x23, 0x93, 0x1F, 0x93,
|
||||
0x96, 0xFE, 0xFE, 0x74, 0x4B, 0xFF, 0xFF, 0x00, 0xC5, 0x00,
|
||||
0x6C, 0x00, 0x32, 0x0B, 0x84, 0x34, 0x01, 0x08, 0x5E, 0x04,
|
||||
0xFE, 0xFE, 0xC5, 0x6C, 0x50, 0x0B, 0xF6, 0x02, 0xF8, 0x29,
|
||||
0x80, 0x00, 0x01, 0xF0, 0x00, 0x70, 0x8A, 0x53, 0x12, 0x64,
|
||||
0x01, 0x01, 0x00, 0x6B, 0x00, 0x05, 0x18, 0x00, 0x0C, 0x00,
|
||||
0x00, 0x00, 0x49, 0x00, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
},
|
||||
.buf_len = 217,
|
||||
},
|
||||
{
|
||||
.procedure_name = "Initial context setup response",
|
||||
.buffer = {
|
||||
0x20, 0x09, 0x00, 0x26, 0x00, 0x00, 0x03, 0x00, 0x00, 0x40,
|
||||
0x05, 0xC0, 0x01, 0x10, 0xCE, 0xCC, 0x00, 0x08, 0x40, 0x03,
|
||||
0x40, 0x01, 0xB3, 0x00, 0x33, 0x40, 0x0F, 0x00, 0x00, 0x32,
|
||||
0x40, 0x0A, 0x0A, 0x1F, 0x0A, 0x05, 0x02, 0x05, 0x00, 0x0F,
|
||||
0x7A, 0x03,
|
||||
},
|
||||
.buf_len = 42,
|
||||
}
|
||||
};
|
||||
|
||||
static int compare_buffer(uint8_t *buffer, uint32_t length_buffer,
|
||||
uint8_t *pattern,
|
||||
uint32_t length_pattern)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (length_buffer != length_pattern) {
|
||||
printf("Length mismatch, expecting %d bytes, got %d bytes\n", length_pattern,
|
||||
length_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < length_buffer; i++) {
|
||||
if (pattern[i] != buffer[i]) {
|
||||
printf("Mismatch fount in bytes %d\nExpecting 0x%02x, got 0x%02x\n",
|
||||
i, pattern[i], buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
asn1_xer_print = 2;
|
||||
|
||||
if (argc > 1) {
|
||||
asn_debug = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(s1ap_test) / sizeof(s1ap_test_t); i++) {
|
||||
S1AP_S1AP_PDU_t pdu;
|
||||
uint8_t *buffer;
|
||||
uint32_t length;
|
||||
memset(&pdu, 0, sizeof(pdu));
|
||||
printf("Trying to decode %s procedure with asn1c decoder\n",
|
||||
s1ap_test[i].procedure_name);
|
||||
|
||||
if (s1ap_mme_decode_pdu(&pdu, s1ap_test[i].buffer,
|
||||
s1ap_test[i].buf_len) < 0) {
|
||||
if (s1ap_eNB_decode_pdu(&pdu, s1ap_test[i].buffer,
|
||||
s1ap_test[i].buf_len) < 0) {
|
||||
printf("Failed to decode this message\n");
|
||||
} else {
|
||||
printf("Succesfully decoded %s with eNB decoder\n", s1ap_test[i].procedure_name);
|
||||
}
|
||||
} else {
|
||||
printf("Succesfully decoded %s with MME decoder\n", s1ap_test[i].procedure_name);
|
||||
}
|
||||
|
||||
printf("Trying to encode %s procedure with asn1c encoder\n",
|
||||
s1ap_test[i].procedure_name);
|
||||
|
||||
if (s1ap_eNB_encode_pdu(&pdu, &buffer, &length) < 0) {
|
||||
printf("Failed to encode this message on MME side, trying eNB side\n");
|
||||
} else {
|
||||
compare_buffer(buffer, length, s1ap_test[i].buffer, s1ap_test[i].buf_len);
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "sctp_primitives_client.h"
|
||||
|
||||
#include "s1ap_common.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "s1ap_mme.h"
|
||||
|
||||
#include "s1ap_eNB_encoder.h"
|
||||
#include "s1ap_eNB_decoder.h"
|
||||
|
||||
int recv_callback(uint32_t assocId,
|
||||
uint32_t stream,
|
||||
uint8_t *buffer,
|
||||
uint32_t length)
|
||||
{
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sctp_connected(void *args,
|
||||
uint32_t assocId,
|
||||
uint32_t instreams,
|
||||
uint32_t outstreams)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
asn_enc_rval_t retVal;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nb_eNB; i++) {
|
||||
sctp_connect_to_remote_host(ip_addr, 36412, NULL, sctp_connected, recv_callback);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
sctp_terminate();
|
||||
return(0);
|
||||
}
|
||||
@@ -1,339 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <linux/sched.h>
|
||||
#include <signal.h>
|
||||
#include <execinfo.h>
|
||||
#include <getopt.h>
|
||||
#include <syscall.h>
|
||||
|
||||
|
||||
#include "UTIL/LOG/log_extern.h"
|
||||
#include "assertions.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "sctp_eNB_task.h"
|
||||
#include "s1ap_eNB.h"
|
||||
#include "enb_config.h"
|
||||
|
||||
#include "oaisim_mme_test_s1c.h"
|
||||
|
||||
# define ENB_REGISTER_RETRY_DELAY 5
|
||||
//------------------------------------------------------------------------------
|
||||
static void get_options (int argc, char **argv);
|
||||
static uint32_t eNB_app_register(const uint32_t enb_id_start, const uint32_t enb_id_end, const Enb_properties_array_t *enb_properties);
|
||||
static void *eNB_app_task (void *args_p);
|
||||
void mme_test_s1_start_test(instance_t instance);
|
||||
//------------------------------------------------------------------------------
|
||||
static char *conf_config_file_name = NULL;
|
||||
const Enb_properties_array_t *enb_properties = NULL;
|
||||
int16_t glog_level = LOG_INFO;
|
||||
int16_t glog_verbosity = LOG_MED;
|
||||
s1c_test_t s1c_test = {
|
||||
0, // scenario_index
|
||||
0, // tx_next_message_index
|
||||
0, // rx_next_message_index
|
||||
0 // assoc_id
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void get_options (int argc, char **argv)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int c;
|
||||
|
||||
|
||||
while ((c = getopt_long (argc, argv, "K:g:G:O:",NULL,NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'O':
|
||||
conf_config_file_name = optarg;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
glog_level=atoi(optarg); // value between 1 - 9
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
glog_verbosity=atoi(optarg);// value from 0, 0x5, 0x15, 0x35, 0x75
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
AssertFatal(conf_config_file_name != NULL,"Please provide a configuration file\n");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static uint32_t eNB_app_register(const uint32_t enb_id_start, const uint32_t enb_id_end, const Enb_properties_array_t *enb_properties)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
uint32_t enb_id;
|
||||
uint32_t mme_id;
|
||||
MessageDef *msg_p;
|
||||
uint32_t register_enb_pending = 0;
|
||||
char *str = NULL;
|
||||
struct in_addr addr;
|
||||
|
||||
// 1 eNB should be max.
|
||||
// 1 eNB should be max.
|
||||
for (enb_id = enb_id_start; (enb_id < enb_id_end) ; enb_id++) {
|
||||
{
|
||||
s1ap_register_enb_req_t *s1ap_register_eNB;
|
||||
|
||||
/* note: there is an implicit relationship between the data structure and the message name */
|
||||
msg_p = itti_alloc_new_message (TASK_ENB_APP, S1AP_REGISTER_ENB_REQ);
|
||||
|
||||
s1ap_register_eNB = &S1AP_REGISTER_ENB_REQ(msg_p);
|
||||
|
||||
/* Some default/random parameters */
|
||||
s1ap_register_eNB->eNB_id = enb_properties->properties[enb_id]->eNB_id;
|
||||
s1ap_register_eNB->cell_type = enb_properties->properties[enb_id]->cell_type;
|
||||
s1ap_register_eNB->eNB_name = enb_properties->properties[enb_id]->eNB_name;
|
||||
s1ap_register_eNB->tac = enb_properties->properties[enb_id]->tac;
|
||||
s1ap_register_eNB->mcc = enb_properties->properties[enb_id]->mcc;
|
||||
s1ap_register_eNB->mnc = enb_properties->properties[enb_id]->mnc;
|
||||
s1ap_register_eNB->mnc_digit_length = enb_properties->properties[enb_id]->mnc_digit_length;
|
||||
s1ap_register_eNB->default_drx = enb_properties->properties[enb_id]->pcch_defaultPagingCycle[0];
|
||||
|
||||
s1ap_register_eNB->nb_mme = enb_properties->properties[enb_id]->nb_mme;
|
||||
AssertFatal (s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS, "Too many MME for eNB %d (%d/%d)!", enb_id, s1ap_register_eNB->nb_mme,
|
||||
S1AP_MAX_NB_MME_IP_ADDRESS);
|
||||
|
||||
for (mme_id = 0; mme_id < s1ap_register_eNB->nb_mme; mme_id++) {
|
||||
s1ap_register_eNB->mme_ip_address[mme_id].ipv4 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4;
|
||||
s1ap_register_eNB->mme_ip_address[mme_id].ipv6 = enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6;
|
||||
strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv4_address,
|
||||
enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv4_address,
|
||||
sizeof(s1ap_register_eNB->mme_ip_address[0].ipv4_address));
|
||||
strncpy (s1ap_register_eNB->mme_ip_address[mme_id].ipv6_address,
|
||||
enb_properties->properties[enb_id]->mme_ip_address[mme_id].ipv6_address,
|
||||
sizeof(s1ap_register_eNB->mme_ip_address[0].ipv6_address));
|
||||
}
|
||||
|
||||
s1ap_register_eNB->enb_ip_address.ipv6 = 0;
|
||||
s1ap_register_eNB->enb_ip_address.ipv4 = 1;
|
||||
addr.s_addr = enb_properties->properties[enb_id]->enb_ipv4_address_for_S1_MME;
|
||||
str = inet_ntoa(addr);
|
||||
strcpy(s1ap_register_eNB->enb_ip_address.ipv4_address, str);
|
||||
|
||||
itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(enb_id), msg_p);
|
||||
|
||||
register_enb_pending++;
|
||||
}
|
||||
}
|
||||
|
||||
return register_enb_pending;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
static void *eNB_app_task(void *args_p)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const Enb_properties_array_t *enb_properties_p = NULL;
|
||||
uint32_t enb_nb = 1; /* Default number of eNB is 1 */
|
||||
uint32_t enb_id_start = 0;
|
||||
uint32_t enb_id_end = enb_id_start + enb_nb;
|
||||
uint32_t register_enb_pending;
|
||||
uint32_t registered_enb;
|
||||
long enb_register_retry_timer_id;
|
||||
MessageDef *msg_p = NULL;
|
||||
const char *msg_name = NULL;
|
||||
instance_t instance;
|
||||
int result;
|
||||
|
||||
itti_mark_task_ready (TASK_ENB_APP);
|
||||
|
||||
enb_properties_p = enb_config_get();
|
||||
|
||||
AssertFatal (enb_nb <= enb_properties_p->number,
|
||||
"Number of eNB is greater than eNB defined in configuration file (%d/%d)!",
|
||||
enb_nb, enb_properties_p->number);
|
||||
|
||||
|
||||
/* Try to register each eNB */
|
||||
registered_enb = 0;
|
||||
register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);
|
||||
|
||||
do {
|
||||
// Wait for a message
|
||||
itti_receive_msg (TASK_ENB_APP, &msg_p);
|
||||
|
||||
msg_name = ITTI_MSG_NAME (msg_p);
|
||||
instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
|
||||
|
||||
switch (ITTI_MSG_ID(msg_p)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
itti_exit_task ();
|
||||
break;
|
||||
|
||||
case MESSAGE_TEST:
|
||||
LOG_I(ENB_APP, "Received %s\n", ITTI_MSG_NAME(msg_p));
|
||||
break;
|
||||
|
||||
|
||||
case S1AP_REGISTER_ENB_CNF:
|
||||
LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
|
||||
S1AP_REGISTER_ENB_CNF(msg_p).nb_mme);
|
||||
|
||||
DevAssert(register_enb_pending > 0);
|
||||
register_enb_pending--;
|
||||
|
||||
/* Check if at least eNB is registered with one MME */
|
||||
if (S1AP_REGISTER_ENB_CNF(msg_p).nb_mme > 0) {
|
||||
registered_enb++;
|
||||
}
|
||||
|
||||
/* Check if all register eNB requests have been processed */
|
||||
if (register_enb_pending == 0) {
|
||||
if (registered_enb == enb_nb) {
|
||||
mme_test_s1_start_test(instance);
|
||||
|
||||
|
||||
} else {
|
||||
uint32_t not_associated = enb_nb - registered_enb;
|
||||
|
||||
LOG_W(ENB_APP, " %d eNB %s not associated with a MME, retrying registration in %d seconds ...\n",
|
||||
not_associated, not_associated > 1 ? "are" : "is", 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 (enb_id_start, enb_id_end, enb_properties_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case S1AP_DEREGISTERED_ENB_IND:
|
||||
LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
|
||||
S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);
|
||||
|
||||
/* TODO handle recovering of registration */
|
||||
break;
|
||||
|
||||
case TIMER_HAS_EXPIRED:
|
||||
LOG_I(ENB_APP, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
|
||||
|
||||
if (TIMER_HAS_EXPIRED (msg_p).timer_id == enb_register_retry_timer_id) {
|
||||
/* Restart the registration process */
|
||||
registered_enb = 0;
|
||||
register_enb_pending = eNB_app_register (enb_id_start, enb_id_end, enb_properties_p);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG_E(ENB_APP, "Received unexpected message %s\n", msg_name);
|
||||
break;
|
||||
}
|
||||
|
||||
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
|
||||
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
|
||||
} while (1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void mme_test_s1_start_test(instance_t instance)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
s1ap_eNB_itti_send_sctp_data_req(instance,
|
||||
s1c_test.assoc_id,
|
||||
s1ap_scenarios[s1c_test.scenario_index][s1c_test.tx_next_message_index].buffer,
|
||||
s1ap_scenarios[s1c_test.scenario_index][s1c_test.tx_next_message_index].buf_len,
|
||||
s1ap_scenarios[s1c_test.scenario_index][s1c_test.tx_next_message_index].sctp_stream_id);
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void mme_test_s1_notify_sctp_data_ind(uint32_t assoc_id, int32_t stream, const uint8_t * const data, const uint32_t data_length)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int main( int argc, char **argv )
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
// initialize the log (see log.h for details)
|
||||
logInit();
|
||||
|
||||
get_options (argc, argv); //Command-line options
|
||||
set_glog(glog_level, glog_verbosity);
|
||||
log_set_instance_type (LOG_INSTANCE_ENB);
|
||||
|
||||
/* Read eNB configuration file */
|
||||
enb_properties = enb_config_init(conf_config_file_name);
|
||||
|
||||
itti_init(TASK_MAX, tasks_info);
|
||||
|
||||
itti_wait_ready(1);
|
||||
|
||||
if (itti_create_task (TASK_SCTP, sctp_eNB_task, NULL) < 0) {
|
||||
LOG_E(SCTP, "Create task for SCTP failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (itti_create_task (TASK_S1AP, s1ap_eNB_task, NULL) < 0) {
|
||||
LOG_E(S1AP, "Create task for S1AP failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (itti_create_task (TASK_ENB_APP, eNB_app_task, NULL) < 0) {
|
||||
LOG_E(S1AP, "Create task for S1AP failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
itti_wait_ready(0);
|
||||
|
||||
|
||||
|
||||
sleep(30);
|
||||
|
||||
logClean();
|
||||
return 0;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
typedef struct s1c_test_s {
|
||||
int scenario_index;
|
||||
int tx_next_message_index;
|
||||
int rx_next_message_index;
|
||||
int32_t assoc_id;
|
||||
}s1c_test_t;
|
||||
|
||||
void mme_test_s1_start_test(instance_t instance);
|
||||
void mme_test_s1_notify_sctp_data_ind(uint32_t assoc_id, int32_t stream, const uint8_t * const data, const uint32_t data_length);
|
||||
@@ -1,291 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <linux/sched.h>
|
||||
#include <signal.h>
|
||||
#include <execinfo.h>
|
||||
#include <getopt.h>
|
||||
#include <syscall.h>
|
||||
|
||||
|
||||
#include "tree.h"
|
||||
#include "queue.h"
|
||||
#include "intertask_interface.h"
|
||||
#include "s1ap_eNB_default_values.h"
|
||||
#include "s1ap_common.h"
|
||||
#include "s1ap_eNB_defs.h"
|
||||
#include "s1ap_eNB_management_procedures.h"
|
||||
#include "assertions.h"
|
||||
|
||||
#include "platform_types.h"
|
||||
#include "oaisim_mme_test_s1c.h"
|
||||
|
||||
|
||||
void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind)
|
||||
{
|
||||
int result;
|
||||
DevAssert(sctp_data_ind != NULL);
|
||||
mme_test_s1_notify_sctp_data_ind(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);
|
||||
}
|
||||
|
||||
|
||||
void s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream)
|
||||
{
|
||||
MessageDef *message_p;
|
||||
sctp_data_req_t *sctp_data_req;
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, SCTP_DATA_REQ);
|
||||
sctp_data_req = &message_p->ittiMsg.sctp_data_req;
|
||||
sctp_data_req->assoc_id = assoc_id;
|
||||
sctp_data_req->buffer = buffer;
|
||||
sctp_data_req->buffer_length = buffer_length;
|
||||
sctp_data_req->stream = stream;
|
||||
itti_send_msg_to_task(TASK_SCTP, instance, message_p);
|
||||
}
|
||||
|
||||
void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown)
|
||||
{
|
||||
if (sctp_shutdown) {
|
||||
/* A previously connected MME has been shutdown */
|
||||
|
||||
/* TODO check if it was used by some eNB and send a message to inform these eNB if there is no more associated MME */
|
||||
if (mme_desc_p->state == S1AP_ENB_STATE_CONNECTED) {
|
||||
mme_desc_p->state = S1AP_ENB_STATE_DISCONNECTED;
|
||||
|
||||
if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb > 0) {
|
||||
/* Decrease associated MME number */
|
||||
mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb --;
|
||||
}
|
||||
|
||||
/* If there are no more associated MME, inform eNB app */
|
||||
if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb == 0) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DEREGISTERED_ENB_IND);
|
||||
S1AP_DEREGISTERED_ENB_IND(message_p).nb_mme = 0;
|
||||
itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Check that at least one setup message is pending */
|
||||
DevCheck(mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0, mme_desc_p->s1ap_eNB_instance->instance,
|
||||
mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb, 0);
|
||||
|
||||
if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0) {
|
||||
/* Decrease pending messages number */
|
||||
mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --;
|
||||
}
|
||||
|
||||
/* If there are no more pending messages, inform eNB app */
|
||||
if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) {
|
||||
MessageDef *message_p;
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF);
|
||||
S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb;
|
||||
itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp)
|
||||
{
|
||||
s1ap_eNB_instance_t *instance_p;
|
||||
s1ap_eNB_mme_data_t *s1ap_mme_data_p;
|
||||
DevAssert(sctp_new_association_resp != NULL);
|
||||
instance_p = s1ap_eNB_get_instance(instance);
|
||||
DevAssert(instance_p != NULL);
|
||||
s1ap_mme_data_p = s1ap_eNB_get_MME(instance_p, -1,
|
||||
sctp_new_association_resp->ulp_cnx_id);
|
||||
DevAssert(s1ap_mme_data_p != NULL);
|
||||
|
||||
if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) {
|
||||
S1AP_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);
|
||||
s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Update parameters */
|
||||
s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id;
|
||||
s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams;
|
||||
s1ap_mme_data_p->out_streams = sctp_new_association_resp->out_streams;
|
||||
/* Prepare new S1 Setup Request */
|
||||
mme_test_s1_start_test(instance_p, s1ap_mme_data_p);
|
||||
}
|
||||
|
||||
void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
net_ip_address_t *mme_ip_address,
|
||||
net_ip_address_t *local_ip_addr)
|
||||
{
|
||||
MessageDef *message_p = NULL;
|
||||
sctp_new_association_req_t *sctp_new_association_req_p = NULL;
|
||||
s1ap_eNB_mme_data_t *s1ap_mme_data_p = NULL;
|
||||
DevAssert(instance_p != NULL);
|
||||
DevAssert(mme_ip_address != NULL);
|
||||
message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ);
|
||||
sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req;
|
||||
sctp_new_association_req_p->port = S1AP_PORT_NUMBER;
|
||||
sctp_new_association_req_p->ppid = S1AP_SCTP_PPID;
|
||||
memcpy(&sctp_new_association_req_p->remote_address,
|
||||
mme_ip_address,
|
||||
sizeof(*mme_ip_address));
|
||||
memcpy(&sctp_new_association_req_p->local_address,
|
||||
local_ip_addr,
|
||||
sizeof(*local_ip_addr));
|
||||
/* Create new MME descriptor */
|
||||
s1ap_mme_data_p = calloc(1, sizeof(*s1ap_mme_data_p));
|
||||
DevAssert(s1ap_mme_data_p != NULL);
|
||||
s1ap_mme_data_p->cnx_id = s1ap_eNB_fetch_add_global_cnx_id();
|
||||
sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
|
||||
s1ap_mme_data_p->assoc_id = -1;
|
||||
s1ap_mme_data_p->s1ap_eNB_instance = instance_p;
|
||||
STAILQ_INIT(&s1ap_mme_data_p->served_gummei);
|
||||
/* Insert the new descriptor in list of known MME
|
||||
* but not yet associated.
|
||||
*/
|
||||
RB_INSERT(s1ap_mme_map, &instance_p->s1ap_mme_head, s1ap_mme_data_p);
|
||||
s1ap_mme_data_p->state = S1AP_ENB_STATE_WAITING;
|
||||
instance_p->s1ap_mme_nb ++;
|
||||
instance_p->s1ap_mme_pending_nb ++;
|
||||
itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB)
|
||||
{
|
||||
s1ap_eNB_instance_t *new_instance;
|
||||
uint8_t index;
|
||||
DevAssert(s1ap_register_eNB != NULL);
|
||||
/* Look if the provided instance already exists */
|
||||
new_instance = s1ap_eNB_get_instance(instance);
|
||||
|
||||
if (new_instance != NULL) {
|
||||
/* Checks if it is a retry on the same eNB */
|
||||
DevCheck(new_instance->eNB_id == s1ap_register_eNB->eNB_id, new_instance->eNB_id, s1ap_register_eNB->eNB_id, 0);
|
||||
DevCheck(new_instance->cell_type == s1ap_register_eNB->cell_type, new_instance->cell_type, s1ap_register_eNB->cell_type, 0);
|
||||
DevCheck(new_instance->tac == s1ap_register_eNB->tac, new_instance->tac, s1ap_register_eNB->tac, 0);
|
||||
DevCheck(new_instance->mcc == s1ap_register_eNB->mcc, new_instance->mcc, s1ap_register_eNB->mcc, 0);
|
||||
DevCheck(new_instance->mnc == s1ap_register_eNB->mnc, new_instance->mnc, s1ap_register_eNB->mnc, 0);
|
||||
DevCheck(new_instance->mnc_digit_length == s1ap_register_eNB->mnc_digit_length, new_instance->mnc_digit_length, s1ap_register_eNB->mnc_digit_length, 0);
|
||||
DevCheck(new_instance->default_drx == s1ap_register_eNB->default_drx, new_instance->default_drx, s1ap_register_eNB->default_drx, 0);
|
||||
} else {
|
||||
new_instance = calloc(1, sizeof(s1ap_eNB_instance_t));
|
||||
DevAssert(new_instance != NULL);
|
||||
RB_INIT(&new_instance->s1ap_ue_head);
|
||||
RB_INIT(&new_instance->s1ap_mme_head);
|
||||
/* Copy usefull parameters */
|
||||
new_instance->instance = instance;
|
||||
new_instance->eNB_name = s1ap_register_eNB->eNB_name;
|
||||
new_instance->eNB_id = s1ap_register_eNB->eNB_id;
|
||||
new_instance->cell_type = s1ap_register_eNB->cell_type;
|
||||
new_instance->tac = s1ap_register_eNB->tac;
|
||||
new_instance->mcc = s1ap_register_eNB->mcc;
|
||||
new_instance->mnc = s1ap_register_eNB->mnc;
|
||||
new_instance->mnc_digit_length = s1ap_register_eNB->mnc_digit_length;
|
||||
new_instance->default_drx = s1ap_register_eNB->default_drx;
|
||||
/* Add the new instance to the list of eNB (meaningfull in virtual mode) */
|
||||
s1ap_eNB_insert_new_instance(new_instance);
|
||||
S1AP_DEBUG("Registered new eNB[%d] and %s eNB id %u\n",
|
||||
instance,
|
||||
s1ap_register_eNB->cell_type == CELL_MACRO_ENB ? "macro" : "home",
|
||||
s1ap_register_eNB->eNB_id);
|
||||
}
|
||||
|
||||
DevCheck(s1ap_register_eNB->nb_mme <= S1AP_MAX_NB_MME_IP_ADDRESS,
|
||||
S1AP_MAX_NB_MME_IP_ADDRESS, s1ap_register_eNB->nb_mme, 0);
|
||||
|
||||
/* Trying to connect to provided list of MME ip address */
|
||||
for (index = 0; index < s1ap_register_eNB->nb_mme; index++) {
|
||||
s1ap_eNB_register_mme(new_instance, &s1ap_register_eNB->mme_ip_address[index],
|
||||
&s1ap_register_eNB->enb_ip_address);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void *s1ap_eNB_task(void *arg)
|
||||
{
|
||||
MessageDef *received_msg = NULL;
|
||||
int result;
|
||||
S1AP_DEBUG("Starting S1AP layer\n");
|
||||
s1ap_eNB_prepare_internal_data();
|
||||
itti_mark_task_ready(TASK_S1AP);
|
||||
|
||||
while (1) {
|
||||
itti_receive_msg(TASK_S1AP, &received_msg);
|
||||
|
||||
switch (ITTI_MSG_ID(received_msg)) {
|
||||
case TERMINATE_MESSAGE:
|
||||
itti_exit_task();
|
||||
break;
|
||||
|
||||
case S1AP_REGISTER_ENB_REQ: {
|
||||
/* Register a new eNB.
|
||||
* in Virtual mode eNBs will be distinguished using the mod_id/
|
||||
* Each eNB has to send an S1AP_REGISTER_ENB message with its
|
||||
* own parameters.
|
||||
*/
|
||||
s1ap_eNB_handle_register_eNB(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&S1AP_REGISTER_ENB_REQ(received_msg));
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_NEW_ASSOCIATION_RESP: {
|
||||
s1ap_eNB_handle_sctp_association_resp(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
|
||||
&received_msg->ittiMsg.sctp_new_association_resp);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCTP_DATA_IND: {
|
||||
s1ap_eNB_handle_sctp_data_ind(&received_msg->ittiMsg.sctp_data_ind);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
S1AP_ERROR("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;
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef __TEST_OAISIM_MME_TEST_S1C_S1AP__H__
|
||||
#define __TEST_OAISIM_MME_TEST_S1C_S1AP__H__
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <linux/sched.h>
|
||||
#include <signal.h>
|
||||
#include <execinfo.h>
|
||||
#include <getopt.h>
|
||||
#include <syscall.h>
|
||||
|
||||
void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind);
|
||||
|
||||
void s1ap_eNB_itti_send_sctp_data_req(instance_t instance, int32_t assoc_id, uint8_t *buffer,
|
||||
uint32_t buffer_length, uint16_t stream);
|
||||
|
||||
void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown);
|
||||
|
||||
void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_association_resp_t *sctp_new_association_resp);
|
||||
|
||||
void s1ap_eNB_register_mme(s1ap_eNB_instance_t *instance_p,
|
||||
net_ip_address_t *mme_ip_address,
|
||||
net_ip_address_t *local_ip_addr,
|
||||
uint16_t in_streams,
|
||||
uint16_t out_streams);
|
||||
void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *s1ap_register_eNB);
|
||||
void *s1ap_eNB_task(void *arg);
|
||||
|
||||
#endif
|
||||
@@ -1,279 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "oaisim_mme_test_s1c_scenario.h"
|
||||
|
||||
int scenario_index = 0;
|
||||
int scenario_message_index = 0;
|
||||
int debug = 0;
|
||||
int error_count = 0;
|
||||
int break_on_error = 0;
|
||||
|
||||
|
||||
extern s1ap_message_test_t s1ap_scenario1[];
|
||||
|
||||
s1ap_message_test_t s1ap_scenarios[][] = {s1ap_scenario1};
|
||||
|
||||
/* -1 means invalid */
|
||||
static const signed char hex_digits[0x100] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
fail (const char *format, ...)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
char str[1024];
|
||||
va_list arg_ptr;
|
||||
|
||||
va_start (arg_ptr, format);
|
||||
vsnprintf ( str, sizeof(str), format, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
fputs(str, stderr);
|
||||
error_count++;
|
||||
|
||||
if (break_on_error)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
success (const char *format, ...)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
char str[1024];
|
||||
va_list arg_ptr;
|
||||
|
||||
va_start (arg_ptr, format);
|
||||
vsnprintf ( str, sizeof(str), format, arg_ptr);
|
||||
va_end (arg_ptr);
|
||||
fputs(str, stderr);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
escapeprint (const char *str, size_t len)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
size_t i;
|
||||
|
||||
printf (" (length %d bytes):\n\t", (int) len);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (((str[i] & 0xFF) >= 'A' && (str[i] & 0xFF) <= 'Z') ||
|
||||
((str[i] & 0xFF) >= 'a' && (str[i] & 0xFF) <= 'z') ||
|
||||
((str[i] & 0xFF) >= '0' && (str[i] & 0xFF) <= '9')
|
||||
|| (str[i] & 0xFF) == ' ' || (str[i] & 0xFF) == '.')
|
||||
printf ("%c", (str[i] & 0xFF));
|
||||
else
|
||||
printf ("\\x%02X", (str[i] & 0xFF));
|
||||
|
||||
if ((i + 1) % 16 == 0 && (i + 1) < len)
|
||||
printf ("'\n\t'");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
hexprint (const void *_str, size_t len)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
size_t i;
|
||||
const char* str = _str;
|
||||
|
||||
printf ("\t;; ");
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
printf ("%02x ", (str[i] & 0xFF));
|
||||
|
||||
if ((i + 1) % 8 == 0)
|
||||
printf (" ");
|
||||
|
||||
if ((i + 1) % 16 == 0 && i + 1 < len)
|
||||
printf ("\n\t;; ");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
void
|
||||
binprint (const void *_str, size_t len)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
size_t i;
|
||||
const char* str = _str;
|
||||
|
||||
printf ("\t;; ");
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
printf ("%d%d%d%d%d%d%d%d ",
|
||||
(str[i] & 0xFF) & 0x80 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x40 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x20 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x10 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x08 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x04 ? 1 : 0,
|
||||
(str[i] & 0xFF) & 0x02 ? 1 : 0, (str[i] & 0xFF) & 0x01 ? 1 : 0);
|
||||
|
||||
if ((i + 1) % 3 == 0)
|
||||
printf (" ");
|
||||
|
||||
if ((i + 1) % 6 == 0 && i + 1 < len)
|
||||
printf ("\n\t;; ");
|
||||
}
|
||||
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
compare_buffer(const uint8_t *buffer, const uint32_t length_buffer,
|
||||
const uint8_t *pattern, const uint32_t length_pattern)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
int i;
|
||||
|
||||
if (length_buffer != length_pattern) {
|
||||
printf("Length mismatch, expecting %d bytes, got %d bytes\n", length_pattern,
|
||||
length_buffer);
|
||||
hexprint(buffer, length_buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < length_buffer; i++) {
|
||||
if (pattern[i] != buffer[i]) {
|
||||
printf("Expecting:\n");
|
||||
hexprint(pattern, length_pattern);
|
||||
printf("Received:\n");
|
||||
hexprint(buffer, length_buffer);
|
||||
printf("Mismatch fount in byte %d\nExpecting 0x%02x, got 0x%02x\n",
|
||||
i, pattern[i], buffer[i]);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
unsigned
|
||||
decode_hex_length(const char *h)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned char *hex = (const unsigned char *) h;
|
||||
unsigned count;
|
||||
unsigned i;
|
||||
|
||||
for (count = i = 0; hex[i]; i++) {
|
||||
if (isspace(hex[i]))
|
||||
continue;
|
||||
|
||||
if (hex_digits[hex[i]] < 0)
|
||||
abort();
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count % 2)
|
||||
abort();
|
||||
|
||||
return count / 2;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
decode_hex(uint8_t *dst, const char *h)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
const unsigned char *hex = (const unsigned char *) h;
|
||||
unsigned i = 0;
|
||||
|
||||
for (;;) {
|
||||
int high, low;
|
||||
|
||||
while (*hex && isspace(*hex))
|
||||
hex++;
|
||||
|
||||
if (!*hex)
|
||||
return 1;
|
||||
|
||||
high = hex_digits[*hex++];
|
||||
|
||||
if (high < 0)
|
||||
return 0;
|
||||
|
||||
while (*hex && isspace(*hex))
|
||||
hex++;
|
||||
|
||||
if (!*hex)
|
||||
return 0;
|
||||
|
||||
low = hex_digits[*hex++];
|
||||
|
||||
if (low < 0)
|
||||
return 0;
|
||||
|
||||
dst[i++] = (high << 4) | low;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t *
|
||||
decode_hex_dup(const char *hex)
|
||||
//------------------------------------------------------------------------------
|
||||
{
|
||||
uint8_t *p;
|
||||
unsigned length = decode_hex_length(hex);
|
||||
|
||||
p = malloc(length * sizeof(uint8_t));
|
||||
|
||||
if (decode_hex(p, hex))
|
||||
return p;
|
||||
else {
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef __TEST_OAISIM_MME_TEST_S1C_SCENARIO__H__
|
||||
#define __TEST_OAISIM_MME_TEST_S1C_SCENARIO__H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MME_TEST_S1_MAX_BUF_LENGTH (1024)
|
||||
#define MME_TEST_S1_MAX_BYTES_TEST (32)
|
||||
|
||||
typedef enum entity_s{
|
||||
MME,
|
||||
ENB
|
||||
} entity_t;
|
||||
|
||||
typedef struct s1ap_message_test_s{
|
||||
char *procedure_name;
|
||||
uint8_t buffer[MME_TEST_S1_MAX_BUF_LENGTH];
|
||||
uint16_t dont_check[MME_TEST_S1_MAX_BYTES_TEST]; // bytes index test that can be omitted
|
||||
uint32_t buf_len;
|
||||
entity_t originating;
|
||||
uint16_t sctp_stream_id;
|
||||
uint32_t assoc_id;
|
||||
} s1ap_message_test_t;
|
||||
|
||||
void fail (const char *format, ...);
|
||||
void success (const char *format, ...);
|
||||
void escapeprint (const char *str, size_t len);
|
||||
void hexprint (const void *_str, size_t len);
|
||||
void binprint (const void *_str, size_t len);
|
||||
int compare_buffer(const uint8_t *buffer, const uint32_t length_buffer, const uint8_t *pattern, const uint32_t length_pattern);
|
||||
unsigned decode_hex_length(const char *h);
|
||||
int decode_hex(uint8_t *dst, const char *h);
|
||||
uint8_t *decode_hex_dup(const char *hex);
|
||||
|
||||
#endif
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "oaisim_mme_test_s1c_scenario.h"
|
||||
|
||||
|
||||
// Description succesfull attach of UE, release UE.
|
||||
|
||||
s1ap_message_test_t s1ap_scenario1[] = {
|
||||
{
|
||||
.procedure_name = "id-initialUEMessage",
|
||||
.buffer = {
|
||||
0x00, 0x0C,
|
||||
0x00, 0x5C, 0x00, 0x00, 0x05, 0x00, 0x08, 0x00, 0x04, 0x80, 0x06, 0x69, 0x2D, 0x00, 0x1A, 0x00,
|
||||
0x32, 0x31, 0x07, 0x41, 0x71, 0x08, 0x29, 0x80, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0xE0,
|
||||
0xE0, 0x00, 0x20, 0x02, 0x01, 0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
|
||||
0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00,
|
||||
0x00, 0x0A, 0x00, 0x00, 0x43, 0x00, 0x06, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x01, 0x00, 0x64, 0x40,
|
||||
0x08, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x86, 0x40, 0x01, 0x30
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 96,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-downlinkNASTransport, Authentication request",
|
||||
.buffer = {
|
||||
0x00, 0x0B,
|
||||
0x00, 0x3D, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xC0, 0x80, 0x00, 0x15, 0x20, 0x00, 0x08,
|
||||
0x00, 0x04, 0x80, 0x06, 0x69, 0x2D, 0x00, 0x1A, 0x00, 0x25, 0x24, 0x07, 0x52, 0x00, 0xD3, 0xB5,
|
||||
0xF0, 0x89, 0x68, 0x02, 0x66, 0x5A, 0x08, 0xE6, 0x51, 0xC7, 0x29, 0x6B, 0x4D, 0xA0, 0x10, 0xDD,
|
||||
0x04, 0x53, 0xC8, 0x3F, 0x94, 0x80, 0x00, 0x03, 0xAF, 0x2F, 0x49, 0xF3, 0xC8, 0x38, 0x90, 0x00,
|
||||
0x00, 0x00
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 65,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = MME,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-uplinkNASTransport, 0xAuthentication response",
|
||||
.buffer = {
|
||||
0x00, 0x0d,
|
||||
0x40, 0x3a, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x80, 0x00, 0x15, 0x20, 0x00, 0x08,
|
||||
0x00, 0x04, 0x80, 0x06, 0x69, 0x2d, 0x00, 0x1a, 0x00, 0x0C, 0x0b, 0x07, 0x53, 0x08, 0x11, 0x82,
|
||||
0x98, 0x98, 0x3b, 0xca, 0xF2, 0x97, 0x00, 0x64, 0x40, 0x08, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x00,
|
||||
0xe0, 0x00, 0x00, 0x43, 0x40, 0x06, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x01, 0x00, 0x00
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 62,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-downlinkNASTransport, Security mode command",
|
||||
.buffer = {
|
||||
0x00, 0x0b,
|
||||
0x00, 0x26, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x80, 0x00, 0x15, 0x20, 0x00, 0x08,
|
||||
0x00, 0x04, 0x80, 0x06, 0x69, 0x2d, 0x00, 0x1a, 0x00, 0x0e, 0x0d, 0x37, 0xFC, 0xc1, 0xda, 0xd9,
|
||||
0x00, 0x07, 0x5d, 0x02, 0x00, 0x02, 0xe0, 0xe0, 0x00, 0x00
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 42,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = MME,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-uplinkNASTransport, Security mode complete",
|
||||
.buffer = {
|
||||
0x00, 0x0d,
|
||||
0x40, 0x37, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x80, 0x00, 0x15, 0x20, 0x00, 0x08,
|
||||
0x00, 0x04, 0x80, 0x06, 0x69, 0x2d, 0x00, 0x1a, 0x00, 0x09, 0x08, 0x47, 0x1d, 0xd0, 0xbb, 0xad,
|
||||
0x00, 0x07, 0x5e, 0x00, 0x64, 0x40, 0x08, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x00, 0xe0, 0x00, 0x00,
|
||||
0x43, 0x40, 0x06, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x01, 0x00
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 59,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-InitialContextSetup, InitialContextSetupRequest , Attach accept, Activate default EPS bearer context request",
|
||||
.buffer = {
|
||||
0x00, 0x09,
|
||||
0x00, 0x80, 0xba, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x80, 0x00, 0x15, 0x20, 0x00,
|
||||
0x08, 0x00, 0x04, 0x80, 0x06, 0x69, 0x2d, 0x00, 0x42, 0x00, 0x0a, 0x18, 0x05, 0xF5, 0xe1, 0x00,
|
||||
0x60, 0x02, 0xFa, 0xF0, 0x80, 0x00, 0x18, 0x00, 0x67, 0x00, 0x00, 0x34, 0x00, 0x62, 0x45, 0x00,
|
||||
0x09, 0x04, 0x0f, 0x80, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x53, 0x27, 0x8b, 0xe6,
|
||||
0x60, 0xb5, 0x01, 0x07, 0x42, 0x01, 0x4a, 0x06, 0x20, 0x02, 0xF8, 0x39, 0x00, 0x01, 0x00, 0x31,
|
||||
0x52, 0x01, 0xc1, 0x01, 0x09, 0x09, 0x03, 0x6f, 0x61, 0x69, 0x04, 0x69, 0x70, 0x76, 0x34, 0x05,
|
||||
0x01, 0xc0, 0xbb, 0x00, 0x02, 0x5e, 0x04, 0xFe, 0xFe, 0xde, 0x9e, 0x27, 0x14, 0x80, 0x80, 0x21,
|
||||
0x10, 0x03, 0x00, 0x00, 0x10, 0x81, 0x06, 0xc0, 0xa8, 0x0C, 0x64, 0x83, 0x06, 0xc0, 0xa8, 0x6a,
|
||||
0x0C, 0x50, 0x0b, 0xF6, 0x02, 0xF8, 0x39, 0x80, 0x00, 0x01, 0x78, 0x00, 0x0C, 0x20, 0x17, 0x2C,
|
||||
0x00, 0x6b, 0x00, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x49, 0x00, 0x20, 0xFa, 0x59, 0x15,
|
||||
0x4e, 0x32, 0x95, 0x04, 0x2d, 0x35, 0xa4, 0x47, 0xc3, 0x80, 0xab, 0x63, 0xd8, 0xe6, 0x91, 0x83,
|
||||
0x6C, 0x9a, 0xF0, 0xed, 0x85, 0x38, 0xa8, 0x27, 0x41, 0x6b, 0x2b, 0x64, 0x86, 0x00
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 191,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = MME,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-UECapabilityInfoIndication",
|
||||
.buffer = {
|
||||
0x00, 0x16,
|
||||
0x40, 0x2C, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x80, 0x00, 0x15, 0x20, 0x00, 0x08,
|
||||
0x00, 0x04, 0x80, 0x06, 0x69, 0x2d, 0x00, 0x4a, 0x40, 0x14, 0x13, 0x81, 0x20, 0x00, 0x03, 0x00,
|
||||
0x10, 0x60, 0xe0, 0xc1, 0xF8, 0x3f, 0x07, 0xe0 ,0xfd, 0x78, 0x37, 0x62, 0x00, 0x00
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 48,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-InitialContextSetup, InitialContextSetupResponse ",
|
||||
.buffer = {
|
||||
0x20, 0x09,
|
||||
0x00, 0x27, 0x00, 0x00, 0x03, 0x00, 0x00, 0x40, 0x05, 0xc0, 0x80, 0x00, 0x15, 0x20, 0x00, 0x08,
|
||||
0x40, 0x04, 0x80, 0x06, 0x69, 0x2d, 0x00, 0x33, 0x40, 0x0f, 0x00, 0x00, 0x32, 0x40, 0x0a, 0x0a,
|
||||
0x1f, 0x7f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 64,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
},
|
||||
{
|
||||
.procedure_name = "id-uplinkNASTransport, Attach complete, Activate default EPS bearer context accept",
|
||||
.buffer = {
|
||||
|
||||
0x00, 0x0d,
|
||||
0x05, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x80, 0x00, 0x15, 0x20, 0x00, 0x08, 0x00, 0x04, 0x80, 0x06,
|
||||
0x69, 0x2d, 0x00, 0x1a, 0x00, 0x0e, 0x0d, 0x27, 0xc7, 0x8f, 0x5a, 0xd2, 0x01, 0x07, 0x43, 0x00,
|
||||
0x03, 0x52, 0x00, 0xc2, 0x00, 0x64, 0x40, 0x08, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x00, 0xe0, 0x00,
|
||||
0x00, 0x43, 0x40, 0x06, 0x00, 0x02, 0xF8, 0x39, 0x00, 0x01
|
||||
},
|
||||
.dont_check = {
|
||||
-1
|
||||
},
|
||||
.buf_len = 64,
|
||||
.sctp_stream_id = 1,
|
||||
.originating = ENB,
|
||||
}
|
||||
};
|
||||
@@ -1,944 +0,0 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <linux/sched.h>
|
||||
#include <signal.h>
|
||||
#include <execinfo.h>
|
||||
#include <getopt.h>
|
||||
#include <syscall.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#include "assertions.h"
|
||||
#include "PHY/types.h"
|
||||
|
||||
#include "PHY/defs.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#define GET_TIME_INIT(num) struct timeval _timers[num]
|
||||
#define GET_TIME_VAL(num) gettimeofday(&_timers[num], NULL)
|
||||
#define TIME_VAL_TO_MS(num) (((double)_timers[num].tv_sec*1000.0) + ((double)_timers[num].tv_usec/1000.0))
|
||||
|
||||
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
#include "../../ARCH/COMMON/common_lib.h"
|
||||
|
||||
#include "PHY/extern.h"
|
||||
#include "SCHED/extern.h"
|
||||
#include "LAYER2/MAC/extern.h"
|
||||
#include "LAYER2/MAC/proto.h"
|
||||
|
||||
#define SYRIQ_CHANNEL_TESTER 0
|
||||
#define SYRIQ_CHANNEL_TESTER2 0
|
||||
#define SYRIQ_CHANNEL_DATA1 1
|
||||
|
||||
volatile int oai_exit = 0;
|
||||
|
||||
openair0_config_t openair0_cfg[MAX_CARDS];
|
||||
|
||||
#if 0
|
||||
#define NB_ANTENNAS_RX 4
|
||||
|
||||
#define DevAssert(cOND) _Assert_(cOND, _Assert_Exit_, "")
|
||||
#define malloc16(x) memalign(16,x)
|
||||
|
||||
#ifdef 0
|
||||
static inline void* malloc16_clear( size_t size )
|
||||
{
|
||||
#ifdef __AVX2__
|
||||
void* ptr = memalign(32, size);
|
||||
#else
|
||||
void* ptr = memalign(16, size);
|
||||
#endif
|
||||
if(ptr)
|
||||
memset( ptr, 0, size );
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct latency_stat {
|
||||
uint64_t counter;
|
||||
|
||||
uint64_t stat250;
|
||||
uint64_t stat500;
|
||||
uint64_t stat600;
|
||||
uint64_t stat700;
|
||||
uint64_t stat800;
|
||||
|
||||
uint64_t stat1300;
|
||||
uint64_t stat1500;
|
||||
uint64_t stat2000;
|
||||
uint64_t stat2500;
|
||||
uint64_t stat3000;
|
||||
|
||||
uint64_t stat880;
|
||||
uint64_t stat960;
|
||||
uint64_t stat1040;
|
||||
uint64_t stat1120;
|
||||
uint64_t stat1200;
|
||||
} latency_stat_t;
|
||||
|
||||
|
||||
typedef struct timing_stats {
|
||||
char *name;
|
||||
double min;
|
||||
double max;
|
||||
double total;
|
||||
unsigned int count;
|
||||
} timing_stats_t;
|
||||
|
||||
|
||||
//static struct timespec get_timespec_diff(
|
||||
// struct timespec *start,
|
||||
// struct timespec *stop )
|
||||
//{
|
||||
// struct timespec result;
|
||||
//
|
||||
// if ( ( stop->tv_nsec - start->tv_nsec ) < 0 ) {
|
||||
// result.tv_sec = stop->tv_sec - start->tv_sec - 1;
|
||||
// result.tv_nsec = stop->tv_nsec - start->tv_nsec + 1000000000;
|
||||
// }
|
||||
// else {
|
||||
// result.tv_sec = stop->tv_sec - start->tv_sec;
|
||||
// result.tv_nsec = stop->tv_nsec - start->tv_nsec;
|
||||
// }
|
||||
//
|
||||
// return result;
|
||||
//}
|
||||
|
||||
|
||||
//static void measure_time (
|
||||
// openair0_device *rf_device,
|
||||
// struct timespec *start,
|
||||
// struct timespec *stop,
|
||||
// timing_stats_t *stats,
|
||||
// boolean_t START,
|
||||
// uint8_t PRINT_INTERVAL )
|
||||
//{
|
||||
// if ( START ) {
|
||||
// clock_gettime( CLOCK_MONOTONIC, start );
|
||||
// }
|
||||
// else {
|
||||
// clock_gettime( CLOCK_MONOTONIC, stop );
|
||||
//
|
||||
// struct timespec diff;
|
||||
// double current = 0;
|
||||
//// boolean_t show_stats = false;
|
||||
//
|
||||
// diff = get_timespec_diff( start, stop );
|
||||
// current = (double)diff.tv_sec * 1000000 + (double)diff.tv_nsec / 1000;
|
||||
//
|
||||
// if ( current > stats->max ) {
|
||||
// stats->max = current;
|
||||
//// show_stats = true;
|
||||
// }
|
||||
// if ( stats->min == 0 || current < stats->min ) {
|
||||
// stats->min = current;
|
||||
//// show_stats = true;
|
||||
// }
|
||||
// stats->total += current;
|
||||
//
|
||||
//// if ( show_stats ) {
|
||||
//// rf_device.trx_get_stats_func( &rf_device );
|
||||
//// }
|
||||
//
|
||||
//// if ( stats->count % PRINT_INTERVAL == 0 ) {
|
||||
//// double avg = stats->total / ( stats->count + 1 );
|
||||
//// printf( "[%s][%d] Current : %.2lf µs, Min : %.2lf µs, Max : %.2lf µs, Avg : %.2lf µs\n",
|
||||
//// stats->count, stats->name, current, stats->min, stats->max, avg );
|
||||
//// }
|
||||
//
|
||||
// stats->count++;
|
||||
// }
|
||||
//}
|
||||
int32_t **rxdata;
|
||||
int32_t **txdata;
|
||||
|
||||
int setup_ue_buffers(PHY_VARS_UE **phy_vars_ue, openair0_config_t *openair0_cfg);
|
||||
|
||||
static inline void saif_meas(unsigned int frame_rx, unsigned int subframe_rx) {
|
||||
static latency_stat_t __thread latency_stat;
|
||||
static struct timespec __thread last= {0};
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &now);
|
||||
if ( last.tv_sec ) {
|
||||
uint64_t diffTime = ((uint64_t)now.tv_sec *1000 *1000 *1000 + now.tv_nsec) -
|
||||
((uint64_t)last.tv_sec *1000 *1000 *1000 + last.tv_nsec);
|
||||
diffTime/=1000;
|
||||
latency_stat.counter++;
|
||||
|
||||
if ( diffTime <= 800 ) {
|
||||
if (diffTime < 250 )
|
||||
latency_stat.stat250++;
|
||||
else if (diffTime < 500 )
|
||||
latency_stat.stat500++;
|
||||
else if (diffTime < 600 )
|
||||
latency_stat.stat600++;
|
||||
else if (diffTime < 700 )
|
||||
latency_stat.stat700++;
|
||||
else
|
||||
latency_stat.stat800++;
|
||||
}
|
||||
else if ( diffTime > 1200 ) {
|
||||
if (diffTime < 1500 )
|
||||
latency_stat.stat1300++;
|
||||
else if ( diffTime < 2000 )
|
||||
latency_stat.stat1500++;
|
||||
else if ( diffTime < 2500 )
|
||||
latency_stat.stat2000++;
|
||||
else if ( diffTime < 3000 )
|
||||
latency_stat.stat2500++;
|
||||
else
|
||||
latency_stat.stat3000++;
|
||||
}
|
||||
else
|
||||
if (diffTime <= 880 )
|
||||
latency_stat.stat880++;
|
||||
else if (diffTime <= 960 )
|
||||
latency_stat.stat960++;
|
||||
else if (diffTime <= 1040 )
|
||||
latency_stat.stat1040++;
|
||||
else if (diffTime < 1120 )
|
||||
latency_stat.stat1120++;
|
||||
else
|
||||
latency_stat.stat1200++;
|
||||
|
||||
|
||||
if ( (diffTime>=1500) || ( !(frame_rx%1024) && subframe_rx == 0 ) ) {
|
||||
time_t current=time(NULL);
|
||||
printf("\n");
|
||||
printf("%.2f Period stats cnt=%7.7ld 0.. 250=%7.7ld 250.. 500=%7.7ld 500.. 600=%7.7ld 600.. 700=%7.7ld 700.. 800=%7.7ld - (frame_rx=%u) - %s",
|
||||
now.tv_sec+(double)now.tv_nsec/1e9,
|
||||
latency_stat.counter,
|
||||
latency_stat.stat250, latency_stat.stat500,
|
||||
latency_stat.stat600, latency_stat.stat700,
|
||||
latency_stat.stat800,
|
||||
frame_rx,
|
||||
ctime(¤t));
|
||||
printf("%.2f Period stats cnt=%7.7ld 800.. 880=%7.7ld 880.. 960=%7.7ld 960..1040=%7.7ld 1040..1120=%7.7ld 1120..1200=%7.7ld - (frame_rx=%u) - %s",
|
||||
now.tv_sec+(double)now.tv_nsec/1e9,
|
||||
latency_stat.counter,
|
||||
latency_stat.stat880, latency_stat.stat960,
|
||||
latency_stat.stat1040, latency_stat.stat1120,
|
||||
latency_stat.stat1200,
|
||||
frame_rx,
|
||||
ctime(¤t));
|
||||
printf("%.2f Period stats cnt=%7.7ld 1200..1300=%7.7ld 1300..1500=%7.7ld 1500..2000=%7.7ld 2000..2500=%7.7ld >3000=%7.7ld - (frame_rx=%u) - %s",
|
||||
now.tv_sec+(double)now.tv_nsec/1e9,
|
||||
latency_stat.counter,
|
||||
latency_stat.stat1300, latency_stat.stat1500,
|
||||
latency_stat.stat2000, latency_stat.stat2500,
|
||||
latency_stat.stat3000,
|
||||
frame_rx,
|
||||
ctime(¤t));
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
last=now;
|
||||
}
|
||||
/* End of Changed by SYRTEM */
|
||||
|
||||
void exit_fun(const char* s)
|
||||
{
|
||||
|
||||
if (s != NULL) {
|
||||
printf("%s %s() Exiting OAI softmodem: %s\n",__FILE__, __FUNCTION__, s);
|
||||
}
|
||||
|
||||
oai_exit = 1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, char * name) {
|
||||
|
||||
#ifdef DEADLINE_SCHEDULER
|
||||
if (sched_runtime!=0) {
|
||||
struct sched_attr attr= {0};
|
||||
attr.size = sizeof(attr);
|
||||
// This creates a .5 ms fpga_recv_cnt reservation
|
||||
attr.sched_policy = SCHED_DEADLINE;
|
||||
attr.sched_runtime = sched_runtime;
|
||||
attr.sched_deadline = sched_deadline;
|
||||
attr.sched_period = 0;
|
||||
AssertFatal(sched_setattr(0, &attr, 0) == 0,
|
||||
"[SCHED] main eNB thread: sched_setattr failed %s \n",perror(errno));
|
||||
LOG_I(HW,"[SCHED][eNB] eNB main deadline thread %lu started on CPU %d\n",
|
||||
(unsigned long)gettid(), sched_getcpu());
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef CPU_AFFINITY
|
||||
if (get_nprocs() >2) {
|
||||
for (j = 1; j < get_nprocs(); j++)
|
||||
CPU_SET(j, &cpuset);
|
||||
}
|
||||
AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset)==0,"");
|
||||
#endif
|
||||
struct sched_param sp;
|
||||
sp.sched_priority = sched_fifo;
|
||||
AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0,
|
||||
"Can't set thread priority, Are you root?\n");
|
||||
#endif
|
||||
|
||||
// Lock memory from swapping. This is a process wide call (not constraint to this thread).
|
||||
mlockall(MCL_CURRENT | MCL_FUTURE);
|
||||
pthread_setname_np( pthread_self(), name );
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int ret;
|
||||
uint64_t i;
|
||||
openair0_device rf_device;
|
||||
openair0_timestamp timestamp = 0;
|
||||
|
||||
unsigned int sub_frame = 0;
|
||||
unsigned int frame_rx = 0;
|
||||
|
||||
unsigned int nb_antennas_tx = 1;
|
||||
unsigned int nb_antennas_rx = 1;
|
||||
|
||||
|
||||
openair0_cfg[0].mmapped_dma = 0;
|
||||
openair0_cfg[0].configFilename = NULL;
|
||||
openair0_cfg[0].duplex_mode = duplex_mode_FDD;
|
||||
|
||||
uint32_t **sendbuff = NULL;
|
||||
uint32_t **recvbuff = NULL;
|
||||
uint32_t expected_value = 0;
|
||||
uint32_t received_value = 0;
|
||||
int nsamp = 0; // 1 ms
|
||||
int antenna_id = 1;
|
||||
int c = 0;
|
||||
int numIter = 0;
|
||||
int fpga_loop = 0;
|
||||
#if SYRIQ_CHANNEL_DATA1
|
||||
uint64_t first_ts = 0;
|
||||
uint8_t is_first_ts = 0;
|
||||
uint64_t trx_read_cnt = 0;
|
||||
uint32_t j = 0;
|
||||
uint32_t err_cnt = 0;
|
||||
#else
|
||||
int failure = 0;
|
||||
#endif
|
||||
#if 0 // 5MHz BW
|
||||
unsigned int nb_sample_per_tti = 7680;
|
||||
openair0_cfg[0].sample_rate = 7.68e6;
|
||||
openair0_cfg[0].samples_per_frame = nb_sample_per_tti*10;
|
||||
openair0_cfg[0].rx_bw = 2.5e6;
|
||||
openair0_cfg[0].tx_bw = 2.5e6;
|
||||
openair0_cfg[0].num_rb_dl = 25;
|
||||
#endif
|
||||
|
||||
#if 0 // 10MHz BW
|
||||
unsigned int nb_sample_per_tti = 15360;
|
||||
openair0_cfg[0].sample_rate = 15.36e6;
|
||||
openair0_cfg[0].samples_per_frame = nb_sample_per_tti*10;
|
||||
openair0_cfg[0].rx_bw = 5.0e6;
|
||||
openair0_cfg[0].tx_bw = 5.0e6;
|
||||
openair0_cfg[0].num_rb_dl = 50;
|
||||
#endif
|
||||
|
||||
#if 1 // 20MHz BW
|
||||
unsigned int nb_sample_per_tti = 30720;
|
||||
openair0_cfg[0].sample_rate = 30.72e6;
|
||||
openair0_cfg[0].samples_per_frame = nb_sample_per_tti*10;
|
||||
openair0_cfg[0].rx_bw = 10.0e6;
|
||||
openair0_cfg[0].tx_bw = 10.0e6;
|
||||
openair0_cfg[0].num_rb_dl = 100;
|
||||
#endif
|
||||
|
||||
const char *openair_dir = getenv("OPENAIR_DIR");
|
||||
const char *ini_file = "/usr/local/etc/syriq/ue.band7.tm1.PRB100.NR20.dat";
|
||||
|
||||
int readBlockSize;
|
||||
void* rxp[nb_antennas_rx];
|
||||
void* txp[nb_antennas_tx];
|
||||
|
||||
// int32_t rxdata[1][nb_sample_per_tti*10+2048];
|
||||
#if 0
|
||||
int32_t **rxdata;
|
||||
#endif
|
||||
// init_thread(100000, 500000, sched_get_priority_max(SCHED_FIFO),"main UE");
|
||||
|
||||
printf("LTE HARDWARE Latency debug utility \n");
|
||||
printf("INIT data buffers \n");
|
||||
|
||||
#if 0
|
||||
rxdata = (int32_t**)memalign(32, nb_antennas_rx*sizeof(int32_t*) );
|
||||
rxdata[0] = (int32_t*)memalign(32,(nb_sample_per_tti*10+2048)*sizeof(int32_t));
|
||||
#else
|
||||
rxdata = (int32_t**)malloc16( nb_antennas_rx*sizeof(int32_t*) );
|
||||
txdata = (int32_t**)malloc16( nb_antennas_tx*sizeof(int32_t*) );
|
||||
rxdata[0] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
|
||||
txdata[0] = (int32_t*)malloc16_clear( 307200*sizeof(int32_t) );
|
||||
#endif
|
||||
|
||||
printf("INIT done\n");
|
||||
|
||||
memset(&rf_device, 0, sizeof(openair0_device));
|
||||
|
||||
rf_device.host_type = BBU_HOST;
|
||||
openair0_cfg[0].duplex_mode = duplex_mode_FDD;
|
||||
openair0_cfg[0].rx_num_channels = 1;
|
||||
openair0_cfg[0].tx_num_channels = 1;
|
||||
|
||||
// configure channel 0
|
||||
for (i=0; i<openair0_cfg[0].rx_num_channels; i++)
|
||||
{
|
||||
printf("configure channel %d \n",i);
|
||||
openair0_cfg[0].autocal[i] = 1;
|
||||
openair0_cfg[0].rx_freq[i] = 2680000000;
|
||||
openair0_cfg[0].tx_freq[i] = 2560000000;
|
||||
openair0_cfg[0].rx_gain[i] = 61;
|
||||
openair0_cfg[0].tx_gain[i] = 90;
|
||||
}
|
||||
|
||||
if (openair_dir)
|
||||
{
|
||||
openair0_cfg[0].configFilename = malloc(strlen(openair_dir) + strlen(ini_file) + 2);
|
||||
sprintf(openair0_cfg[0].configFilename, "%s/%s", openair_dir, ini_file);
|
||||
}
|
||||
// printf("openair0_cfg[0].configFilename:%s\n", openair0_cfg[0].configFilename);
|
||||
|
||||
ret = openair0_device_load( &rf_device, &openair0_cfg[0] );
|
||||
if (ret != 0){
|
||||
exit_fun("Error loading device library");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* Runtime test
|
||||
* 30 720 000 samples (4 bytes) for 1 sec (30 720 for 1 ms)
|
||||
*/
|
||||
puts( "* Starting the device" );
|
||||
|
||||
// TIMING
|
||||
// struct timespec start, stop; // tx_start, tx_stop;
|
||||
// timing_stats_t rx_stats, tx_stats;
|
||||
|
||||
// rx_stats.name = strdup( "RX" );
|
||||
// tx_stats.name = strdup( "TX" );
|
||||
// TIMING
|
||||
|
||||
nsamp = 307200; // 1 ms
|
||||
sendbuff = memalign( 128, nb_antennas_rx * sizeof( uint32_t * ) );
|
||||
sendbuff[0] = memalign( 128, nsamp * sizeof( uint32_t ) );
|
||||
recvbuff = memalign( 128, nb_antennas_rx * sizeof( uint32_t * ) );
|
||||
recvbuff[0] = memalign( 128, nsamp * sizeof( uint32_t ) );
|
||||
|
||||
// Create dummy buffer
|
||||
for ( c = 0; c < nsamp; c++ ) {
|
||||
// sendbuff[0][c] = (c+1);
|
||||
sendbuff[0][c] = (c+1)*16;
|
||||
// sendbuff[0][c] = (nsamp-c);
|
||||
recvbuff[0][c] = 0;
|
||||
}
|
||||
|
||||
GET_TIME_INIT(3);
|
||||
|
||||
if ( rf_device.trx_start_func( &rf_device ) < 0 ) {
|
||||
printf( " device could not be started !\n" );
|
||||
return -1;
|
||||
}
|
||||
|
||||
// read 30720
|
||||
|
||||
// write 30720 ts+2*30720
|
||||
|
||||
// if tsread >= 2-307200 -> check expected value + status (RxoVer TxUnder)
|
||||
|
||||
rxp[0] = (void*)&rxdata[0][0];
|
||||
txp[0] = (void*)&txdata[0][0];
|
||||
timestamp = 0;
|
||||
nsamp = 30720; // 30720 => 1ms buffer
|
||||
trx_read_cnt = 100000; // 1 loop => 1ms (10sec=10000; 15min = 900000)
|
||||
antenna_id = 1;
|
||||
int diff = 0;
|
||||
int compare_start = 0;
|
||||
|
||||
uint32_t looploop=0;
|
||||
uint64_t error_cnt = 0;
|
||||
uint64_t error_ts_start;
|
||||
|
||||
for (i = 0; i < trx_read_cnt; i++)
|
||||
{
|
||||
|
||||
// printf("\n\n");
|
||||
|
||||
|
||||
// ret = rf_device.trx_read_func( &rf_device, ×tamp, &(rxp[0][(i*30720)%307200]), nsamp, antenna_id );
|
||||
// ret = rf_device.trx_read_func( &rf_device, ×tamp, recvbuff[0][(i*30720)%307200], nsamp, antenna_id );
|
||||
rxp[0] = (void*)&rxdata[0][(i*30720)%307200];
|
||||
GET_TIME_VAL(0);
|
||||
ret = rf_device.trx_read_func( &rf_device, ×tamp, rxp, nsamp, antenna_id );
|
||||
GET_TIME_VAL(1);
|
||||
|
||||
if (ret != nsamp)
|
||||
{
|
||||
printf("Error: nsamp received (%d) != nsamp required (%d)\n", ret, nsamp);
|
||||
fflush(stdout);
|
||||
return (-1);
|
||||
}
|
||||
if (!is_first_ts)
|
||||
{
|
||||
first_ts = timestamp;
|
||||
is_first_ts = 1;
|
||||
}
|
||||
|
||||
// printf("%d - trx_read_func ret=%d - ts = %d - @=0x%08lx\n", i, ret, timestamp, rxp[0] );
|
||||
|
||||
txp[0] = (void*)&(txdata[0][ ((i*30720)%307200+2*30720)%307200 ]);
|
||||
// printf(" i=%d @txp[0][0] = 0x%016lx\n", i, &(((uint32_t *)txp[0])[0]) );
|
||||
// printf(" i=%d @txp[0][1] = 0x%016lx\n", i, &(((uint32_t *)txp[0])[1]) );
|
||||
|
||||
for ( c = 0; c < nsamp; c++ )
|
||||
{
|
||||
(((uint32_t *)txp[0])[c]) = ( (((timestamp+c+2*30720)<<4)&0x0000FFF0) + (((timestamp+c+2*30720)<<8)&0xFFF00000) );
|
||||
}
|
||||
|
||||
// printf(" txp[0][%d] = 0x%x\n",0,((uint32_t *)(txp[0]))[0]);
|
||||
// printf(" txp[0][%d] = 0x%x\n",1,((uint32_t *)(txp[0]))[1]);
|
||||
// printf(" ...\n");
|
||||
// printf(" txp[0][%d] = 0x%x\n",nsamp-2,((uint32_t *)(txp[0]))[nsamp-2]);
|
||||
// printf(" txp[0][%d] = 0x%x\n",nsamp-1,((uint32_t *)(txp[0]))[nsamp-1]);
|
||||
|
||||
|
||||
ret = rf_device.trx_write_func( &rf_device, (timestamp+2*30720), txp, nsamp, antenna_id, false );
|
||||
if (ret != nsamp)
|
||||
{
|
||||
printf("Error: nsamp sent (%d) != nsamp required (%d)\n", ret, nsamp);
|
||||
fflush(stdout);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
// printf("%d - trx_write_func ret=%d - ts = %d - @=0x%08lx\n", i, ret, (timestamp+2*30720), txp[0] );
|
||||
|
||||
|
||||
if (timestamp >= (first_ts + 2 * 307200))
|
||||
{
|
||||
|
||||
// check Rx Overflow
|
||||
|
||||
// check Tx Underflow
|
||||
|
||||
// check Expected Value
|
||||
for ( c = 0; c < nsamp; c++ )
|
||||
{
|
||||
|
||||
// LOOPBACK
|
||||
#if 1
|
||||
expected_value = ((timestamp + c)&0xFFFFFF);
|
||||
received_value = ((uint32_t *)(rxp[0]))[c];
|
||||
received_value = ((received_value)&0xFFF) + ((received_value>>4)&0xFFF000);
|
||||
|
||||
if (compare_start == 0)
|
||||
{
|
||||
compare_start = 1;
|
||||
diff = expected_value - received_value;
|
||||
}
|
||||
received_value = (received_value + diff)&0xFFFFFF;
|
||||
|
||||
#if 1
|
||||
|
||||
if (expected_value != received_value)
|
||||
{
|
||||
if(!error_cnt)
|
||||
error_ts_start = (timestamp + c);
|
||||
else
|
||||
{
|
||||
if (looploop < 32)
|
||||
printf("%d - %d != %d - ts %d - raw 0x%x - diff %d\n",
|
||||
looploop,
|
||||
expected_value, received_value,
|
||||
(timestamp + c), ((uint32_t *)(rxp[0]))[c],
|
||||
diff);
|
||||
looploop++;
|
||||
}
|
||||
|
||||
error_cnt++;
|
||||
|
||||
if(!(error_cnt%102400))
|
||||
printf(" -> error detected : cnt=%d - start=%ld - stop=... diff=%d\n",
|
||||
error_cnt,
|
||||
error_ts_start,
|
||||
diff);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(error_cnt)
|
||||
{
|
||||
printf(" -> error detected : cnt=%d - start=%ld - stop=%ld\n\n",
|
||||
error_cnt,
|
||||
error_ts_start,
|
||||
(timestamp + c) );
|
||||
looploop=0;
|
||||
}
|
||||
error_cnt=0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// DEBUG mode 0
|
||||
#if 0
|
||||
received_value = ((uint32_t *)(rxp[0]))[c];
|
||||
received_value = ((received_value)&0xFFF) + ((received_value>>4)&0xFFF000);
|
||||
received_value = (received_value&0xFFFFFF);
|
||||
if (compare_start == 0)
|
||||
{
|
||||
compare_start = 1;
|
||||
expected_value = received_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
expected_value++;
|
||||
expected_value = (expected_value&0xFFFFFF);
|
||||
}
|
||||
|
||||
if (expected_value != received_value)
|
||||
{
|
||||
if(!error_cnt)
|
||||
error_ts_start = (timestamp + c);
|
||||
error_cnt++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(error_cnt)
|
||||
{
|
||||
printf(" -> error detected : cnt=%d - start=%ld - stop=%ld\n\n",
|
||||
error_cnt,
|
||||
error_ts_start,
|
||||
(timestamp + c) );
|
||||
}
|
||||
error_cnt=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if (expected_value != received_value)
|
||||
// {
|
||||
// printf("%d -> %d != %d (ts+c=%ld)(raw=0x%08x)\n",
|
||||
// looploop,
|
||||
// expected_value, received_value,
|
||||
// (timestamp + c),
|
||||
// ((uint32_t *)(rxp[0]))[c] );
|
||||
//
|
||||
// if (received_value)
|
||||
// expected_value = received_value;
|
||||
// }
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("HwLat Application returns !!!\n");
|
||||
fflush(stdout);
|
||||
sleep(1);
|
||||
|
||||
|
||||
printf("\n");
|
||||
rf_device.trx_end_func( &rf_device );
|
||||
|
||||
sleep(1);
|
||||
free(sendbuff[0]);
|
||||
free(sendbuff);
|
||||
free(recvbuff[0]);
|
||||
free(recvbuff);
|
||||
|
||||
exit(0);
|
||||
|
||||
|
||||
|
||||
return(0);
|
||||
|
||||
|
||||
|
||||
// puts( "* Frequency modification test" );
|
||||
// rf_device.trx_set_freq_func( &rf_device, &openair0_cfg[0], 0 );
|
||||
|
||||
// puts( "* Gain modification test" );
|
||||
// rf_device.trx_set_gains_func( &rf_device, &openair0_cfg[0] ); // NOT working (cf. initialization)
|
||||
|
||||
//#if LTE_UE
|
||||
// sleep(1);
|
||||
GET_TIME_VAL(0);
|
||||
for (i = 0; i < trx_read_cnt; i++)
|
||||
{
|
||||
printf("\n");
|
||||
ret = rf_device.trx_read_func( &rf_device, ×tamp, rxp, nsamp, antenna_id );
|
||||
printf("* timestamp=%ld\n", timestamp);
|
||||
#if 1
|
||||
for (j = 0; j < nsamp; j++)
|
||||
{
|
||||
if ( ((uint32_t *)rxp[0])[j] != ((expected_value + j + timestamp)%307200) )
|
||||
{
|
||||
err_cnt++;
|
||||
printf("rxp[%06d]=0x%08x (expected 0x%08lx)\n", j, ((uint32_t *)rxp[0])[j], ((expected_value + j + timestamp)%307200) );
|
||||
}
|
||||
if (err_cnt >= 128)
|
||||
{
|
||||
printf("Error: more than 128 expected value failed !\n");
|
||||
i = (trx_read_cnt - 1);
|
||||
j = nsamp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
//expected_value = (expected_value + nsamp)%307200;
|
||||
expected_value = (expected_value)%307200;
|
||||
#endif
|
||||
}
|
||||
GET_TIME_VAL(1);
|
||||
//#endif
|
||||
|
||||
/* ********** ********** */
|
||||
/* SYRIQ_CHANNEL_DATA1 */
|
||||
/* ********** ********** */
|
||||
#if SYRIQ_CHANNEL_DATA1
|
||||
|
||||
// rf_device.trx_get_stats_func( &rf_device );
|
||||
|
||||
rf_device.trx_end_func( &rf_device );
|
||||
|
||||
printf("\n* rf_device.trx_read_func(%d) x %d: %.6lf s\n\n", nsamp, i, ((TIME_VAL_TO_MS(1) - TIME_VAL_TO_MS(0)))/1000.0 );
|
||||
|
||||
// rf_device.trx_get_stats_func( &rf_device );
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < nsamp; i++)
|
||||
{
|
||||
// if ( ((uint32_t *)rxp[0])[i] != i)
|
||||
// {
|
||||
err_cnt++;
|
||||
printf("rxp[%06d]=0x%08x (expected 0x%08x)\n", i, ((uint32_t *)rxp[0])[i], i);
|
||||
// }
|
||||
// if (err_cnt > 256)
|
||||
// {
|
||||
// i = 307200;
|
||||
// break;
|
||||
// }
|
||||
}
|
||||
#endif
|
||||
// for (i = 1024-32; i < 1024+32; i++)
|
||||
// {
|
||||
//// if ( ((uint32_t *)rxp[0])[i] != i)
|
||||
//// {
|
||||
// err_cnt++;
|
||||
// printf("rxp[%06d]=0x%08x (expected 0x%08x)\n", i, ((uint32_t *)rxp[0])[i], i);
|
||||
//// }
|
||||
// if (err_cnt > 256)
|
||||
// {
|
||||
// i = 307200;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
printf("SYRIQ CHANNEL DATA1 done !!!\n");
|
||||
sleep(1);
|
||||
return(0);
|
||||
#endif
|
||||
/* ********** ********** */
|
||||
/* SYRIQ_CHANNEL_DATA1 */
|
||||
/* ********** ********** */
|
||||
|
||||
|
||||
|
||||
timestamp = 0;
|
||||
ret = rf_device.trx_write_func( &rf_device, timestamp, (void**)sendbuff, nsamp, antenna_id, false );
|
||||
printf("* rf_device.trx_write_func returns %d\n", ret);
|
||||
|
||||
sleep(1);
|
||||
|
||||
nsamp = 30720;
|
||||
numIter = 100000;
|
||||
for ( c = 0; c < numIter; c++ )
|
||||
{
|
||||
fpga_loop ++;
|
||||
if ( !(fpga_loop % 1000) )
|
||||
{
|
||||
printf("\rtest loop %d / %d", fpga_loop, numIter);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
// printf("* TEST : %08d\n", (c+1));
|
||||
// measure_time( &rf_device, &start, &stop, &tx_stats, true, 10 );
|
||||
// ret = rf_device.trx_write_func( &rf_device, timestamp, (void**)sendbuff, nsamp, antenna_id, false );
|
||||
// printf("* rf_device.trx_write_func returns %d\n", ret);
|
||||
// measure_time( &rf_device, &start, &stop, &tx_stats, false, 10 );
|
||||
|
||||
// sleep(1);
|
||||
|
||||
// measure_time( &rf_device, &start, &stop, &tx_stats, true, 10 );
|
||||
ret = rf_device.trx_read_func( &rf_device, ×tamp, (void**)recvbuff, nsamp, antenna_id );
|
||||
// measure_time( &rf_device, &start, &stop, &tx_stats, false, 10 );
|
||||
|
||||
// Check the data
|
||||
if (ret > 0)
|
||||
{
|
||||
/* ********** ********** */
|
||||
/* SYRIQ_CHANNEL_TESTER */
|
||||
/* ********** ********** */
|
||||
#if SYRIQ_CHANNEL_TESTER
|
||||
failure = 0;
|
||||
for (i = 0; i < ret; i++)
|
||||
{
|
||||
if ( ((i%1024) == 0) || ((i%1024) == 1) || ((i%1024) == 2) || ((i%1024) == 3) )
|
||||
{
|
||||
if ( (recvbuff[0])[i] != (1020 + ((i%1024)+1)) )
|
||||
{
|
||||
printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) );
|
||||
failure = 1;
|
||||
}
|
||||
}
|
||||
else if ( (recvbuff[0])[i] != ((i%1024)+1) )
|
||||
{
|
||||
printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) );
|
||||
failure = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("* DONE (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) );
|
||||
}
|
||||
if(failure)
|
||||
break;
|
||||
}
|
||||
if (failure)
|
||||
printf("* ERROR recv %08d checked FAILURE ret=%d\n", (c+1), ret);
|
||||
else
|
||||
{
|
||||
// printf("* DONE recv %08d checked SUCCESSFULLY ret=%d\n", (c+1), ret);
|
||||
}
|
||||
#endif
|
||||
/* ********** ********** */
|
||||
/* SYRIQ_CHANNEL_TESTER2*/
|
||||
/* ********** ********** */
|
||||
#if SYRIQ_CHANNEL_TESTER2
|
||||
// printf("* ret=%d timestamp=%ld (%ld)\n", ret, timestamp, (timestamp%307200));
|
||||
failure = 0;
|
||||
for (i = 0; i < ret; i++)
|
||||
{
|
||||
// printf("* (recvbuff[0])[%d]: %d\n", i, (uint32_t)(recvbuff[0])[i]);
|
||||
// printf("* timestamp+(i/1024+1)*1024 - 3 + i%1024: %d\n", (timestamp-nsamp+(i/1024+1)*1024 - 3 + i%1024)%307200 );
|
||||
expected_value = ((((i%1024)+1)/*>>4*/)&0x00000FFF);
|
||||
if ( ((i%1024) == 0) || ((i%1024) == 1) || ((i%1024) == 2) || ((i%1024) == 3) )
|
||||
{
|
||||
expected_value = ((((timestamp-nsamp+(i/1024+1)*1024 - 3 + i%1024))%307200));
|
||||
if ( (recvbuff[0])[i] != expected_value)
|
||||
{
|
||||
if ( (expected_value == 0) && ((recvbuff[0])[i] != 4915200) )
|
||||
{
|
||||
printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], expected_value );
|
||||
failure = 1;
|
||||
}
|
||||
if ( (expected_value == 0) && ((recvbuff[0])[i] == 4915200) )
|
||||
{
|
||||
// printf("* DONE loop in circular buffer\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( (recvbuff[0])[i] != expected_value )
|
||||
{
|
||||
printf("* ERROR (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) );
|
||||
failure = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("* DONE (buff[0])[%d]: %d, expected %d\n", i, (uint32_t)(recvbuff[0])[i], ((i%1024)+1) );
|
||||
}
|
||||
// if(failure)
|
||||
// break;
|
||||
}
|
||||
if (failure)
|
||||
printf("* ERROR recv %08d checked FAILURE ret=%d\n", (c+1), ret);
|
||||
else
|
||||
{
|
||||
// printf("* DONE recv %08d checked SUCCESSFULLY ret=%d\n", (c+1), ret);
|
||||
}
|
||||
#endif
|
||||
#if LOOPBACK
|
||||
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("* ERROR rf_device.trx_read_func returns %d\n", ret);
|
||||
}
|
||||
|
||||
}
|
||||
printf("\n");
|
||||
rf_device.trx_end_func( &rf_device );
|
||||
|
||||
sleep(1);
|
||||
free(sendbuff[0]);
|
||||
free(sendbuff);
|
||||
free(recvbuff[0]);
|
||||
free(recvbuff);
|
||||
|
||||
exit(0);
|
||||
|
||||
// END IS HERE !
|
||||
|
||||
rf_device.trx_set_freq_func(&rf_device,&openair0_cfg[0],0);
|
||||
|
||||
if (rf_device.trx_start_func(&rf_device) != 0 ) {
|
||||
printf("Could not start the device\n");
|
||||
oai_exit=1;
|
||||
}
|
||||
|
||||
while(!oai_exit){
|
||||
|
||||
rxp[0] = (void*)&rxdata[0][sub_frame*nb_sample_per_tti];
|
||||
|
||||
readBlockSize = rf_device.trx_read_func(&rf_device,
|
||||
×tamp,
|
||||
rxp,
|
||||
nb_sample_per_tti,
|
||||
0);
|
||||
|
||||
if ( readBlockSize != nb_sample_per_tti )
|
||||
oai_exit = 1;
|
||||
|
||||
sub_frame++;
|
||||
sub_frame%=10;
|
||||
|
||||
if( sub_frame == 0)
|
||||
frame_rx++;
|
||||
|
||||
saif_meas(frame_rx, sub_frame);
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user