mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-20 16:10:29 +00:00
Compare commits
1 Commits
issue-963
...
l2-sim-new
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0bca5048db |
230
ci-scripts/conf_files/gnb_l2proxy_vnf.conf
Normal file
230
ci-scripts/conf_files/gnb_l2proxy_vnf.conf
Normal file
@@ -0,0 +1,230 @@
|
||||
Active_gNBs = ( "oai-gnb-rfsim");
|
||||
# Asn1_verbosity, choice in: none, info, annoying
|
||||
Asn1_verbosity = "none";
|
||||
gNBs =
|
||||
(
|
||||
{
|
||||
////////// Identification parameters:
|
||||
gNB_ID = 0xe00;
|
||||
gNB_name = "oai-gnb-rfsim";
|
||||
// Tracking area code, 0x0000 and 0xfffe are reserved values
|
||||
tracking_area_code = 1 ;
|
||||
plmn_list = ({ mcc = 001; mnc = 01; mnc_length = 2; snssaiList = ({ sst = 1 }) });
|
||||
|
||||
nr_cellid = 12345678L
|
||||
|
||||
# tr_s_preference = "local_mac"
|
||||
|
||||
////////// Physical parameters:
|
||||
|
||||
sib1_tda = 5;
|
||||
min_rxtxtime = 6;
|
||||
|
||||
# metrics_db_url = "http://default:Jamsung665@metrics-db-clickhouse.oai.svc.cluster.local:8123/";
|
||||
|
||||
servingCellConfigCommon = (
|
||||
{
|
||||
#spCellConfigCommon
|
||||
|
||||
physCellId = 0;
|
||||
|
||||
# downlinkConfigCommon
|
||||
#frequencyInfoDL
|
||||
# this is 3600 MHz + 43 PRBs@30kHz SCS (same as initial BWP)
|
||||
absoluteFrequencySSB = 641280;
|
||||
dl_frequencyBand = 78;
|
||||
# this is 3600 MHz
|
||||
dl_absoluteFrequencyPointA = 640008;
|
||||
#scs-SpecificCarrierList
|
||||
dl_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
dl_subcarrierSpacing = 1;
|
||||
dl_carrierBandwidth = 106;
|
||||
#initialDownlinkBWP
|
||||
#genericParameters
|
||||
# this is RBstart=27,L=48 (275*(L-1))+RBstart
|
||||
initialDLBWPlocationAndBandwidth = 28875; # 6366 12925 12956 28875 12952
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialDLBWPsubcarrierSpacing = 1;
|
||||
#pdcch-ConfigCommon
|
||||
initialDLBWPcontrolResourceSetZero = 12;
|
||||
initialDLBWPsearchSpaceZero = 0;
|
||||
|
||||
#uplinkConfigCommon
|
||||
#frequencyInfoUL
|
||||
ul_frequencyBand = 78;
|
||||
#scs-SpecificCarrierList
|
||||
ul_offstToCarrier = 0;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
ul_subcarrierSpacing = 1;
|
||||
ul_carrierBandwidth = 106;
|
||||
pMax = 20;
|
||||
#initialUplinkBWP
|
||||
#genericParameters
|
||||
initialULBWPlocationAndBandwidth = 28875;
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
initialULBWPsubcarrierSpacing = 1;
|
||||
#rach-ConfigCommon
|
||||
#rach-ConfigGeneric
|
||||
prach_ConfigurationIndex = 98;
|
||||
#prach_msg1_FDM
|
||||
#0 = one, 1=two, 2=four, 3=eight
|
||||
prach_msg1_FDM = 0;
|
||||
prach_msg1_FrequencyStart = 0;
|
||||
zeroCorrelationZoneConfig = 13;
|
||||
preambleReceivedTargetPower = -96;
|
||||
#preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200)
|
||||
preambleTransMax = 6;
|
||||
#powerRampingStep
|
||||
# 0=dB0,1=dB2,2=dB4,3=dB6
|
||||
powerRampingStep = 1;
|
||||
#ra_ReponseWindow
|
||||
#1,2,4,8,10,20,40,80
|
||||
ra_ResponseWindow = 5; // RDF: Change from 4 to 5 for nFAPI VNF
|
||||
#ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR
|
||||
#1=oneeighth,2=onefourth,3=half,4=one,5=two,6=four,7=eight,8=sixteen
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB_PR = 4;
|
||||
#oneHalf (0..15) 4,8,12,16,...60,64
|
||||
ssb_perRACH_OccasionAndCB_PreamblesPerSSB = 14;
|
||||
#ra_ContentionResolutionTimer
|
||||
#(0..7) 8,16,24,32,40,48,56,64
|
||||
ra_ContentionResolutionTimer = 7;
|
||||
rsrp_ThresholdSSB = 19;
|
||||
#prach-RootSequenceIndex_PR
|
||||
#1 = 839, 2 = 139
|
||||
prach_RootSequenceIndex_PR = 2;
|
||||
prach_RootSequenceIndex = 1;
|
||||
# SCS for msg1, can only be 15 for 30 kHz < 6 GHz, takes precendence over the one derived from prach-ConfigIndex
|
||||
#
|
||||
msg1_SubcarrierSpacing = 1,
|
||||
# restrictedSetConfig
|
||||
# 0=unrestricted, 1=restricted type A, 2=restricted type B
|
||||
restrictedSetConfig = 0,
|
||||
|
||||
msg3_DeltaPreamble = 1;
|
||||
p0_NominalWithGrant =-90;
|
||||
|
||||
# pucch-ConfigCommon setup :
|
||||
# pucchGroupHopping
|
||||
# 0 = neither, 1= group hopping, 2=sequence hopping
|
||||
pucchGroupHopping = 0;
|
||||
hoppingId = 40;
|
||||
p0_nominal = -90;
|
||||
# ssb_PositionsInBurs_BitmapPR
|
||||
# 1=short, 2=medium, 3=long
|
||||
ssb_PositionsInBurst_PR = 2;
|
||||
ssb_PositionsInBurst_Bitmap = 1;
|
||||
|
||||
# ssb_periodicityServingCell
|
||||
# 0 = ms5, 1=ms10, 2=ms20, 3=ms40, 4=ms80, 5=ms160, 6=spare2, 7=spare1
|
||||
ssb_periodicityServingCell = 2;
|
||||
|
||||
# dmrs_TypeA_position
|
||||
# 0 = pos2, 1 = pos3
|
||||
dmrs_TypeA_Position = 0;
|
||||
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
subcarrierSpacing = 1;
|
||||
|
||||
|
||||
#tdd-UL-DL-ConfigurationCommon
|
||||
# subcarrierSpacing
|
||||
# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120
|
||||
referenceSubcarrierSpacing = 1;
|
||||
# pattern1
|
||||
# dl_UL_TransmissionPeriodicity
|
||||
# 0=ms0p5, 1=ms0p625, 2=ms1, 3=ms1p25, 4=ms2, 5=ms2p5, 6=ms5, 7=ms10
|
||||
dl_UL_TransmissionPeriodicity = 6;
|
||||
nrofDownlinkSlots = 7;
|
||||
nrofDownlinkSymbols = 6;
|
||||
nrofUplinkSlots = 2;
|
||||
nrofUplinkSymbols = 4;
|
||||
|
||||
ssPBCH_BlockPower = -25;
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
# ------- SCTP definitions
|
||||
SCTP :
|
||||
{
|
||||
# Number of streams to use in input/output
|
||||
SCTP_INSTREAMS = 2;
|
||||
SCTP_OUTSTREAMS = 2;
|
||||
};
|
||||
|
||||
////////// AMF parameters:
|
||||
amf_ip_address = ( { ipv4 = "10.42.0.133";});
|
||||
|
||||
|
||||
NETWORK_INTERFACES :
|
||||
{
|
||||
GNB_IPV4_ADDRESS_FOR_NG_AMF = "10.42.0.142";
|
||||
GNB_IPV4_ADDRESS_FOR_NGU = "10.42.0.142";
|
||||
GNB_PORT_FOR_S1U = 2152; # Spec 2152
|
||||
};
|
||||
}
|
||||
);
|
||||
MACRLCs = (
|
||||
{
|
||||
num_cc = 1;
|
||||
local_s_if_name = "lo:";
|
||||
remote_s_address = "127.0.0.1"; // pnf addr [!]
|
||||
local_s_address = "127.0.0.2"; // vnf addr
|
||||
local_s_portc = 50601; // vnf p5 port
|
||||
remote_s_portc = 50600; // pnf p5 port [!]
|
||||
local_s_portd = 50611; // vnf p7 port [!]
|
||||
remote_s_portd = 50610; // pnf p7 port [!]
|
||||
tr_s_preference = "nfapi";
|
||||
tr_n_preference = "local_RRC";
|
||||
# pusch_TargetSNRx10 = 200; # 150;
|
||||
# pucch_TargetSNRx10 = 200; #200;
|
||||
# ulsch_max_frame_inactivity = 10;
|
||||
# dl_max_mcs = 25;
|
||||
# ul_max_mcs = 25;
|
||||
}
|
||||
);
|
||||
|
||||
# THREAD_STRUCT = (
|
||||
# {
|
||||
# #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT"
|
||||
# parallel_config = "PARALLEL_SINGLE_THREAD";
|
||||
# #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE"
|
||||
# worker_config = "WORKER_ENABLE";
|
||||
# }
|
||||
# );
|
||||
|
||||
security = {
|
||||
# preferred ciphering algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nea0, nea1, nea2, nea3
|
||||
ciphering_algorithms = ( "nea0" );
|
||||
|
||||
# preferred integrity algorithms
|
||||
# the first one of the list that an UE supports in chosen
|
||||
# valid values: nia0, nia1, nia2, nia3
|
||||
integrity_algorithms = ( "nia2", "nia0" );
|
||||
|
||||
# setting 'drb_ciphering' to "no" disables ciphering for DRBs, no matter
|
||||
# what 'ciphering_algorithms' configures; same thing for 'drb_integrity'
|
||||
drb_ciphering = "yes";
|
||||
drb_integrity = "no";
|
||||
};
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
nr_mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
49
ci-scripts/conf_files/nrue_l2proxy.conf
Normal file
49
ci-scripts/conf_files/nrue_l2proxy.conf
Normal file
@@ -0,0 +1,49 @@
|
||||
uicc0 = {
|
||||
imsi = "001010000000100";
|
||||
key = "fec86ba6eb707ed08905757b1bb44b8f";
|
||||
opc= "C42449363BBAD02B66D16BC975D77CC1";
|
||||
dnn= "oai";
|
||||
nssai_sst="1";
|
||||
nssai_sd="16777215";
|
||||
}
|
||||
|
||||
MACRLCs = ( {
|
||||
num_cc = 1;
|
||||
tr_n_preference = "nfapi";
|
||||
local_n_if_name = "eth0:";
|
||||
remote_n_address = "10.42.0.142"; //Proxy IP
|
||||
local_n_address = "10.42.0.143";
|
||||
local_n_portc = 50600;
|
||||
remote_n_portc = 50601;
|
||||
local_n_portd = 50610;
|
||||
remote_n_portd = 50611;
|
||||
} );
|
||||
|
||||
|
||||
log_config :
|
||||
{
|
||||
global_log_level ="info";
|
||||
|
||||
hw_log_level ="info";
|
||||
phy_log_level ="info";
|
||||
nr_phy_log_level ="info";
|
||||
mac_log_level ="info";
|
||||
nr_mac_log_level ="info";
|
||||
# rlc_log_level ="debug";
|
||||
# pdcp_log_level ="debug";
|
||||
# rrc_log_level ="debug";
|
||||
# nr_rrc_log_level ="debug";
|
||||
# nr_phy_dci_log_level ="debug";
|
||||
# nr_mac_dci_log_level ="debug";
|
||||
|
||||
# mac_log_level ="info";
|
||||
# nr_mac_log_level ="info";
|
||||
rlc_log_level ="info";
|
||||
pdcp_log_level ="info";
|
||||
rrc_log_level ="info";
|
||||
nr_rrc_log_level ="info";
|
||||
f1ap_log_level ="info";
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OPENAIRINTERFACE5G_LIMITS_H_
|
||||
#define OPENAIRINTERFACE5G_LIMITS_H_
|
||||
|
||||
# define MAX_MOBILES_PER_GNB 16
|
||||
# define MAX_MOBILES_PER_GNB 50
|
||||
# define NUMBER_OF_eNB_MAX 1
|
||||
# define NUMBER_OF_gNB_MAX 1
|
||||
# define NUMBER_OF_RU_MAX 2
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "nr_phy_common.h"
|
||||
#include "common/utils/time_manager/time_manager.h"
|
||||
#include "log.h"
|
||||
#include "nfapi/open-nFAPI/common/public_inc/debug.h"
|
||||
|
||||
/*
|
||||
* NR SLOT PROCESSING SEQUENCE
|
||||
@@ -222,20 +223,30 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn, int slo
|
||||
nfapi_nr_dl_tti_request_t *dl_tti_request = get_queue(&nr_dl_tti_req_queue);
|
||||
nfapi_nr_ul_dci_request_t *ul_dci_request = get_queue(&nr_ul_dci_req_queue);
|
||||
|
||||
nfapi_nr_ul_tti_request_t *ul_tti_request_crc_curr_slot = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
|
||||
|
||||
for (int i = 0; i < NR_MAX_HARQ_PROCESSES; i++) {
|
||||
LOG_D(NR_MAC,
|
||||
LOG_T(NR_MAC,
|
||||
"Try to get a ul_tti_req by matching CRC active sfn/slot %d.%d from queue with %lu items\n",
|
||||
sfn,
|
||||
slot,
|
||||
nr_ul_tti_req_queue.num_items);
|
||||
struct sfn_slot_s sfn_sf = {.sfn = mac->nr_ue_emul_l1.harq[i].active_ul_harq_sfn, .slot = mac->nr_ue_emul_l1.harq[i].active_ul_harq_slot };
|
||||
nfapi_nr_ul_tti_request_t *ul_tti_request_crc = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_sf);
|
||||
nfapi_nr_ul_tti_request_t *ul_tti_request_crc;
|
||||
if (ul_tti_request_crc_curr_slot && ul_tti_request_crc_curr_slot->n_pdus > 0 && sfn_sf.sfn == sfn && sfn_sf.slot == slot) {
|
||||
ul_tti_request_crc = ul_tti_request_crc_curr_slot;
|
||||
} else {
|
||||
ul_tti_request_crc = unqueue_matching(&nr_ul_tti_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_sf);
|
||||
}
|
||||
|
||||
if (ul_tti_request_crc && ul_tti_request_crc->n_pdus > 0) {
|
||||
LOG_D(NR_MAC, "Got ul_tti_req for sfn/slot %d.%d\n", sfn, slot);
|
||||
check_and_process_dci(NULL, NULL, NULL, ul_tti_request_crc);
|
||||
free_and_zero(ul_tti_request_crc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (rach_ind && rach_ind->number_of_pdus > 0) {
|
||||
NR_UL_IND_t UL_INFO = {
|
||||
.rach_ind = *rach_ind,
|
||||
@@ -246,8 +257,19 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn, int slo
|
||||
}
|
||||
if (dl_tti_request) {
|
||||
struct sfn_slot_s sfn_slot = {.sfn = dl_tti_request->SFN, .slot = dl_tti_request->Slot};
|
||||
nfapi_nr_tx_data_request_t *tx_data_request = unqueue_matching(&nr_tx_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
|
||||
nfapi_nr_tx_data_request_t *tx_data_request = NULL;
|
||||
int try_ctr = 10;
|
||||
int sleep_time = 0;
|
||||
while (try_ctr-- > 0) {
|
||||
tx_data_request = unqueue_matching(&nr_tx_req_queue, MAX_QUEUE_SIZE, sfn_slot_matcher, &sfn_slot);
|
||||
if (tx_data_request)
|
||||
break;
|
||||
usleep(200);
|
||||
sleep_time += 200;
|
||||
}
|
||||
if (!tx_data_request) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_DEBUG, "[%d.%d] No corresponding tx_data_request for given dl_tti_request sfn/slot\n",
|
||||
dl_tti_request->SFN, dl_tti_request->Slot);
|
||||
LOG_E(NR_MAC, "[%d.%d] No corresponding tx_data_request for given dl_tti_request sfn/slot\n",
|
||||
dl_tti_request->SFN, dl_tti_request->Slot);
|
||||
if (get_softmodem_params()->nsa)
|
||||
@@ -255,6 +277,10 @@ static void process_queued_nr_nfapi_msgs(NR_UE_MAC_INST_t *mac, int sfn, int slo
|
||||
free_and_zero(dl_tti_request);
|
||||
}
|
||||
else if (dl_tti_request->dl_tti_request_body.nPDUs > 0 && tx_data_request->Number_of_PDUs > 0) {
|
||||
// if (sleep_time > 0) {
|
||||
// LOG_E(NR_MAC, "[%d.%d] Had to wait for %d us for tx_data_request for sfn/slot\n",
|
||||
// dl_tti_request->SFN, dl_tti_request->Slot, sleep_time);
|
||||
// }
|
||||
if (get_softmodem_params()->nsa)
|
||||
save_nr_measurement_info(dl_tti_request);
|
||||
check_and_process_dci(dl_tti_request, tx_data_request, NULL, NULL);
|
||||
@@ -312,7 +338,7 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
||||
}
|
||||
else if (ch_info) {
|
||||
sfn_slot = ch_info->sfn_slot;
|
||||
free_and_zero(ch_info);
|
||||
// free_and_zero(ch_info);
|
||||
}
|
||||
|
||||
int mu = 1; // NR-UE emul-L1 is hardcoded to 30kHZ, see check_and_process_dci()
|
||||
@@ -325,7 +351,14 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
||||
}
|
||||
last_sfn_slot = sfn_slot;
|
||||
|
||||
LOG_D(NR_MAC, "The received sfn/slot [%d %d] from proxy\n",
|
||||
int ret = pthread_mutex_lock(&mac->if_mutex);
|
||||
AssertFatal(!ret, "mutex failed %d\n", ret);
|
||||
update_mac_ul_timers(mac);
|
||||
update_mac_dl_timers(mac);
|
||||
ret = pthread_mutex_unlock(&mac->if_mutex);
|
||||
AssertFatal(!ret, "mutex failed %d\n", ret);
|
||||
|
||||
LOG_D(NR_MAC, "Received sfn/slot indication [%d %d] from proxy\n",
|
||||
frame, slot);
|
||||
|
||||
if (IS_SA_MODE(get_softmodem_params()) && mac->mib == NULL) {
|
||||
@@ -350,8 +383,12 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
||||
mac->nr_ue_emul_l1.pmi = ch_info->csi[0].pmi;
|
||||
mac->nr_ue_emul_l1.ri = ch_info->csi[0].ri;
|
||||
mac->nr_ue_emul_l1.cqi = ch_info->csi[0].cqi;
|
||||
mac->nr_ue_emul_l1.rsrp_dBm = ch_info->csi[0].rsrp;
|
||||
free_and_zero(ch_info);
|
||||
}
|
||||
else {
|
||||
mac->nr_ue_emul_l1.rsrp_dBm = -44;
|
||||
}
|
||||
|
||||
if (is_dl_slot(slot, &mac->frame_structure)) {
|
||||
memset(&mac->dl_info, 0, sizeof(mac->dl_info));
|
||||
@@ -372,6 +409,8 @@ static void *NRUE_phy_stub_standalone_pnf_task(void *arg)
|
||||
nr_ue_ul_scheduler(mac, &ul_info);
|
||||
}
|
||||
process_queued_nr_nfapi_msgs(mac, frame, slot);
|
||||
|
||||
send_slot_response(frame, slot);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -128,6 +128,23 @@ int otg_enabled;
|
||||
double cpuf;
|
||||
uint32_t N_RB_DL = 106;
|
||||
|
||||
void *emu_l1_mac_ue(void *notUsed)
|
||||
{
|
||||
MessageDef *msg = NULL;
|
||||
itti_receive_msg(TASK_MAC_UE, &msg);
|
||||
if (msg)
|
||||
process_msg_rcc_to_mac(msg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *emu_l1_mac_ue_task(void *args_p)
|
||||
{
|
||||
itti_mark_task_ready(TASK_MAC_UE);
|
||||
while (1) {
|
||||
emu_l1_mac_ue(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int create_tasks_nrue(uint32_t ue_nb) {
|
||||
LOG_D(NR_RRC, "%s(ue_nb:%d)\n", __FUNCTION__, ue_nb);
|
||||
itti_wait_ready(1);
|
||||
@@ -151,6 +168,13 @@ int create_tasks_nrue(uint32_t ue_nb) {
|
||||
LOG_E(NR_RRC, "Create task for NAS UE failed\n");
|
||||
return -1;
|
||||
}
|
||||
if(get_softmodem_params()->emulate_l1) {
|
||||
const ittiTask_parms_t parmsEmuMacUe = {NULL, emu_l1_mac_ue};
|
||||
if (itti_create_task(TASK_MAC_UE, emu_l1_mac_ue_task, &parmsEmuMacUe) < 0) {
|
||||
LOG_E(NR_RRC, "Create task for Emu L1 MAC UE failed\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
itti_wait_ready(0);
|
||||
|
||||
32
l2-fapi-proxy/.gitignore
vendored
Normal file
32
l2-fapi-proxy/.gitignore
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
# autotools
|
||||
Makefile.in
|
||||
*.o
|
||||
.dirstamp
|
||||
|
||||
# object files/dependencies
|
||||
*.la
|
||||
*.lo
|
||||
*.o
|
||||
**/.deps
|
||||
**/.libs
|
||||
|
||||
# python byte code
|
||||
*.pyc
|
||||
|
||||
# deb
|
||||
.debbuild
|
||||
|
||||
# man pages
|
||||
*.1
|
||||
|
||||
#build output
|
||||
build/
|
||||
|
||||
.vscode/
|
||||
|
||||
*.log
|
||||
*~
|
||||
coredump-*
|
||||
*.log.bz2
|
||||
|
||||
|
||||
194
l2-fapi-proxy/LICENSE
Normal file
194
l2-fapi-proxy/LICENSE
Normal file
@@ -0,0 +1,194 @@
|
||||
The Episys Science (EpiSci) Public License (Version 1.1)
|
||||
|
||||
LICENSE TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION OF EPISYS SCIENCE (EpiSci) 5G SOFTWARE.
|
||||
|
||||
1. Definitions.
|
||||
|
||||
“License” shall mean the terms and conditions for use, reproduction, and distribution set forth
|
||||
in this document.
|
||||
|
||||
“Licensor” shall mean the Episys Science (EpiSci).
|
||||
|
||||
“Legal Entity” shall mean the union, at the time an acting entity joins the Company, of the
|
||||
acting entity and all other entities that control, are controlled by, or are under common control
|
||||
with that entity. For the purposes of this definition, “control” means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii)
|
||||
beneficial ownership of such entity.
|
||||
|
||||
“You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by
|
||||
this License.
|
||||
|
||||
“Source” form shall mean the preferred form for making modifications, including but not
|
||||
limited to software source code, documentation source, and configuration files.
|
||||
|
||||
“Object” form shall mean any form resulting from mechanical transformation or translation of
|
||||
a Source form, including but not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
“Work” shall mean the work of authorship, whether in Source or Object form, made available
|
||||
under the License, as indicated by a copyright notice that is included in or attached to the
|
||||
work (an example is provided in the Appendix below).
|
||||
|
||||
“Derivative Works” shall mean any work, whether in Source or Object form, that is based on
|
||||
(or derived from) the Work and for which the editorial revisions, annotations, elaborations, or
|
||||
other modifications represent, as a whole, an original work of authorship. For the purposes of
|
||||
this License, Derivative Works shall not include works that remain separable from, or merely
|
||||
link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
“Contribution” shall mean any work of authorship that is intentionally submitted to Licensor
|
||||
for inclusion in the Work by the copyright owner or by an individual or Legal Entity
|
||||
authorized to submit on behalf of the copyright owner. For the purposes of this definition,
|
||||
“submitted” means any form of electronic, , or written communication sent to the Licensor or
|
||||
its representatives, including but not limited to communication on electronic mailing lists,
|
||||
source code control systems, and issue tracking systems that are managed by, or on behalf of,
|
||||
the Licensor for the purpose of discussing and improving the Work
|
||||
|
||||
“Contributor License Agreement” shall mean the agreement signed by any Contributor setting
|
||||
forth the terms and conditions applicable to its Contribution.
|
||||
|
||||
“Contributor” shall mean any individual or Legal Entity on behalf of whom a Contribution
|
||||
has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License.
|
||||
Subject to the terms and conditions of this License, Licensor and each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of, publicly display, publicly
|
||||
perform, and distribute the Work and such Derivative Works in Source or Object form
|
||||
|
||||
3. Grant of Patent License.
|
||||
|
||||
3.1 Grant of Patent License for study, testing and research purposes:
|
||||
Subject to the terms and conditions of this License, Licensor and each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made, use, and otherwise
|
||||
transfer (excluding selling) the Work, solely for study, testing and research purposes, where
|
||||
such license applies only to those patent claims licensable by Licensor or such Contributor
|
||||
that are necessarily infringed respectively by the Work and/or the said Contributor
|
||||
Contribution(s) alone or by combination of their Contribution(s) with the Work to which
|
||||
such Contribution(s) was submitted (“Essential Patents”).
|
||||
|
||||
3.2 Grant of Patent License for purposes other than study and research:
|
||||
For purposes other than study, testing and research, and subject to the terms and conditions of
|
||||
this License, You commit to be prepared to negotiate a non-exclusive, non-transferable, non-
|
||||
assignable license of Essential Patents with each Contributor and/or the Licensor on Fair,
|
||||
Reasonable and Non-Discriminatory (“FRAND”) terms and conditions for the use of the
|
||||
Work or Contribution(s) incorporated within the Work.
|
||||
Licensor and/or each Contributor, by submitting a Contribution, will identify any of its known
|
||||
Essential Patent it owns related to the Work and/or its Contribution.
|
||||
|
||||
3.3 Patent Litigation
|
||||
If You institute patent litigation against any entity making use of the Work solely for study,
|
||||
testing and research purposes (including a cross-claim or counterclaim in a lawsuit) alleging
|
||||
that the Work or a Contribution incorporated within the Work constitutes direct or
|
||||
contributory patent infringement, then the patent licenses granted to You under section 3.1 of
|
||||
this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Sublicensing
|
||||
You may grant sublicenses under the licenses granted under sections 2 and 3.1 provided that
|
||||
the sublicense is subject to and inclusive of all the terms of and rights under this License to
|
||||
which the Work is or was distributed by the Episys Science (EpiSci).
|
||||
|
||||
5. Redistribution
|
||||
Subject to terms and conditions set forth in sections 2 and 3, You may reproduce and
|
||||
distribute copies of the Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You meet the following
|
||||
conditions:
|
||||
|
||||
1. You must give any other recipients of the Work or Derivative Works a copy of this
|
||||
License; and
|
||||
|
||||
2. You must cause any modified files by You to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
|
||||
3. You must retain, in the Source form of any Derivative Works that You distribute, all
|
||||
copyright, patent, trademark, and attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
|
||||
4. If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative
|
||||
Works that You distribute must include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works, in at least one of the following places: within a NOTICE text file
|
||||
distributed as part of the Derivative Works; within the Source form or documentation, if
|
||||
provided along with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of the
|
||||
NOTICE file are for informational purposes only and do not modify the License. You may
|
||||
add Your own attribution notices within Derivative Works that You distribute, alongside or as
|
||||
an addendum to the NOTICE text from the Work, provided that such additional attribution
|
||||
notices cannot be construed as modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or distribution of
|
||||
Your modifications, or for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with the conditions stated in
|
||||
this License.
|
||||
|
||||
6. Submission of Contributions.
|
||||
Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be
|
||||
under the terms and conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of any
|
||||
separate license agreement such as the Contributor License Agreement You may have
|
||||
executed with Licensor regarding such Contributions.
|
||||
|
||||
7. Trademarks.
|
||||
This License does not grant permission to use the trade names, trademarks, service marks, or
|
||||
product names of the Licensor, except as required for reasonable and customary use in
|
||||
describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
8. Disclaimer of Warranty.
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the Work (and
|
||||
each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including,
|
||||
without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
|
||||
MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely
|
||||
responsible for determining the appropriateness of using or redistributing the Work and
|
||||
assume any risks associated with your exercise of permissions under this License.
|
||||
|
||||
9. Limitation of Liability.
|
||||
In no event and under no legal theory, whether in tort (including negligence), contract, or
|
||||
otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or
|
||||
agreed to in writing, shall Licensor and any Contributor, as such, be liable to You for
|
||||
damages, including any direct, indirect, special, incidental, or consequential damages of any
|
||||
character arising as a result of this License or out of Your use or inability to use the Work
|
||||
(including but not limited to damages for loss of goodwill, work stoppage, computer failure or
|
||||
malfunction, or any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
10. Accepting Warranty or Additional Liability.
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to offer, and
|
||||
charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations
|
||||
and/or rights consistent with this License. However, in accepting such obligations, You may
|
||||
act only on Your own behalf and on Your sole responsibility, not on behalf of any other
|
||||
Contributor and/or the Licensor, and only if You agree to indemnify, defend, and hold each
|
||||
Contributor and/or the Licensor harmless for any liability incurred by, or claims asserted
|
||||
against, such Contributor and/or Licensor by reason of Your accepting any such warranty or
|
||||
additional liability.
|
||||
|
||||
11. Applicable law.
|
||||
The present license shall be governed by the laws of France.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
1. APPENDIX: How to apply the PRESENT EPISYS SCIENCE (EpiSci) 5G License to your work
|
||||
To apply the present License to your work, attach the following boilerplate notice, with the
|
||||
fields enclosed by brackets “[]” replaced with your own identifying information. (Don’t
|
||||
include the brackets!) The text should be enclosed in the appropriate comment syntax for the
|
||||
file format. We also recommend that a file or class name and description of purpose be
|
||||
included on the same “printed page” as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the License terms and conditions for use, reproduction, and distribution of
|
||||
EPISYS SCIENCE (EpiSci) 5G software (the “License”);
|
||||
|
||||
you may not use this file except in compliance with the License. You may obtain a copy of
|
||||
the License at
|
||||
|
||||
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.
|
||||
|
||||
87
l2-fapi-proxy/Makefile
Normal file
87
l2-fapi-proxy/Makefile
Normal file
@@ -0,0 +1,87 @@
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -g -O3 -Wall -Werror
|
||||
CXX = g++ -O3 -std=c++11
|
||||
CXXFLAGS = -g -O3 -Wall -Wextra -Werror
|
||||
|
||||
# CXX = g++ -std=c++11
|
||||
# CFLAGS = -g -Wall #-Werror
|
||||
# CXXFLAGS = -g -Wall -Wextra #-Werror
|
||||
|
||||
|
||||
BUILD_DIR = ./build
|
||||
TARGET_EXEC = $(BUILD_DIR)/proxy
|
||||
|
||||
top_srcdir = .
|
||||
|
||||
LIB_DIR = .
|
||||
SRC_DIR = ./src
|
||||
INC_DIRS = \
|
||||
$(SRC_DIR) \
|
||||
$(LIB_DIR)/open-nFAPI/nfapi/public_inc \
|
||||
$(LIB_DIR)/open-nFAPI/pnf_sim/inc \
|
||||
$(LIB_DIR)/open-nFAPI/nfapi/inc \
|
||||
$(LIB_DIR)/open-nFAPI/fapi/inc \
|
||||
$(LIB_DIR)/open-nFAPI/pnf/public_inc \
|
||||
$(LIB_DIR)/open-nFAPI/pnf/inc \
|
||||
$(LIB_DIR)/open-nFAPI/common/public_inc \
|
||||
$(LIB_DIR)/open-nFAPI/common/inc \
|
||||
$(LIB_DIR)/common \
|
||||
$(LIB_DIR)/common/utils \
|
||||
$(LIB_DIR)/common/utils/LOG \
|
||||
|
||||
LIB_SOURCES = \
|
||||
$(LIB_DIR)/open-nFAPI/nfapi/src/nfapi_p4.c \
|
||||
$(LIB_DIR)/open-nFAPI/nfapi/src/nfapi_p5.c \
|
||||
$(LIB_DIR)/open-nFAPI/nfapi/src/nfapi_p7.c \
|
||||
$(LIB_DIR)/open-nFAPI/fapi/src/nr_fapi.c \
|
||||
$(LIB_DIR)/open-nFAPI/fapi/src/nr_fapi_p5.c \
|
||||
$(LIB_DIR)/open-nFAPI/fapi/src/nr_fapi_p7.c \
|
||||
$(LIB_DIR)/open-nFAPI/fapi/src/nr_fapi_p7_utils.c \
|
||||
$(LIB_DIR)/open-nFAPI/pnf/src/pnf_interface.c \
|
||||
$(LIB_DIR)/open-nFAPI/pnf/src/pnf_p7_interface.c \
|
||||
$(LIB_DIR)/open-nFAPI/pnf/src/pnf.c \
|
||||
$(LIB_DIR)/open-nFAPI/pnf/src/pnf_p7.c \
|
||||
$(LIB_DIR)/open-nFAPI/common/src/debug.c \
|
||||
$(LIB_DIR)/open-nFAPI/common/src/nfapi.c \
|
||||
|
||||
SRCS = \
|
||||
$(SRC_DIR)/proxy.cc \
|
||||
$(SRC_DIR)/nr_proxy.cc \
|
||||
$(SRC_DIR)/nfapiutils.c \
|
||||
$(SRC_DIR)/nfapi_pnf.c \
|
||||
$(SRC_DIR)/queue.c \
|
||||
$(LIB_SOURCES)
|
||||
|
||||
OBJS := $(SRCS:%=$(BUILD_DIR)/%.o)
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
|
||||
INC_FLAGS := $(addprefix -I,$(INC_DIRS))
|
||||
|
||||
LDFLAGS = -pthread -lpthread -lz -lsctp -rdynamic
|
||||
|
||||
MKDIR_P ?= mkdir -p
|
||||
|
||||
$(TARGET_EXEC): $(OBJS)
|
||||
$(CXX) $(OBJS) -o $@ $(LDFLAGS)
|
||||
|
||||
# c source
|
||||
$(BUILD_DIR)/%.c.o: %.c
|
||||
$(MKDIR_P) $(dir $@)
|
||||
$(CC) $(INC_FLAGS) $(CFLAGS) -c $< -o $@
|
||||
|
||||
# c++ source
|
||||
$(BUILD_DIR)/%.cc.o: %.cc
|
||||
$(MKDIR_P) $(dir $@)
|
||||
$(CXX) $(INC_FLAGS) $(CXXFLAGS) -c $< -o $@
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
$(RM) -r $(BUILD_DIR)
|
||||
|
||||
-include $(DEPS)
|
||||
|
||||
# Run static analysis checks on Python scripts
|
||||
.PHONY: mypy
|
||||
mypy:
|
||||
python3 -m mypy proxy_testscript.py
|
||||
46
l2-fapi-proxy/README
Normal file
46
l2-fapi-proxy/README
Normal file
@@ -0,0 +1,46 @@
|
||||
# Description #
|
||||
|
||||
This directory contains the L2 FAPI Proxy server, which allows multiple UEs to communicate with an OAI gNB at Layer 2 of the stack.
|
||||
This makes it possible to bypass the L1 processing of the gNB/UE.
|
||||
The code is based off the original Multi-UE Proxy from EpiSci (located at <https://gitlab.eurecom.fr/oai/openairinterface5g>).
|
||||
The L2 Proxy and UE L2 Simulation (i.e., emulate-l1) Mode code has been updated based on the wk25 release of the OAI gNB and UE.
|
||||
Note that only NR Standalone (SA) Mode is currently supported with a single gNB.
|
||||
The updated feature is provided by Samsung Research America (SRA).
|
||||
|
||||
The high-level architecture and networking of the L2 Proxy and UE in L2 Simulation Mode is shown below.
|
||||
|
||||

|
||||
|
||||
## Included Features ##
|
||||
|
||||
The features included from the former EpiSci multi-UE proxy are:
|
||||
|
||||
- Socket communciation from/to nrUE(s)
|
||||
- Socket communication from/to gNB
|
||||
- Uplink/downlink packet queueing
|
||||
- nFAPI compatibility
|
||||
- Logging mechanism
|
||||
|
||||
Modifications made in the updated L2 FAPI Proxy/L2 Simulation Mode:
|
||||
|
||||
- Updated nFAPI messages and methods to the latest API version used by OAI (as of wk25)
|
||||
- Support for NR Standalone (SA) operation
|
||||
- Tested to support up to 50 UEs running on a single multi-core server in real-time
|
||||
- Downlink (PDSCH) PHY abstraction and error model based on CSI traces
|
||||
|
||||
** Note: Only NR Standalone (SA) Mode is currently supported with a single gNB. **
|
||||
|
||||
## L2 Simulation and PHY Abstraction ##
|
||||
|
||||

|
||||
|
||||
## Contact ##
|
||||
|
||||
For questions on the updated L2 FAPI Proxy, please contact:
|
||||
- Russell Ford <russelldford@gmail.com>
|
||||
- Daoud Burghal <d.burghal@samsung.com>
|
||||
- Pranav Madadi <p.madadi@samsung.com>
|
||||
|
||||
## Prerequsites ##
|
||||
|
||||
TODO
|
||||
46
l2-fapi-proxy/README.md
Normal file
46
l2-fapi-proxy/README.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# Description #
|
||||
|
||||
This directory contains the L2 FAPI Proxy server, which allows multiple UEs to communicate with an OAI gNB at Layer 2 of the stack.
|
||||
This makes it possible to bypass the L1 processing of the gNB/UE.
|
||||
The code is based off the original Multi-UE Proxy from EpiSci (located at <https://gitlab.eurecom.fr/oai/openairinterface5g>).
|
||||
The L2 Proxy and UE L2 Simulation (i.e., emulate-l1) Mode code has been updated based on the wk25 release of the OAI gNB and UE.
|
||||
Note that only NR Standalone (SA) Mode is currently supported with a single gNB.
|
||||
The updated feature is provided by Samsung Research America (SRA).
|
||||
|
||||
The high-level architecture and networking of the L2 Proxy and UE in L2 Simulation Mode is shown below.
|
||||
|
||||

|
||||
|
||||
## Included Features ##
|
||||
|
||||
The features included from the former EpiSci multi-UE proxy are:
|
||||
|
||||
- Socket communciation from/to nrUE(s)
|
||||
- Socket communication from/to gNB
|
||||
- Uplink/downlink packet queueing
|
||||
- nFAPI compatibility
|
||||
- Logging mechanism
|
||||
|
||||
Modifications made in the updated L2 FAPI Proxy/L2 Simulation Mode:
|
||||
|
||||
- Updated nFAPI messages and methods to the latest API version used by OAI (as of wk25)
|
||||
- Support for NR Standalone (SA) operation
|
||||
- Tested to support up to 50 UEs running on a single multi-core server in real-time
|
||||
- Downlink (PDSCH) PHY abstraction and error model based on CSI traces
|
||||
|
||||
** Note: Only NR Standalone (SA) Mode is currently supported with a single gNB. **
|
||||
|
||||
## L2 Simulation and PHY Abstraction ##
|
||||
|
||||

|
||||
|
||||
## Contact ##
|
||||
|
||||
For questions on the updated L2 FAPI Proxy, please contact:
|
||||
- Russell Ford <russelldford@gmail.com>
|
||||
- Daoud Burghal <d.burghal@samsung.com>
|
||||
- Pranav Madadi <p.madadi@samsung.com>
|
||||
|
||||
## Prerequsites ##
|
||||
|
||||
TODO
|
||||
329
l2-fapi-proxy/common/platform_types.h
Normal file
329
l2-fapi-proxy/common/platform_types.h
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.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
|
||||
*/
|
||||
|
||||
/*
|
||||
platform_types.h
|
||||
-------------------
|
||||
AUTHOR : Lionel GAUTHIER
|
||||
COMPANY : EURECOM
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr
|
||||
|
||||
***************************************************************************/
|
||||
#ifndef __PLATFORM_TYPES_H__
|
||||
#define __PLATFORM_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GENERIC ACCESS STRATUM TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef int32_t sdu_size_t;
|
||||
typedef uint32_t frame_t;
|
||||
typedef int32_t sframe_t;
|
||||
typedef uint32_t sub_frame_t;
|
||||
typedef uint32_t slot_t;
|
||||
typedef uint16_t module_id_t;
|
||||
typedef uint8_t slice_id_t;
|
||||
typedef uint8_t eNB_index_t;
|
||||
typedef uint64_t ue_id_t;
|
||||
typedef int16_t smodule_id_t;
|
||||
typedef long rb_id_t;
|
||||
typedef long srb_id_t;
|
||||
|
||||
typedef bool MBMS_flag_t;
|
||||
#define MBMS_FLAG_NO false
|
||||
#define MBMS_FLAG_YES true
|
||||
|
||||
typedef bool eNB_flag_t;
|
||||
#define ENB_FLAG_NO false
|
||||
#define ENB_FLAG_YES true
|
||||
|
||||
typedef bool gNB_flag_t;
|
||||
#define GNB_FLAG_NO false
|
||||
#define GNB_FLAG_YES true
|
||||
|
||||
typedef bool srb_flag_t;
|
||||
#define SRB_FLAG_NO false
|
||||
#define SRB_FLAG_YES true
|
||||
|
||||
typedef bool sl_discovery_flag_t;
|
||||
#define SL_DISCOVERY_FLAG_NO false
|
||||
#define SL_DISCOVERY_FLAG_YES true
|
||||
|
||||
typedef enum {
|
||||
TDD = 1,
|
||||
FDD = 0
|
||||
} frame_type_t;
|
||||
|
||||
typedef enum link_direction_e { UNKNOWN_DIR = 0, DIR_UPLINK = 1, DIR_DOWNLINK = 2 } link_direction_t;
|
||||
|
||||
typedef enum rb_type_e { UNKNOWN_RADIO_BEARER = 0, SIGNALLING_RADIO_BEARER = 1, RADIO_ACCESS_BEARER = 2 } rb_type_t;
|
||||
|
||||
typedef enum { CR_ROUND = 0, CR_SRB12 = 1, CR_HOL = 2, CR_LC = 3, CR_CQI = 4, CR_LCP = 5, CR_NUM = 6 } sorting_criterion_t;
|
||||
|
||||
typedef enum { POL_FAIR = 0, POL_GREEDY = 1, POL_NUM = 2 } accounting_policy_t;
|
||||
//-----------------------------------------------------------------------------
|
||||
// PHY TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef uint8_t crc8_t;
|
||||
typedef uint16_t crc16_t;
|
||||
typedef uint32_t crc32_t;
|
||||
typedef unsigned int crc_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MAC TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef sdu_size_t tbs_size_t;
|
||||
typedef sdu_size_t tb_size_t;
|
||||
typedef unsigned int logical_chan_id_t;
|
||||
typedef unsigned int num_tb_t;
|
||||
typedef uint8_t mac_enb_index_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RLC TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef unsigned int mui_t;
|
||||
typedef unsigned int confirm_t;
|
||||
typedef unsigned int rlc_tx_status_t;
|
||||
typedef int16_t rlc_sn_t;
|
||||
typedef uint16_t rlc_usn_t;
|
||||
typedef int32_t rlc_buffer_occupancy_t;
|
||||
typedef signed int rlc_op_status_t;
|
||||
|
||||
typedef enum rlc_mode_e { RLC_MODE_NONE = 0, RLC_MODE_AM = 1, RLC_MODE_UM = 2, RLC_MODE_TM = 4 } rlc_mode_t;
|
||||
|
||||
/*! \struct mac_rlc_status_resp_t
|
||||
* \brief Primitive exchanged between RLC and MAC informing about the buffer occupancy of the RLC protocol instance.
|
||||
*/
|
||||
typedef struct {
|
||||
rlc_buffer_occupancy_t bytes_in_buffer; /*!< \brief Bytes buffered in RLC protocol instance. */
|
||||
rlc_buffer_occupancy_t pdus_in_buffer; /*!< \brief Number of PDUs buffered in RLC protocol instance (OBSOLETE). */
|
||||
frame_t head_sdu_creation_time; /*!< \brief Head SDU creation time. */
|
||||
sdu_size_t head_sdu_remaining_size_to_send; /*!< \brief remaining size of sdu: could be the total size or the remaining size of
|
||||
already segmented sdu */
|
||||
bool head_sdu_is_segmented; /*!< \brief 0 if head SDU has not been segmented, 1 if already segmented */
|
||||
} mac_rlc_status_resp_t;
|
||||
|
||||
#define SDU_CONFIRM_NO false
|
||||
#define SDU_CONFIRM_YES true
|
||||
//-----------------------------------------------------------------------------
|
||||
// PDCP TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef uint16_t pdcp_sn_t;
|
||||
typedef uint32_t pdcp_hfn_t;
|
||||
typedef int16_t pdcp_hfn_offset_t;
|
||||
|
||||
typedef enum pdcp_transmission_mode_e {
|
||||
PDCP_TRANSMISSION_MODE_UNKNOWN = 0,
|
||||
PDCP_TRANSMISSION_MODE_CONTROL = 1,
|
||||
PDCP_TRANSMISSION_MODE_DATA = 2,
|
||||
PDCP_TRANSMISSION_MODE_TRANSPARENT = 3
|
||||
} pdcp_transmission_mode_t;
|
||||
//-----------------------------------------------------------------------------
|
||||
// IP DRIVER / PDCP TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef uint16_t tcp_udp_port_t;
|
||||
typedef enum ip_traffic_type_e {
|
||||
TRAFFIC_IPVX_TYPE_UNKNOWN = 0,
|
||||
TRAFFIC_IPV6_TYPE_UNICAST = 1,
|
||||
TRAFFIC_IPV6_TYPE_MULTICAST = 2,
|
||||
TRAFFIC_IPV6_TYPE_UNKNOWN = 3,
|
||||
TRAFFIC_IPV4_TYPE_UNICAST = 5,
|
||||
TRAFFIC_IPV4_TYPE_MULTICAST = 6,
|
||||
TRAFFIC_IPV4_TYPE_BROADCAST = 7,
|
||||
TRAFFIC_IPV4_TYPE_UNKNOWN = 8,
|
||||
TRAFFIC_PC5S_SIGNALLING = 9,
|
||||
TRAFFIC_PC5S_SESSION_INIT = 10
|
||||
} ip_traffic_type_t;
|
||||
|
||||
typedef enum {
|
||||
PDCCH_AGG_LEVEL1 = 0,
|
||||
PDCCH_AGG_LEVEL2,
|
||||
PDCCH_AGG_LEVEL4,
|
||||
PDCCH_AGG_LEVEL8,
|
||||
PDCCH_AGG_LEVEL16,
|
||||
NUM_PDCCH_AGG_LEVELS
|
||||
} Pdcch_Aggregation_Level_t;
|
||||
|
||||
typedef struct net_ip_address_s {
|
||||
unsigned ipv4: 1;
|
||||
unsigned ipv6: 1;
|
||||
char ipv4_address[16];
|
||||
char ipv6_address[46];
|
||||
} net_ip_address_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RRC TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef uint32_t mbms_session_id_t;
|
||||
typedef uint16_t mbms_service_id_t;
|
||||
typedef uint16_t rnti_t;
|
||||
typedef uint8_t rrc_enb_index_t;
|
||||
typedef uint8_t mme_code_t;
|
||||
typedef uint32_t m_tmsi_t;
|
||||
|
||||
// Random UE identity length = 40 bits
|
||||
#define NOT_A_RANDOM_UE_IDENTITY (uint64_t)0xFFFFFFFF
|
||||
#define NOT_A_RNTI (rnti_t)0
|
||||
#define M_RNTI (rnti_t)0xFFFD
|
||||
#define P_RNTI (rnti_t)0xFFFE
|
||||
#define SI_RNTI (rnti_t)0xFFFF
|
||||
#define CBA_RNTI (rnti_t)0xfff4
|
||||
#define OAI_C_RNTI (rnti_t)0x1234
|
||||
typedef enum config_action_e {
|
||||
CONFIG_ACTION_NULL = 0,
|
||||
CONFIG_ACTION_ADD = 1,
|
||||
CONFIG_ACTION_REMOVE = 2,
|
||||
CONFIG_ACTION_MODIFY = 3,
|
||||
CONFIG_ACTION_SET_SECURITY_MODE = 4,
|
||||
CONFIG_ACTION_MBMS_ADD = 10,
|
||||
CONFIG_ACTION_MBMS_MODIFY = 11
|
||||
} config_action_t;
|
||||
|
||||
/* Maximum size of any message we might send or receive (e.g., via a socket) */
|
||||
#define MAX_MESSAGE_SIZE 8192
|
||||
|
||||
typedef struct nsa_msg_t {
|
||||
uint8_t msg_type;
|
||||
uint8_t msg_buffer[MAX_MESSAGE_SIZE];
|
||||
} nsa_msg_t;
|
||||
|
||||
typedef enum nr_lcid_rb_type { NR_LCID_NONE = 0, NR_LCID_SRB = 1, NR_LCID_DRB = 2 } nr_lcid_rb_type;
|
||||
|
||||
typedef struct nr_lcid_rb_t {
|
||||
nr_lcid_rb_type type;
|
||||
union {
|
||||
int srb_id;
|
||||
int drb_id;
|
||||
} choice;
|
||||
} nr_lcid_rb_t;
|
||||
|
||||
typedef struct transport_layer_addr_s {
|
||||
/**
|
||||
* Transport Layer Address as a bitstring:
|
||||
* - 32 bits for IPv4 (RFC 791),
|
||||
* - 128 bits for IPv6 (RFC 2460),
|
||||
* - 160 bits for both IPv4 and IPv6, with IPv4 in the first 32 bits.
|
||||
* The S1AP/NGAP layer forwards this address (bitstring<1..160>)
|
||||
* to S1-U/NG-U without interpreting it.
|
||||
*/
|
||||
uint8_t length;
|
||||
/// Buffer: address in network byte order
|
||||
uint8_t buffer[20];
|
||||
} transport_layer_addr_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GTPV1U TYPES
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef uint32_t teid_t; // tunnel endpoint identifier
|
||||
typedef uint8_t ebi_t; // eps bearer id
|
||||
typedef uint8_t pdusessionid_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// may be ITTI not enabled, but type instance is useful also for OTG,
|
||||
typedef intptr_t instance_t;
|
||||
|
||||
typedef struct protocol_ctxt_s {
|
||||
module_id_t module_id; /*!< \brief Virtualized module identifier */
|
||||
eNB_flag_t enb_flag; /*!< \brief Flag to indicate eNB (1) or UE (0) */
|
||||
instance_t instance; /*!< \brief ITTI or OTG module identifier */
|
||||
ue_id_t rntiMaybeUEid;
|
||||
frame_t frame; /*!< \brief LTE frame number.*/
|
||||
sub_frame_t subframe; /*!< \brief LTE sub frame number.*/
|
||||
eNB_index_t eNB_index; /*!< \brief valid for UE indicating the index of connected eNB(s) */
|
||||
bool brOption;
|
||||
} protocol_ctxt_t;
|
||||
// warning time hardcoded
|
||||
#define PROTOCOL_CTXT_TIME_MILLI_SECONDS(CtXt_h) ((CtXt_h)->frame * 10 + (CtXt_h)->subframe)
|
||||
|
||||
#define UE_MODULE_ID_TO_INSTANCE(mODULE_iD) mODULE_iD + RC.nb_inst
|
||||
#define ENB_MODULE_ID_TO_INSTANCE(mODULE_iD) mODULE_iD
|
||||
#define UE_INSTANCE_TO_MODULE_ID(iNSTANCE) iNSTANCE - RC.nb_inst
|
||||
#define ENB_INSTANCE_TO_MODULE_ID(iNSTANCE) iNSTANCE
|
||||
|
||||
// NR
|
||||
#define GNB_MODULE_ID_TO_INSTANCE(mODULE_iD) mODULE_iD
|
||||
|
||||
#define MODULE_ID_TO_INSTANCE(mODULE_iD, iNSTANCE, eNB_fLAG) \
|
||||
do { \
|
||||
iNSTANCE = eNB_fLAG == ENB_FLAG_YES ? ENB_MODULE_ID_TO_INSTANCE(mODULE_iD) : UE_MODULE_ID_TO_INSTANCE(mODULE_iD); \
|
||||
} while (0)
|
||||
|
||||
#define INSTANCE_TO_MODULE_ID(iNSTANCE, mODULE_iD, eNB_fLAG) \
|
||||
do { \
|
||||
mODULE_iD = eNB_fLAG == ENB_FLAG_YES ? ENB_INSTANCE_TO_MODULE_ID(iNSTANCE) : UE_INSTANCE_TO_MODULE_ID(iNSTANCE); \
|
||||
} while (0)
|
||||
|
||||
#define PROTOCOL_CTXT_COMPUTE_MODULE_ID(CtXt_h) INSTANCE_TO_MODULE_ID((CtXt_h)->instance, (CtXt_h)->module_id, (CtXt_h)->enb_flag)
|
||||
|
||||
#define PROTOCOL_CTXT_COMPUTE_INSTANCE(CtXt_h) MODULE_ID_TO_INSTANCE((CtXt_h)->module_id, (CtXt_h)->instance, (CtXt_h)->enb_flag)
|
||||
|
||||
#define PROTOCOL_CTXT_SET_BY_MODULE_ID(Ctxt_Pp, mODULE_iD, eNB_fLAG, rNTI, fRAME, sUBfRAME, eNB_iNDEX) \
|
||||
do { \
|
||||
(Ctxt_Pp)->module_id = mODULE_iD; \
|
||||
(Ctxt_Pp)->enb_flag = eNB_fLAG; \
|
||||
(Ctxt_Pp)->rntiMaybeUEid = rNTI; \
|
||||
(Ctxt_Pp)->frame = fRAME; \
|
||||
(Ctxt_Pp)->subframe = sUBfRAME; \
|
||||
(Ctxt_Pp)->eNB_index = eNB_iNDEX; \
|
||||
(Ctxt_Pp)->brOption = false; /* set a default value */ \
|
||||
PROTOCOL_CTXT_COMPUTE_INSTANCE(Ctxt_Pp); \
|
||||
} while (0)
|
||||
|
||||
#define PROTOCOL_CTXT_SET_BY_INSTANCE(Ctxt_Pp, iNSTANCE, eNB_fLAG, rNTI, fRAME, sUBfRAME) \
|
||||
do { \
|
||||
(Ctxt_Pp)->instance = iNSTANCE; \
|
||||
(Ctxt_Pp)->enb_flag = eNB_fLAG; \
|
||||
(Ctxt_Pp)->rntiMaybeUEid = rNTI; \
|
||||
(Ctxt_Pp)->frame = fRAME; \
|
||||
(Ctxt_Pp)->subframe = sUBfRAME; \
|
||||
(Ctxt_Pp)->eNB_index = 0; /* set a default value */ \
|
||||
(Ctxt_Pp)->brOption = false; /* set a default value */ \
|
||||
PROTOCOL_CTXT_COMPUTE_MODULE_ID(Ctxt_Pp); \
|
||||
} while (0)
|
||||
|
||||
#define PROTOCOL_CTXT_FMT "[FRAME %05u][%s][MOD %02d][RNTI %" PRIx64 "]"
|
||||
#define PROTOCOL_CTXT_ARGS(CTXT_Pp) \
|
||||
(CTXT_Pp)->frame, ((CTXT_Pp)->enb_flag == ENB_FLAG_YES) ? "eNB" : " UE", (CTXT_Pp)->module_id, (CTXT_Pp)->rntiMaybeUEid
|
||||
|
||||
#define PROTOCOL_NR_CTXT_ARGS(CTXT_Pp) \
|
||||
(CTXT_Pp)->frame, ((CTXT_Pp)->enb_flag == GNB_FLAG_YES) ? "gNB" : " UE", (CTXT_Pp)->module_id, (CTXT_Pp)->rntiMaybeUEid
|
||||
|
||||
#define CHECK_CTXT_ARGS(CTXT_Pp)
|
||||
|
||||
|
||||
static inline int ceil_mod(const unsigned int v, const unsigned int mod)
|
||||
{
|
||||
return ((v + mod - 1) / mod) * mod;
|
||||
}
|
||||
|
||||
#define exit_fun(msg) exit_function(__FILE__, __FUNCTION__, __LINE__, "exit_fun", OAI_EXIT_NORMAL)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
1071
l2-fapi-proxy/common/utils/LOG/log.c
Normal file
1071
l2-fapi-proxy/common/utils/LOG/log.c
Normal file
File diff suppressed because it is too large
Load Diff
601
l2-fapi-proxy/common/utils/LOG/log.h
Normal file
601
l2-fapi-proxy/common/utils/LOG/log.h
Normal file
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
* 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 log.h
|
||||
* \brief openair log generator (OLG) for
|
||||
* \author Navid Nikaein
|
||||
* \date 2009 - 2014
|
||||
* \version 0.5
|
||||
* @ingroup util
|
||||
*/
|
||||
|
||||
#ifndef __LOG_H__
|
||||
#define __LOG_H__
|
||||
|
||||
/*--- INCLUDES ---------------------------------------------------------------*/
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <stdint.h>
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
#include <inttypes.h>
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
// #include <common/utils/utils.h>
|
||||
#include <utils.h>
|
||||
#if ENABLE_LTTNG
|
||||
#include "lttng-log.h"
|
||||
#endif
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#include <assert.h>
|
||||
#ifdef NDEBUG
|
||||
#warning assert is disabled
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @}*/
|
||||
|
||||
/** @defgroup _log_level Message levels defined by LOG
|
||||
* @ingroup _macro
|
||||
* @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8
|
||||
* @{*/
|
||||
# define OAILOG_DISABLE -1 /*!< \brief disable all LOG messages, cannot be used in LOG macros, use only in LOG module */
|
||||
# define OAILOG_ERR 0 /*!< \brief critical error conditions, impact on "must have" functionalities */
|
||||
# define OAILOG_WARNING 1 /*!< \brief warning conditions, shouldn't happen but doesn't impact "must have" functionalities */
|
||||
# define OAILOG_ANALYSIS 2 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */
|
||||
# define OAILOG_INFO 3 /*!< \brief informational messages most people don't need, shouldn't impact real-time behavior */
|
||||
# define OAILOG_DEBUG 4 /*!< \brief first level debug-level messages, for developers, may impact real-time behavior */
|
||||
# define OAILOG_TRACE 5 /*!< \brief second level debug-level messages, for developers, likely impact real-time behavior*/
|
||||
|
||||
#define NUM_LOG_LEVEL 6 /*!< \brief the number of message levels users have with LOG (OAILOG_DISABLE is not available to user as a level, so it is not included)*/
|
||||
/** @}*/
|
||||
|
||||
#define SET_LOG_OPTION(O) g_log->flag = (g_log->flag | O)
|
||||
#define CLEAR_LOG_OPTION(O) g_log->flag = (g_log->flag & (~O))
|
||||
|
||||
/** @defgroup macros to identify a debug entity
|
||||
* @ingroup each macro is a bit mask where the unique bit set identifies an entity to be debugged
|
||||
* it allows to dynamically activate or not blocks of code. The LOG_MASKMAP_INIT macro
|
||||
* is used to map a character string name to each debug bit, it allows to set or clear
|
||||
* the corresponding bit via the defined name, from the configuration or from the telnet
|
||||
* server.
|
||||
* @brief
|
||||
* @{*/
|
||||
|
||||
#define FOREACH_FLAG(FLAG_DEF) \
|
||||
FLAG_DEF(PRACH) \
|
||||
FLAG_DEF(UE_PHYPROC) \
|
||||
FLAG_DEF(LTEESTIM) \
|
||||
FLAG_DEF(DLCELLSPEC) \
|
||||
FLAG_DEF(ULSCH) \
|
||||
FLAG_DEF(RRC) \
|
||||
FLAG_DEF(PDCP) \
|
||||
FLAG_DEF(DFT) \
|
||||
FLAG_DEF(ASN1) \
|
||||
FLAG_DEF(CTRLSOCKET) \
|
||||
FLAG_DEF(SECURITY) \
|
||||
FLAG_DEF(NAS) \
|
||||
FLAG_DEF(DLSCH_DECOD) \
|
||||
FLAG_DEF(UE_TIMING) \
|
||||
FLAG_DEF(F1AP)
|
||||
|
||||
#define FLAG_BITF(flag) uint64_t DEBUG_##flag: 1;
|
||||
typedef struct {
|
||||
FOREACH_FLAG(FLAG_BITF)
|
||||
} debug_flags_t;
|
||||
|
||||
#define FLAG_TEXT(flag) #flag,
|
||||
static const char *const flag_name[] = {FOREACH_FLAG(FLAG_TEXT) ""};
|
||||
|
||||
#define SET_LOG_DEBUG(B) g_log->debug_mask.B = true
|
||||
#define CLEAR_LOG_DEBUG(B) g_log->debug_mask.B = false
|
||||
|
||||
#define SET_LOG_DUMP(B) g_log->dump_mask.B = true
|
||||
#define CLEAR_LOG_DUMP(B) g_log->dump_mask.B = false
|
||||
|
||||
#define FOREACH_COMP(COMP_DEF) \
|
||||
COMP_DEF(PHY, log) \
|
||||
COMP_DEF(MAC, log) \
|
||||
COMP_DEF(EMU, log) \
|
||||
COMP_DEF(SIM, txt) \
|
||||
COMP_DEF(OMG, csv) \
|
||||
COMP_DEF(OPT, log) \
|
||||
COMP_DEF(OTG, log) \
|
||||
COMP_DEF(OTG_LATENCY, dat) \
|
||||
COMP_DEF(OTG_LATENCY_BG, dat) \
|
||||
COMP_DEF(OTG_GP, dat) \
|
||||
COMP_DEF(OTG_GP_BG, dat) \
|
||||
COMP_DEF(OTG_JITTER, dat) \
|
||||
COMP_DEF(RLC, ) \
|
||||
COMP_DEF(PDCP, ) \
|
||||
COMP_DEF(RRC, ) \
|
||||
COMP_DEF(NAS, log) \
|
||||
COMP_DEF(OIP, ) \
|
||||
COMP_DEF(CLI, ) \
|
||||
COMP_DEF(OCM, ) \
|
||||
COMP_DEF(GTPU, ) \
|
||||
COMP_DEF(SDAP, ) \
|
||||
COMP_DEF(SPGW, ) \
|
||||
COMP_DEF(S1AP, ) \
|
||||
COMP_DEF(F1AP, ) \
|
||||
COMP_DEF(E1AP, ) \
|
||||
COMP_DEF(SCTP, ) \
|
||||
COMP_DEF(HW, ) \
|
||||
COMP_DEF(OSA, ) \
|
||||
COMP_DEF(ENB_APP, log) \
|
||||
COMP_DEF(MCE_APP, log) \
|
||||
COMP_DEF(MME_APP, log) \
|
||||
COMP_DEF(TMR, ) \
|
||||
COMP_DEF(USIM, log) \
|
||||
COMP_DEF(F1U, ) \
|
||||
COMP_DEF(X2AP, ) \
|
||||
COMP_DEF(M2AP, ) \
|
||||
COMP_DEF(M3AP, ) \
|
||||
COMP_DEF(NGAP, ) \
|
||||
COMP_DEF(GNB_APP, log) \
|
||||
COMP_DEF(NR_RRC, log) \
|
||||
COMP_DEF(NR_MAC, log) \
|
||||
COMP_DEF(NR_MAC_DCI, log) \
|
||||
COMP_DEF(NR_PHY_DCI, log) \
|
||||
COMP_DEF(NR_PHY, log) \
|
||||
COMP_DEF(LOADER, log) \
|
||||
COMP_DEF(ASN1, log) \
|
||||
COMP_DEF(NFAPI_VNF, log) \
|
||||
COMP_DEF(NFAPI_PNF, log) \
|
||||
COMP_DEF(ITTI, log) \
|
||||
COMP_DEF(UTIL, log) \
|
||||
COMP_DEF(MAX_LOG_PREDEF_COMPONENTS, )
|
||||
|
||||
#define COMP_ENUM(comp, file_extension) comp,
|
||||
typedef enum { FOREACH_COMP(COMP_ENUM) } comp_name_t;
|
||||
|
||||
#define COMP_TEXT(comp, file_extension) #comp,
|
||||
static const char *const comp_name[] = {FOREACH_COMP(COMP_TEXT)};
|
||||
|
||||
#define COMP_EXTENSION(comp, file_extension) #file_extension,
|
||||
static const char *const comp_extension[] = {FOREACH_COMP(COMP_EXTENSION)};
|
||||
|
||||
#define MAX_LOG_DYNALLOC_COMPONENTS 20
|
||||
#define MAX_LOG_COMPONENTS (MAX_LOG_PREDEF_COMPONENTS + MAX_LOG_DYNALLOC_COMPONENTS)
|
||||
|
||||
typedef struct {
|
||||
char *name; /*!< \brief string name of item */
|
||||
int value; /*!< \brief integer value of mapping */
|
||||
} mapping;
|
||||
|
||||
typedef int(*log_vprint_func_t)(FILE *stream, const char *format, va_list ap );
|
||||
typedef int(*log_print_func_t)(FILE *stream, const char *format, ... );
|
||||
typedef struct {
|
||||
int savedlevel;
|
||||
char *filelog_name;
|
||||
} log_component_back_t;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int level;
|
||||
int filelog;
|
||||
FILE *stream;
|
||||
log_vprint_func_t vprint;
|
||||
log_print_func_t print;
|
||||
} log_component_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
log_component_t log_component[MAX_LOG_COMPONENTS];
|
||||
log_component_back_t log_rarely_used[MAX_LOG_COMPONENTS];
|
||||
char level2string[NUM_LOG_LEVEL];
|
||||
int flag;
|
||||
char *filelog_name;
|
||||
debug_flags_t debug_mask;
|
||||
debug_flags_t dump_mask;
|
||||
} log_t;
|
||||
|
||||
#ifdef LOG_MAIN
|
||||
log_t *g_log;
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern log_t *g_log;
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#define FLAG_DEBUG_SET(flag) \
|
||||
if (strcmp(name, #flag) == 0) { \
|
||||
g_log->debug_mask.DEBUG_##flag = val; \
|
||||
return true; \
|
||||
};
|
||||
static inline bool set_log_debug(char *name, bool val)
|
||||
{
|
||||
FOREACH_FLAG(FLAG_DEBUG_SET);
|
||||
printf("Error: setting log debug of %s option, not existing\n", name);
|
||||
return false;
|
||||
}
|
||||
#define FLAG_DUMP_SET(flag) \
|
||||
if (strcmp(name, #flag) == 0) { \
|
||||
g_log->dump_mask.DEBUG_##flag = val; \
|
||||
return true; \
|
||||
};
|
||||
static inline bool set_log_dump(char *name, bool val)
|
||||
{
|
||||
FOREACH_FLAG(FLAG_DUMP_SET);
|
||||
printf("Error: setting log dump of %s option, not existing\n", name);
|
||||
return false;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
int logInit (void);
|
||||
void logTerm (void);
|
||||
int isLogInitDone (void);
|
||||
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
|
||||
void vlogRecord_mt(const char *file, const char *func, int line, int comp, int level, const char *format, va_list args );
|
||||
#if ENABLE_LTTNG
|
||||
void logRecord_lttng(const char *file, const char *func, int line, int comp, int level, const char *format, ...)
|
||||
__attribute__((format(printf, 6, 7)));
|
||||
#endif
|
||||
void log_dump(int component, void *buffer, int buffsize,int datatype, const char *format, ... );
|
||||
int set_log(int component, int level);
|
||||
void set_glog(int level);
|
||||
|
||||
mapping * log_level_names_ptr(void);
|
||||
mapping * log_option_names_ptr(void);
|
||||
mapping * log_maskmap_ptr(void);
|
||||
void set_glog_onlinelog(int enable);
|
||||
void set_glog_filelog(int enable);
|
||||
void set_component_filelog(int comp);
|
||||
void close_component_filelog(int comp);
|
||||
void set_component_consolelog(int comp);
|
||||
int map_str_to_int(const mapping *map, const char *str);
|
||||
char *map_int_to_str(const mapping *map, const int val);
|
||||
void logClean (void);
|
||||
|
||||
int register_log_component(const char *name, const char *fext, int compidx);
|
||||
|
||||
int logInit_log_mem(char*);
|
||||
void close_log_mem(void);
|
||||
|
||||
/** @}*/
|
||||
|
||||
/*!\fn int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, char format);
|
||||
\brief Write output file from signal data
|
||||
@param fname output file name
|
||||
@param vname output vector name (for MATLAB/OCTAVE)
|
||||
@param data point to data
|
||||
@param length length of data vector to output
|
||||
@param dec decimation level
|
||||
@param format data format (0 = real 16-bit, 1 = complex 16-bit,2 real 32-bit, 3 complex 32-bit,4 = real 8-bit, 5 = complex 8-bit)
|
||||
@param multiVec create new file or append to existing (useful for writing multiple vectors to same file. Just call the function multiple times with same file name and with this parameter set to 1)
|
||||
*/
|
||||
#define MATLAB_RAW (1U<<31)
|
||||
#define MATLAB_SHORT 0
|
||||
#define MATLAB_CSHORT 1
|
||||
#define MATLAB_INT 2
|
||||
#define MATLAB_CINT 3
|
||||
#define MATLAB_INT8 4
|
||||
#define MATLAB_CINT8 5
|
||||
#define MATLAB_LLONG 6
|
||||
#define MATLAB_DOUBLE 7
|
||||
#define MATLAB_CDOUBLE 8
|
||||
#define MATLAB_UINT8 9
|
||||
#define MATLEB_EREN1 10
|
||||
#define MATLEB_EREN2 11
|
||||
#define MATLEB_EREN3 12
|
||||
#define MATLAB_CSHORT_BRACKET1 13
|
||||
#define MATLAB_CSHORT_BRACKET2 14
|
||||
#define MATLAB_CSHORT_BRACKET3 15
|
||||
|
||||
int32_t write_file_matlab(const char *fname, const char *vname, void *data, int length, int dec, unsigned int format, int multiVec);
|
||||
#define write_output(a, b, c, d, e, f) write_file_matlab(a, b, c, d, e, f, 0)
|
||||
|
||||
/*----------------macro definitions for reading log configuration from the config module */
|
||||
#define CONFIG_STRING_LOG_PREFIX "log_config"
|
||||
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL "global_log_level"
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE "global_log_online"
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_INFILE "global_log_infile"
|
||||
#define LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS "global_log_options"
|
||||
|
||||
#define LOG_CONFIG_LEVEL_FORMAT "%s_log_level"
|
||||
#define LOG_CONFIG_LOGFILE_FORMAT "%s_log_infile"
|
||||
#define LOG_CONFIG_DEBUG_FORMAT "%s_debug"
|
||||
#define LOG_CONFIG_DUMP_FORMAT "%s_dump"
|
||||
|
||||
#define LOG_CONFIG_HELP_OPTIONS " list of comma separated options to enable log module behavior. Available options: \n"\
|
||||
" nocolor: disable color usage in log messages\n"\
|
||||
" level: add log level indication in log messages\n"\
|
||||
" thread: add threads names in log messages\n"
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* LOG global configuration parameters */
|
||||
/* optname help paramflags XXXptr defXXXval type numelt */
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
// clang-format off
|
||||
#define LOG_GLOBALPARAMS_DESC { \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_LEVEL, "Default log level for all componemts\n", 0, .strptr=&gloglevel, .defstrval=log_level_names[3].name, TYPE_STRING, 0}, \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_ONLINE, "Default console output option, for all components\n", 0, .iptr=&(consolelog), .defintval=1, TYPE_INT, 0}, \
|
||||
{LOG_CONFIG_STRING_GLOBAL_LOG_OPTIONS, LOG_CONFIG_HELP_OPTIONS, 0, .strlistptr=NULL, .defstrlistval=NULL, TYPE_STRINGLIST, 0}, \
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
#define LOG_OPTIONS_IDX 2
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
/** @defgroup _debugging debugging macros
|
||||
* @ingroup _macro
|
||||
* @brief Macro used to call logIt function with different message levels
|
||||
* @{*/
|
||||
#define LOG_DUMP_CHAR 0
|
||||
#define LOG_DUMP_DOUBLE 1
|
||||
#define LOG_DUMP_I16 2
|
||||
#define LOG_DUMP_C16 3
|
||||
#define LOG_DUMP_C32 4
|
||||
// debugging macros
|
||||
#define LOG_F LOG_I /* because LOG_F was originaly to dump a message or buffer but is also used as a regular level...., to dump use LOG_DUMPMSG */
|
||||
|
||||
# if T_TRACER
|
||||
#include "T.h"
|
||||
/* per component, level dependent macros */
|
||||
#define LOG_E(c, x...) \
|
||||
do { \
|
||||
T(T_LEGACY_##c##_ERROR, T_PRINTF(x)); \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ERR) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ERR, x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_W(c, x...) \
|
||||
do { \
|
||||
T(T_LEGACY_##c##_WARNING, T_PRINTF(x)); \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= OAILOG_WARNING) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_WARNING, x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_A(c, x...) \
|
||||
do { \
|
||||
T(T_LEGACY_##c##_INFO, T_PRINTF(x)); \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ANALYSIS) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ANALYSIS, x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_I(c, x...) \
|
||||
do { \
|
||||
T(T_LEGACY_##c##_INFO, T_PRINTF(x)); \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= OAILOG_INFO) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_INFO, x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_D(c, x...) \
|
||||
do { \
|
||||
T(T_LEGACY_##c##_DEBUG, T_PRINTF(x)); \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_DEBUG, x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_DDUMP(c, b, s, f, x...) \
|
||||
do { \
|
||||
T(T_LEGACY_##c##_DEBUG, T_PRINTF(x)); \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) \
|
||||
log_dump(c, b, s, f, x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_T(c, x...) \
|
||||
do { \
|
||||
T(T_LEGACY_##c##_TRACE, T_PRINTF(x)); \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= OAILOG_TRACE) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define VLOG(c, l, f, args) \
|
||||
do { \
|
||||
if (T_stdout) { \
|
||||
if (g_log->log_component[c].level >= l) \
|
||||
vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, l, f, args); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* macro used to dump a buffer or a message as in openair2/RRC/LTE/RRC_eNB.c, replaces LOG_F macro */
|
||||
#define LOG_DUMPMSG(c, f, b, s, x...) \
|
||||
do { \
|
||||
if (g_log->dump_mask.f) \
|
||||
log_dump(c, b, s, LOG_DUMP_CHAR, x); \
|
||||
} while (0)
|
||||
|
||||
/* bitmask dependent macros, to isolate debugging code */
|
||||
#define LOG_DEBUGFLAG(D) (g_log->debug_mask.D)
|
||||
|
||||
/* bitmask dependent macros, to generate debug file such as matlab file or message dump */
|
||||
#define LOG_DUMPFLAG(D) (g_log->dump_mask.D)
|
||||
|
||||
#define LOG_M(file, vector, data, len, dec, format) \
|
||||
do { \
|
||||
write_file_matlab(file, vector, data, len, dec, format, 0); \
|
||||
} while (0)
|
||||
|
||||
/* define variable only used in LOG macro's */
|
||||
#define LOG_VAR(A, B) A B
|
||||
#else /* T_TRACER */
|
||||
#if ENABLE_LTTNG
|
||||
#define LOG_E(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ERR) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ERR, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_W(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_WARNING) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_WARNING, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_A(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ANALYSIS) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ANALYSIS, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_I(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_INFO) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_INFO, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_D(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_DEBUG, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_T(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_TRACE) { \
|
||||
logRecord_lttng(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \
|
||||
} \
|
||||
} while (0)
|
||||
#define LOG_DDUMP(c, b, s, f, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) \
|
||||
log_dump(c, b, s, f, x); \
|
||||
} while (0)
|
||||
#else
|
||||
#define LOG_E(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ERR) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ERR, x); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_W(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_WARNING) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_WARNING, x); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_A(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_ANALYSIS) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_ANALYSIS, x); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_I(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_INFO) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_INFO, x); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_D(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_DEBUG, x); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_DDUMP(c, b, s, f, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_DEBUG) \
|
||||
log_dump(c, b, s, f, x); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_T(c, x...) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= OAILOG_TRACE) \
|
||||
logRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, OAILOG_TRACE, x); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define VLOG(c, l, f, args) \
|
||||
do { \
|
||||
if (g_log->log_component[c].level >= l) \
|
||||
vlogRecord_mt(__FILE__, __FUNCTION__, __LINE__, c, l, f, args); \
|
||||
} while (0)
|
||||
|
||||
#define nfapi_log(FILE, FNC, LN, COMP, LVL, FMT...)
|
||||
#define LOG_DEBUGFLAG(D) (g_log->debug_mask.D)
|
||||
#define LOG_DUMPFLAG(D) (g_log->dump_mask.D)
|
||||
#define LOG_DUMPMSG(c, f, b, s, x...) \
|
||||
do { \
|
||||
if (g_log->dump_mask.f) \
|
||||
log_dump(c, b, s, LOG_DUMP_CHAR, x); \
|
||||
} while (0) /* */
|
||||
|
||||
#define LOG_M(file, vector, data, len, dec, format) \
|
||||
do { \
|
||||
write_file_matlab(file, vector, data, len, dec, format, 0); \
|
||||
} while (0)
|
||||
|
||||
#define LOG_VAR(A, B) A B
|
||||
#define T_ACTIVE(a) (0)
|
||||
|
||||
#endif /* T_TRACER */
|
||||
|
||||
/* avoid warnings for variables only used in LOG macro's but set outside debug section */
|
||||
#define GCC_NOTUSED __attribute__((unused))
|
||||
#define LOG_USEDINLOG_VAR(A,B) GCC_NOTUSED A B
|
||||
|
||||
/* unfiltered macros, useful for simulators or messages at init time, before log is configured */
|
||||
#define LOG_UM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 0);} while(0)
|
||||
#define LOG_UI(c, x...) do {logRecord_mt(__FILE__, __FUNCTION__, __LINE__,c, OAILOG_INFO, x) ; } while(0)
|
||||
#define LOG_UDUMPMSG(c, b, s, f, x...) do { log_dump(c, b, s, f, x) ;} while (0) /* */
|
||||
# define LOG_MM(file, vector, data, len, dec, format) do { write_file_matlab(file, vector, data, len, dec, format, 1);} while(0)
|
||||
/** @}*/
|
||||
|
||||
/** @defgroup _useful_functions useful functions in LOG
|
||||
* @ingroup _macro
|
||||
* @brief Macro of some useful functions defined by LOG
|
||||
* @{*/
|
||||
#define LOG_ENTER(c) do {LOG_T(c, "Entering %s\n",__FUNCTION__);}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */
|
||||
#define LOG_END(c) do {LOG_T(c, "End of %s\n",__FUNCTION__);}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */
|
||||
#define LOG_EXIT(c) do { LOG_END(c); return;}while(0) /*!< \brief Macro to log a message with severity TRACE when exiting a function */
|
||||
#define LOG_RETURN(c,r) do {LOG_T(c,"Leaving %s (rc = %08lx)\n", __FUNCTION__ , (unsigned long)(r) );return(r);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */
|
||||
|
||||
/** @}*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
90
l2-fapi-proxy/common/utils/assertions.h
Normal file
90
l2-fapi-proxy/common/utils/assertions.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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 __COMMON_UTILS_ASSERTIONS__H__
|
||||
#define __COMMON_UTILS_ASSERTIONS__H__
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
// #include "common/platform_types.h"
|
||||
#include "platform_types.h"
|
||||
|
||||
#define OAI_EXIT_NORMAL 0
|
||||
#define OAI_EXIT_ASSERT 1
|
||||
|
||||
#define _Assert_Exit_ \
|
||||
if (getenv("OAI_GDBSTACKS")) { \
|
||||
char tmp [1000]; \
|
||||
sprintf(tmp,"gdb -ex='set confirm off' -ex 'thread apply all bt' -ex q -p %d < /dev/null", getpid()); \
|
||||
__attribute__((unused)) int dummy=system(tmp); \
|
||||
} \
|
||||
fprintf(stderr, "\nExiting execution\n"); \
|
||||
fflush(stdout); \
|
||||
fflush(stderr); \
|
||||
exit_function(__FILE__, __FUNCTION__, __LINE__, "_Assert_Exit_", OAI_EXIT_ASSERT); \
|
||||
abort(); // to avoid gcc warnings - never executed unless app-specific exit_function() does not exit() nor abort()
|
||||
|
||||
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
|
||||
do { \
|
||||
if (!(cOND)) { \
|
||||
fprintf(stderr, "\nAssertion (%s) failed!\n" \
|
||||
"In %s() %s:%d\n" fORMAT, \
|
||||
#cOND, __FUNCTION__, __FILE__, __LINE__, ##aRGS); \
|
||||
aCTION; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define AssertFatal(cOND, fORMAT, aRGS...) _Assert_(cOND, _Assert_Exit_, fORMAT, ##aRGS)
|
||||
|
||||
#define AssertError(cOND, aCTION, fORMAT, aRGS...) _Assert_(cOND, aCTION, fORMAT, ##aRGS)
|
||||
|
||||
|
||||
|
||||
#define DevCheck(cOND, vALUE1, vALUE2, vALUE3) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1 ": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3)
|
||||
|
||||
#define DevCheck4(cOND, vALUE1, vALUE2, vALUE3, vALUE4) \
|
||||
_Assert_(cOND, _Assert_Exit_, #vALUE1": %" PRIdMAX "\n" #vALUE2 ": %" PRIdMAX "\n" #vALUE3 ": %" PRIdMAX "\n" #vALUE4 ": %" PRIdMAX "\n\n", \
|
||||
(intmax_t)vALUE1, (intmax_t)vALUE2, (intmax_t)vALUE3, (intmax_t)vALUE4)
|
||||
|
||||
#define DevParam(vALUE1, vALUE2, vALUE3) DevCheck(0, vALUE1, vALUE2, vALUE3)
|
||||
|
||||
#define DevAssert(cOND) _Assert_(cOND, _Assert_Exit_, "")
|
||||
|
||||
#define DevMessage(mESSAGE) _Assert_(0, _Assert_Exit_, #mESSAGE)
|
||||
|
||||
#define CHECK_INIT_RETURN(fCT) \
|
||||
do { \
|
||||
int fct_ret; \
|
||||
if ((fct_ret = (fCT)) != 0) { \
|
||||
fprintf(stderr, "Function "#fCT" has failed\n" \
|
||||
"returning %d\n", fct_ret); \
|
||||
fflush(stdout); \
|
||||
fflush(stderr); \
|
||||
exit(EXIT_FAILURE); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* __COMMON_UTILS_ASSERTIONS__H__ */
|
||||
137
l2-fapi-proxy/common/utils/utils.h
Normal file
137
l2-fapi-proxy/common/utils/utils.h
Normal file
@@ -0,0 +1,137 @@
|
||||
#ifndef _UTILS_H
|
||||
#define _UTILS_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/types.h>
|
||||
// #include <common/utils/assertions.h>
|
||||
#include <assertions.h>
|
||||
|
||||
#ifdef MALLOC_TRACE
|
||||
#define malloc myMalloc
|
||||
#endif
|
||||
|
||||
#define sizeofArray(a) (sizeof(a)/sizeof(*(a)))
|
||||
#define CHECK_INDEX(ARRAY, INDEX) assert((INDEX) < sizeofArray(ARRAY))
|
||||
|
||||
// Prevent double evaluation in max macro
|
||||
#define cmax(a,b) ({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a > _b ? _a : _b; })
|
||||
|
||||
|
||||
#define cmax3(a,b,c) ( cmax(cmax(a,b), c) )
|
||||
|
||||
// Prevent double evaluation in min macro
|
||||
#define cmin(a,b) ({ __typeof__ (a) _a = (a); \
|
||||
__typeof__ (b) _b = (b); \
|
||||
_a < _b ? _a : _b; })
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef min
|
||||
#undef min
|
||||
#undef max
|
||||
#endif
|
||||
#else
|
||||
#define max(a,b) cmax(a,b)
|
||||
#define min(a,b) cmin(a,b)
|
||||
#endif
|
||||
|
||||
#ifndef malloc16
|
||||
# define malloc16(x) memalign(32,x+32)
|
||||
#endif
|
||||
#define free16(y,x) free(y)
|
||||
#define bigmalloc malloc
|
||||
#define bigmalloc16 malloc16
|
||||
#define openair_free(y,x) free((y))
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
#define free_and_zero(PtR) do { \
|
||||
if (PtR) { \
|
||||
free(PtR); \
|
||||
PtR = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static inline void *malloc16_clear( size_t size ) {
|
||||
void *ptr = memalign(32, size+32);
|
||||
DevAssert(ptr);
|
||||
memset( ptr, 0, size );
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline void *calloc_or_fail(size_t nmemb, size_t size)
|
||||
{
|
||||
void *ptr = calloc(nmemb, size);
|
||||
|
||||
if (ptr == NULL) {
|
||||
fprintf(stderr, "Failed to calloc() %zu elements of %zu bytes: out of memory", nmemb, size);
|
||||
abort();
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static inline void *malloc_or_fail(size_t size)
|
||||
{
|
||||
void *ptr = malloc(size);
|
||||
|
||||
if (ptr == NULL) {
|
||||
fprintf(stderr, "Failed to malloc() %zu bytes: out of memory", size);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#if !defined (msg)
|
||||
# define msg(aRGS...) LOG_D(PHY, ##aRGS)
|
||||
#endif
|
||||
#ifndef malloc16
|
||||
# define malloc16(x) memalign(32,x)
|
||||
#endif
|
||||
|
||||
#define free16(y,x) free(y)
|
||||
#define bigmalloc malloc
|
||||
#define bigmalloc16 malloc16
|
||||
#define openair_free(y,x) free((y))
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
#define PAGE_MASK 0xfffff000
|
||||
#define virt_to_phys(x) (x)
|
||||
|
||||
// Converts an hexadecimal ASCII coded digit into its value. **
|
||||
int hex_char_to_hex_value (char c);
|
||||
// Converts an hexadecimal ASCII coded string into its value.**
|
||||
int hex_string_to_hex_value (uint8_t *hex_value, const char *hex_string, int size);
|
||||
|
||||
char *itoa(int i);
|
||||
|
||||
#define STRINGIFY(S) #S
|
||||
#define TO_STRING(S) STRINGIFY(S)
|
||||
int read_version(const char *version, uint8_t *major, uint8_t *minor, uint8_t *patch);
|
||||
|
||||
#define findInList(keY, result, list, element_type) {\
|
||||
int i;\
|
||||
for (i=0; i<sizeof(list)/sizeof(element_type) ; i++)\
|
||||
if (list[i].key==keY) {\
|
||||
result=list[i].val;\
|
||||
break;\
|
||||
}\
|
||||
AssertFatal(i < sizeof(list)/sizeof(element_type), "List %s doesn't contain %s\n",#list, #keY); \
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
44
l2-fapi-proxy/docker/Dockerfile.ubuntu18.04
Normal file
44
l2-fapi-proxy/docker/Dockerfile.ubuntu18.04
Normal file
@@ -0,0 +1,44 @@
|
||||
FROM ubuntu:bionic as proxy-builder
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Europe
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
|
||||
build-essential \
|
||||
libsctp1 \
|
||||
libsctp-dev \
|
||||
libz-dev \
|
||||
psmisc \
|
||||
git && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Copy the workspace as is
|
||||
WORKDIR /oai-lte-multi-ue-proxy
|
||||
COPY . .
|
||||
RUN make
|
||||
|
||||
RUN ldd build/proxy
|
||||
|
||||
FROM ubuntu:bionic as oai-lte-multi-ue-proxy
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV TZ=Europe/Paris
|
||||
# We install some debug tools for the moment in addition of mandatory libraries
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get upgrade --yes && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install --yes \
|
||||
net-tools \
|
||||
tzdata \
|
||||
psmisc \
|
||||
libasan4 \
|
||||
libsctp1 && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /oai-lte-multi-ue-proxy/bin
|
||||
COPY --from=proxy-builder /oai-lte-multi-ue-proxy/build/proxy .
|
||||
|
||||
RUN ldd proxy
|
||||
|
||||
CMD ["sleep", "infinity"]
|
||||
BIN
l2-fapi-proxy/l2_proxy_arch_diag.png
Normal file
BIN
l2-fapi-proxy/l2_proxy_arch_diag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
l2-fapi-proxy/l2_simulation_diag.png
Normal file
BIN
l2-fapi-proxy/l2_simulation_diag.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
201
l2-fapi-proxy/open-nFAPI/LICENSE.md
Normal file
201
l2-fapi-proxy/open-nFAPI/LICENSE.md
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
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.
|
||||
15
l2-fapi-proxy/open-nFAPI/Makefile.am
Normal file
15
l2-fapi-proxy/open-nFAPI/Makefile.am
Normal file
@@ -0,0 +1,15 @@
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS =common/ \
|
||||
sim_common/ \
|
||||
nfapi/ \
|
||||
pnf/ \
|
||||
vnf/ \
|
||||
nfapi/tests \
|
||||
pnf/tests \
|
||||
vnf/tests \
|
||||
pnf_sim/ \
|
||||
vnf_sim/ \
|
||||
integration_tests/ \
|
||||
docs/ \
|
||||
$(NULL)
|
||||
138
l2-fapi-proxy/open-nFAPI/README.md
Normal file
138
l2-fapi-proxy/open-nFAPI/README.md
Normal file
@@ -0,0 +1,138 @@
|
||||
[](https://travis-ci.org/cisco/open-nFAPI)
|
||||
[](https://scan.coverity.com/projects/cisco-open-nfapi)
|
||||
|
||||
# open-nFAPI
|
||||
|
||||
Open-nFAPI is implementation of the Small Cell Forum's network functional API or nFAPI for short.
|
||||
nFAPI defines a network protocol that is used to connect a Physical Network Function (PNF)
|
||||
running LTE Layer 1 to a Virtual Network Function (VNF) running LTE layer 2 and above. The specification
|
||||
can be found at http://scf.io/documents/082.
|
||||
|
||||
The aim of open-nFAPI is to provide an open interface between LTE layer 1 and layer 2 to allow for
|
||||
interoperability between the PNF and VNF & also to facilitate the sharing of PNF's between
|
||||
different VNF's
|
||||
|
||||
Open-nFAPI implements the P4, P5 and P7 interfaces as defined by the nFAPI specification.
|
||||
* The P5 interface allows the VNF to query and configure the 'resources' of the PNF; i.e slice it into
|
||||
1 or more PHY instances.
|
||||
* The P7 interface is used to send the subframe information between the PNF and VNF for a PHY instance
|
||||
* The P4 interface allows the VNF to request the PNF PHY instance to perform measurements of the surrounding network
|
||||
|
||||
The remaining interfaces are currently outside of the scope of this project.
|
||||
|
||||
Supports release 082.09.05 of the nFAPI specification
|
||||
|
||||
**The Small Cell Forum cordially requests that any derivative work that looks to
|
||||
extend the nFAPI libraries use the specified vendor extension techniques,
|
||||
so ensuring the widest interoperability of the baseline nFAPI specification
|
||||
in those derivative works.**
|
||||
|
||||
## Awards
|
||||
|
||||
The Open-nFAPI project has won the Small Cell Forum Judges Choice award 2017. (http://www.smallcellforum.org/awards-2/winners-2017/)
|
||||
|
||||
## Licensing
|
||||
|
||||
The open-nFAPI libraries are release by CISCO under an Apache 2 license. See `LICENSE.md` file for details
|
||||
|
||||
## Downloading
|
||||
|
||||
The open-nFAPI project can be pulled from git hub
|
||||
|
||||
```
|
||||
git clone https://github.com/cisco/open-nFAPI.git nfapi
|
||||
```
|
||||
|
||||
The following dependencies are required. These are based on a fresh ubuntu installation.
|
||||
|
||||
```
|
||||
sudo apt-get install autoconf
|
||||
sudo apt-get install gcc
|
||||
sudo apt-get install g++
|
||||
sudo apt-get install libtool
|
||||
sudo apt-get install make
|
||||
sudo apt-get install doxygen
|
||||
sudo apt-get install libcunit1-dev
|
||||
sudo apt-get install libz-dev
|
||||
sudo apt-get install libsctp-dev
|
||||
sudo apt-get install libboost-all-dev
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
To build the open-nFAPI project
|
||||
|
||||
```
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
```
|
||||
|
||||
To run the unit and integration tests
|
||||
|
||||
```
|
||||
make check
|
||||
```
|
||||
|
||||
You may notice in the console output of the final integration tests the following
|
||||
|
||||
```
|
||||
*** Missing subframe 123 125
|
||||
```
|
||||
|
||||
Out of the box the machine on which you are running has not be configured for real time operation as a result
|
||||
the vnf may not be scheduled at the correct times and hence it may risk 'missing' subframe opportunities. This
|
||||
warning indicates this has happened.
|
||||
|
||||
## Running the simulator
|
||||
|
||||
The vnf and pnf simulator can be run using the following commands. The pnf and vnf simulator support sourcing and sinking
|
||||
data over udp. Review the xml configuration files for the details of the port and address to configure. Console logging will show
|
||||
which address:port is being used
|
||||
|
||||
Note : Pinning the simulators to unused cores will produce more consistent behaviour.
|
||||
|
||||
Note : You may have to run the processes with sudo to be able to set the real time scheduling and priority
|
||||
|
||||
### vnf simulator
|
||||
|
||||
To run the vnf simulator you need to specify the port the vnf will listen for p5 connection request upon and also the xml configuration file
|
||||
|
||||
```
|
||||
vnfsim <port> <xml config file>
|
||||
```
|
||||
|
||||
### pnf simulator
|
||||
|
||||
To run the vnf simulator you need to specify the addrss & port the pnf will connect to the vnf on and also the xml configuration file
|
||||
|
||||
```
|
||||
pnfsim <address> <port> <xml config file>
|
||||
```
|
||||
|
||||
|
||||
## Directory structure
|
||||
|
||||
```
|
||||
docs doxgen documentation
|
||||
common common code used by the nfapi libraries
|
||||
nfapi the nfapi library including message definitions & encode/decode functions
|
||||
pnf the pnf library for p4, p5, & p7 interfaces
|
||||
vnf the vnf library for p4, p5, & p7 interfaces
|
||||
sim_common common simulation for used by the vnf and pnf sim
|
||||
vnf_sim a vnf simulator including a stub mac implementation
|
||||
pnf_sim a pnf simualtor including a fapi interface defintion and stub implementation
|
||||
xml xml configuration files for the vnf and pnf simulator
|
||||
wireshark code for a wireshark dissector for the nFAPI protocol
|
||||
```
|
||||
|
||||
## Coverity
|
||||
|
||||
Coverity runs on the coverity-scan branch. Changes must be merged to the coverity-scan branch to be checked.
|
||||
|
||||
|
||||
## eNB Integration - Open Air Interface
|
||||
|
||||
The open-nFAPI implementation has been integrated with the Open Air Interface solution here (https://gitlab.eurecom.fr/oai/openairinterface5g) and is (at the time of writing) here (https://gitlab.eurecom.fr/daveprice/openairinterface5g/tree/nfapi-ru-rau-split). The open-nFAPI implementation is integrated with the source eNB implementation with any changes required applied as a patch on top of the baseline open-nFAPI library. Any extensions required must be implemented through the vendor extensions as specified by the Small Cell Forum documentation. Any integration wrapping of functionality must be done within the target environment as shown in the Open Air Interface implementation nfapi directory which is defined by the $NFAPI_DIR location at the top level.
|
||||
31
l2-fapi-proxy/open-nFAPI/common/Makefile.am
Normal file
31
l2-fapi-proxy/open-nFAPI/common/Makefile.am
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/common/public_inc -g -Wall -Werror
|
||||
|
||||
noinst_LIBRARIES =libnfapi_common.a
|
||||
|
||||
libnfapi_common_a_SOURCES = src/debug.c
|
||||
|
||||
libnfapi_common_a_CFLAGS =$(AM_CFLAGS)
|
||||
|
||||
lib_LTLIBRARIES =libnfapi_common.la
|
||||
|
||||
libnfapi_common_la_SOURCES = src/debug.c
|
||||
|
||||
|
||||
|
||||
|
||||
44
l2-fapi-proxy/open-nFAPI/common/public_inc/debug.h
Normal file
44
l2-fapi-proxy/open-nFAPI/common/public_inc/debug.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define ERR strerror(errno)
|
||||
|
||||
/*! The trace levels used by the nfapi libraries */
|
||||
typedef enum nfapi_trace_level
|
||||
{
|
||||
NFAPI_TRACE_NONE,
|
||||
NFAPI_TRACE_ERROR,
|
||||
NFAPI_TRACE_WARN,
|
||||
NFAPI_TRACE_NOTE,
|
||||
NFAPI_TRACE_INFO,
|
||||
NFAPI_TRACE_DEBUG,
|
||||
} nfapi_trace_level_t;
|
||||
|
||||
void nfapi_trace(nfapi_trace_level_t, char const *caller, const char *format, ...)
|
||||
__attribute__((format(printf, 3, 4)));
|
||||
|
||||
nfapi_trace_level_t nfapi_trace_level(void);
|
||||
|
||||
#define NFAPI_TRACE(LEVEL, FORMAT, ...) do { \
|
||||
if (nfapi_trace_level() >= (LEVEL)) \
|
||||
nfapi_trace(LEVEL, __func__, FORMAT, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
202
l2-fapi-proxy/open-nFAPI/common/public_inc/nfapi.h
Normal file
202
l2-fapi-proxy/open-nFAPI/common/public_inc/nfapi.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _NFAPI_H_
|
||||
#define _NFAPI_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// todo : move to public_inc so can be used by vendor extensions
|
||||
|
||||
#define MAX_BAD_TAG 3
|
||||
int nfapitooai_level(int nfapilevel);
|
||||
uint8_t push8(uint8_t in, uint8_t **out, uint8_t *end);
|
||||
uint8_t pushs8(int8_t in, uint8_t **out, uint8_t *end);
|
||||
uint8_t push16(uint16_t in, uint8_t **out, uint8_t *end);
|
||||
uint8_t pushs16(int16_t in, uint8_t **out, uint8_t *end);
|
||||
uint8_t push32(uint32_t in, uint8_t **out, uint8_t *end);
|
||||
uint8_t pushs32(int32_t in, uint8_t **out, uint8_t *end);
|
||||
|
||||
uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end);
|
||||
uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end);
|
||||
uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end);
|
||||
uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end);
|
||||
|
||||
/*! \brief Pull an arbitrary amount of bytes ( 0 to 4 ) into an uint32_t
|
||||
* \param length the amount of bytes to pull
|
||||
* \param in the buffer from where to pull the bytes
|
||||
* \param out a pointer to the destination uint32_t
|
||||
* \param end a pointer to the end of the buffer in
|
||||
*
|
||||
* This function is used to pull `length` amount of bytes from `in` into `out`.
|
||||
* Used where pulling the full 32 bits would cause the `in` pointer to go over `end`.
|
||||
* It's currently used to pull the last bytes of a payload where the buffer does not contain padding at the end.
|
||||
*/
|
||||
uint8_t pullx32(uint8_t length, uint8_t **in, uint32_t *out, uint8_t *end);
|
||||
uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end);
|
||||
uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end);
|
||||
|
||||
uint32_t pullarray8(uint8_t **in, uint8_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
|
||||
uint32_t pullarray16(uint8_t **in, uint16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
|
||||
uint32_t pullarrays16(uint8_t **in, int16_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
|
||||
uint32_t pullarray32(uint8_t **values_to_pull,
|
||||
uint32_t out[],
|
||||
uint32_t max_num_values_to_pull,
|
||||
uint32_t num_values_to_pull,
|
||||
uint8_t *out_end);
|
||||
uint32_t pullarrays32(uint8_t **in, int32_t out[], uint32_t max_len, uint32_t len, uint8_t *end);
|
||||
|
||||
uint32_t pusharray8(uint8_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
|
||||
uint32_t pusharray16(uint16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
|
||||
uint32_t pusharrays16(int16_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
|
||||
uint32_t pusharray32(const uint32_t *values_to_push,
|
||||
uint32_t max_num_values_to_push,
|
||||
uint32_t num_values_to_push,
|
||||
uint8_t **out,
|
||||
uint8_t *out_end);
|
||||
uint32_t pusharrays32(int32_t in[], uint32_t max_len, uint32_t len, uint8_t **out, uint8_t *end);
|
||||
|
||||
typedef uint8_t (*pack_array_elem_fn)(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t packarray(void *array,
|
||||
uint16_t elem_size,
|
||||
uint16_t max_count,
|
||||
uint16_t count,
|
||||
uint8_t **ppWritePackedMsg,
|
||||
uint8_t *end,
|
||||
pack_array_elem_fn fn);
|
||||
|
||||
typedef uint8_t (*unpack_array_elem_fn)(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
uint8_t unpackarray(uint8_t **ppReadPackedMsg,
|
||||
void *array,
|
||||
uint16_t elem_size,
|
||||
uint16_t max_count,
|
||||
uint16_t count,
|
||||
uint8_t *end,
|
||||
unpack_array_elem_fn fn);
|
||||
|
||||
uint32_t pack_dci_payload(uint8_t *payload, uint16_t payloadSizeBits, uint8_t **out, uint8_t *end);
|
||||
uint32_t unpack_dci_payload(uint8_t *payload, uint16_t payloadSizeBits, uint8_t **in, uint8_t *end);
|
||||
|
||||
uint8_t pack_tl(nfapi_tl_t *tl, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_tl(uint8_t **ppReadPackedMsg, nfapi_tl_t *tl, uint8_t *end);
|
||||
|
||||
typedef uint8_t (*pack_tlv_fn)(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t pack_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn);
|
||||
uint8_t pack_nr_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, pack_tlv_fn fn);
|
||||
uint8_t pack_nr_generic_tlv(uint16_t tag, void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
|
||||
uint32_t pack_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
int unpack_vendor_extension_tlv(nfapi_tl_t *tl,
|
||||
uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_p4_p5_codec_config_t *config,
|
||||
nfapi_tl_t **ve_tlv);
|
||||
|
||||
uint8_t unpack_nr_generic_tlv_list(void *tlv_list, uint8_t tlv_count, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t get_tlv_padding(uint16_t tlv_length);
|
||||
|
||||
typedef uint8_t (*unpack_tlv_fn)(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
typedef struct {
|
||||
uint16_t tag;
|
||||
void *tlv;
|
||||
unpack_tlv_fn unpack_func;
|
||||
} unpack_tlv_t;
|
||||
|
||||
int unpack_tlv_list(unpack_tlv_t unpack_fns[],
|
||||
uint16_t size,
|
||||
uint8_t **ppReadPackedMsg,
|
||||
uint8_t *packedMsgEnd,
|
||||
nfapi_p4_p5_codec_config_t *config,
|
||||
nfapi_tl_t **ve);
|
||||
int unpack_nr_tlv_list(unpack_tlv_t unpack_fns[],
|
||||
uint16_t size,
|
||||
uint8_t **ppReadPackedMsg,
|
||||
uint8_t *packedMsgEnd,
|
||||
nfapi_p4_p5_codec_config_t *config,
|
||||
nfapi_tl_t **ve);
|
||||
|
||||
uint32_t pack_p7_vendor_extension_tlv(nfapi_tl_t *ve, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
typedef uint8_t (*unpack_p7_tlv_fn)(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *);
|
||||
typedef struct {
|
||||
uint16_t tag;
|
||||
void *tlv;
|
||||
unpack_p7_tlv_fn unpack_func;
|
||||
} unpack_p7_tlv_t;
|
||||
int unpack_p7_tlv_list(unpack_p7_tlv_t unpack_fns[],
|
||||
uint16_t size,
|
||||
uint8_t **ppReadPackedMsg,
|
||||
uint8_t *packedMsgEnd,
|
||||
nfapi_p7_codec_config_t *config,
|
||||
nfapi_tl_t **ve);
|
||||
int unpack_nr_p7_tlv_list(unpack_p7_tlv_t unpack_fns[],
|
||||
uint16_t size,
|
||||
uint8_t **ppReadPackedMsg,
|
||||
uint8_t *packedMsgEnd,
|
||||
nfapi_p7_codec_config_t *config,
|
||||
nfapi_tl_t **ve);
|
||||
|
||||
uint8_t pack_pnf_param_general_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_pnf_param_general_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_rf_config_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_rf_config_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_pnf_phy_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_pnf_phy_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_pnf_phy_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_pnf_phy_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_phy_rf_config_info(void *elem, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_phy_rf_config_info(void *elem, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_pnf_phy_rf_config_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_ipv4_address_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_ipv4_address_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_ipv6_address_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_ipv6_address_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_stop_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_stop_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
uint8_t pack_measurement_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_measurement_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
uint8_t pack_uint32_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_uint32_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_uint16_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_uint16_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_int16_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_int16_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint8_t pack_uint8_tlv_value(void *tlv, uint8_t **ppWritePackedMsg, uint8_t *end);
|
||||
uint8_t unpack_uint8_tlv_value(void *tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
|
||||
uint32_t get_packed_msg_len(uintptr_t msgHead, uintptr_t msgEnd);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _NFAPI_H_ */
|
||||
87
l2-fapi-proxy/open-nFAPI/common/src/debug.c
Normal file
87
l2-fapi-proxy/open-nFAPI/common/src/debug.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "debug.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static nfapi_trace_level_t trace_level = NFAPI_TRACE_WARN;
|
||||
|
||||
static void nfapi_trace_init(void)
|
||||
{
|
||||
static bool initialized;
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = true;
|
||||
|
||||
const char *env = getenv("NFAPI_TRACE_LEVEL");
|
||||
if (!env)
|
||||
return;
|
||||
if (strcmp(env, "none") == 0)
|
||||
trace_level = NFAPI_TRACE_NONE;
|
||||
else if (strcmp(env, "error") == 0)
|
||||
trace_level = NFAPI_TRACE_ERROR;
|
||||
else if (strcmp(env, "warn") == 0)
|
||||
trace_level = NFAPI_TRACE_WARN;
|
||||
else if (strcmp(env, "note") == 0)
|
||||
trace_level = NFAPI_TRACE_NOTE;
|
||||
else if (strcmp(env, "info") == 0)
|
||||
trace_level = NFAPI_TRACE_INFO;
|
||||
else if (strcmp(env, "debug") == 0)
|
||||
trace_level = NFAPI_TRACE_DEBUG;
|
||||
else
|
||||
{
|
||||
nfapi_trace(NFAPI_TRACE_ERROR, __func__, "Invalid NFAPI_TRACE_LEVEL='%s'", env);
|
||||
return;
|
||||
}
|
||||
nfapi_trace(trace_level, __func__, "NFAPI_TRACE_LEVEL='%s'", env);
|
||||
}
|
||||
|
||||
nfapi_trace_level_t nfapi_trace_level()
|
||||
{
|
||||
nfapi_trace_init();
|
||||
return trace_level;
|
||||
}
|
||||
|
||||
void nfapi_trace(nfapi_trace_level_t level,
|
||||
char const *caller,
|
||||
char const *format, ...)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
printf("%ld.%06ld [%c] %10u: %s: ",
|
||||
ts.tv_sec,
|
||||
ts.tv_nsec / 1000,
|
||||
"XEWNID"[level], // NFAPI_TRACE_NONE, NFAPI_TRACE_ERROR, ...
|
||||
(unsigned) pthread_self(),
|
||||
caller);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vprintf(format, ap);
|
||||
va_end(ap);
|
||||
|
||||
// Add a newline if the format string didn't have one
|
||||
int len = strlen(format);
|
||||
if (len == 0 || format[len - 1] != '\n')
|
||||
putchar('\n');
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
1733
l2-fapi-proxy/open-nFAPI/common/src/nfapi.c
Normal file
1733
l2-fapi-proxy/open-nFAPI/common/src/nfapi.c
Normal file
File diff suppressed because it is too large
Load Diff
45
l2-fapi-proxy/open-nFAPI/configure.ac
Normal file
45
l2-fapi-proxy/open-nFAPI/configure.ac
Normal file
@@ -0,0 +1,45 @@
|
||||
AC_INIT([open-nFAPI], [1.0])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_INIT_AUTOMAKE([subdir-objects -Wall -Werror foreign serial-tests])
|
||||
AM_PROG_AR
|
||||
|
||||
LT_INIT([shared static])
|
||||
|
||||
# Dependencies
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_AWK
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_CHECK_FILE([/usr/include/CUnit/CUnit.h],
|
||||
[CFLAGS_CUNIT=-I/usr/include/CUnit AC_SUBST(CFLAGS_CUNIT)],
|
||||
[AC_MSG_NOTICE([Have cunit *************])])
|
||||
|
||||
# Need doxygen
|
||||
AC_CHECK_PROGS([DOXYGEN], [doxygen])
|
||||
if test -z "$DOXYGEN";
|
||||
then AC_MSG_WARN([Doxygen not found - continuing without Doxygen support])
|
||||
fi
|
||||
AM_CONDITIONAL([HAVE_DOXYGEN], [test -n "$DOXYGEN"])AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([docs/Doxyfile])])
|
||||
|
||||
AC_REQUIRE_AUX_FILE([tap-driver.sh])
|
||||
|
||||
AC_CONFIG_FILES([Makefile
|
||||
sim_common/Makefile
|
||||
common/Makefile
|
||||
nfapi/Makefile
|
||||
pnf/Makefile
|
||||
vnf/Makefile
|
||||
nfapi/tests/Makefile
|
||||
pnf/tests/Makefile
|
||||
vnf/tests/Makefile
|
||||
pnf_sim/Makefile
|
||||
vnf_sim/Makefile
|
||||
integration_tests/Makefile
|
||||
docs/Makefile
|
||||
])
|
||||
AC_OUTPUT
|
||||
1720
l2-fapi-proxy/open-nFAPI/docs/Doxyfile
Normal file
1720
l2-fapi-proxy/open-nFAPI/docs/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
1720
l2-fapi-proxy/open-nFAPI/docs/Doxyfile.in
Normal file
1720
l2-fapi-proxy/open-nFAPI/docs/Doxyfile.in
Normal file
File diff suppressed because it is too large
Load Diff
35
l2-fapi-proxy/open-nFAPI/docs/Makefile.am
Normal file
35
l2-fapi-proxy/open-nFAPI/docs/Makefile.am
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
if HAVE_DOXYGEN
|
||||
directory = $(top_srcdir)/docs/man/man3/
|
||||
|
||||
dist_man_MANS = $(directory)/man_page_1.3 $(directory)/man_page_2.3
|
||||
$(directory)/man_page_1.3: doxyfile.stamp
|
||||
$(directory)/man_page_2.3: doxyfile.stamp
|
||||
|
||||
doxyfile.stamp:
|
||||
$(DOXYGEN) Doxyfile
|
||||
echo Timestamp > doxyfile.stamp
|
||||
|
||||
CLEANFILES = doxyfile.stamp
|
||||
|
||||
all-local: doxyfile.stamp
|
||||
clean-local:
|
||||
rm -rf $(top_srcdir)/docs/man
|
||||
rm -rf $(top_srcdir)/docs/html
|
||||
rm -rf $(top_srcdir)/docs/latex
|
||||
endif
|
||||
327
l2-fapi-proxy/open-nFAPI/docs/doxygen.h
Normal file
327
l2-fapi-proxy/open-nFAPI/docs/doxygen.h
Normal file
@@ -0,0 +1,327 @@
|
||||
/*! \mainpage Open Network Function Application Platform Interface (Open-nFAPI)
|
||||
*
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* Open-nFAPI is implementation of the Small Cell Forum's network femto API or nFAPI for short.
|
||||
* nFAPI defines a network protocol that is used to connect a Physical Network Function (PNF)
|
||||
* running LTE Layer 1 to a Virtual Network Function (VNF) running LTE Layer 2 and above. The specification
|
||||
* can be found at http://scf.io/documents/082.
|
||||
*
|
||||
* The aim of Open-nFAPI is to provide an open interface between LTE Layer 1 and Layer 2 to allow for
|
||||
* interoperability between the PNF and VNF & also to facilitate the sharing of PNF's between
|
||||
* different VNF's
|
||||
*
|
||||
* Open-nFAPI implements the P4, P5 and P7 interfaces as defined by the nFAPI specification.
|
||||
* - The P5 interface allows the VNF to query and configure the 'resources' of the PNF; slicing it into
|
||||
* 1 or more phy instances.
|
||||
* - The P7 interface is used to send the subframe information between the PNF and VNF for 1 or more phy instances
|
||||
* - The P4 interface allows the VNF to request the PNF phy instances to perform measurements of the surrounding network
|
||||
*
|
||||
* The remaining interfaces are currently outside of the scope of this project.
|
||||
*
|
||||
* The best place to start is by reviewing the detailed nFAPI call flow which can be \ref nfapi_call_flow "here"
|
||||
*
|
||||
* \section contrib Contibuting
|
||||
*
|
||||
* The Small Cell Forum cordially requests that any derivative work that looks to extend
|
||||
* the nFAPI libraries use the specified vendor extension techniques, so ensuring
|
||||
*the widest interoperability of the baseline nFAPI specification in those derivative works.
|
||||
*
|
||||
* \section install_sec Installation
|
||||
*
|
||||
* \subsection step1 Step 1: Opening the box
|
||||
*
|
||||
* etc...
|
||||
*
|
||||
* \section dir_struct Directory Structure
|
||||
* \code
|
||||
|
||||
* nfapi
|
||||
* |- common Common functions for the nfapi project
|
||||
* | |- src
|
||||
* | |- public-inc
|
||||
* |- nfapi The NFAPI lib
|
||||
* | |- inc
|
||||
* | |- src
|
||||
* | |- public-inc Public interface for the nfapi library
|
||||
* | |- tests Unit test for the nfapi lib
|
||||
* |- pnf The PNF lib
|
||||
* | |- inc
|
||||
* | |- src
|
||||
* | |- public-inc Public interface for the pnf library
|
||||
* | |- tests Unit test for the pnf lib
|
||||
* |- vnf The VNF lib
|
||||
* | |- inc
|
||||
* | |- src
|
||||
* | |- public-inc Public interface for the vnf library
|
||||
* | |- tests Unit test for the vnf lib
|
||||
* |- sim_common Common functions for the nfapi simulators
|
||||
* | |- inc
|
||||
* | |- src
|
||||
* |- pnf_sim The PNF simulator
|
||||
* | |- inc
|
||||
* | |- src
|
||||
* |- vnf_sim The VNF simulator
|
||||
* | |- inc
|
||||
* | |- src
|
||||
* |- integration_tests Integration tests that run both VNF & PNF simulators
|
||||
* | |- inc
|
||||
* | |- src
|
||||
* |- docs Documentation
|
||||
* |- xml Xml configuration for the simulator
|
||||
|
||||
* \endcode
|
||||
* \section building Building
|
||||
* To build the nfapi project and run the unit test you will need to
|
||||
* \code
|
||||
* autoreconf -i
|
||||
* ./configure
|
||||
* make
|
||||
* make check
|
||||
* \endcode
|
||||
* The following dependencies will be required
|
||||
* - Boost. Need to build the simulators
|
||||
* - STCP. Need to run the simulators
|
||||
* -
|
||||
* \section simulators Running the simulators
|
||||
* Once you have build the nfapi project you can run the PNF/VNF simulators on either the same
|
||||
* of seperate linux machines.
|
||||
*
|
||||
* To run the VNF from the vnf_sim directory.
|
||||
* \code
|
||||
* ./vnfsim 4242 ../xml/vnf_A.xml
|
||||
* [MAC] Rx Data from 8891
|
||||
* [MAC] Tx Data to 10.231.16.80.8892
|
||||
* Calling nfapi_vnf_start
|
||||
* 2035.854438: 0x04: 773068608: nfapi_vnf_start()
|
||||
* 2035.854450: 0x04: 773068608: Starting P5 VNF connection on port 4242
|
||||
* 2035.854472: 0x04: 773068608: P5 socket created... 3
|
||||
* 2035.854478: 0x03: 773068608: VNF Setting the SCTP_INITMSG
|
||||
* 2035.854481: 0x04: 773068608: IPV4 binding to port 4242
|
||||
* 2035.854485: 0x04: 773068608: bind succeeded..3.
|
||||
* 2035.854497: 0x04: 773068608: listen succeeded...
|
||||
* \endcode
|
||||
*
|
||||
*
|
||||
* To run the PNF from the pnf_sim directory
|
||||
* \code
|
||||
* ./pnfsim 127.0.01 4242 ../xml/pnf_phy_1_A.xml
|
||||
* nfapi_pnf_start
|
||||
* Starting P5 PNF connection to VNF at 127.0.0.1:4242
|
||||
* Host address info 0 Family:IPV4 Address:127.0.0.1
|
||||
* PNF Setting the SCTP_INITMSG
|
||||
* P5 socket created...
|
||||
* Socket CONNECTED
|
||||
* PNF_PARAM.request received
|
||||
* [PNF_SIM] pnf param request
|
||||
* PNF_CONFIG.request received
|
||||
* [PNF_SIM] pnf config request
|
||||
* .... and so on
|
||||
* \endcode
|
||||
*
|
||||
* You can Ctrl-C to exit the simulators.
|
||||
*
|
||||
|
||||
*/
|
||||
|
||||
/*! \page nfapi_call_flow NFAPI Call Flow
|
||||
*
|
||||
* \section seq_diag Sequence diagram
|
||||
*
|
||||
* The follow sequence digram show how the nFAPI api will be used to bring up
|
||||
* the PNF and then the PNF PHY and initiate subframe message exchange
|
||||
* The names of the CLIENT callbacks are placeholders for the functions that
|
||||
* the CLIENT will provide.
|
||||
*
|
||||
* \msc
|
||||
*
|
||||
* width="1750";
|
||||
* FAPI, PNF_P7_CLIENT, PNF_P7_LIB, PNF_P5_CLIENT, PNF_P5_LIB, VNF_P5_LIB, VNF_P5_CLIENT, VNF_P7_LIB, VNF_P7_CLIENT, MAC;
|
||||
* VNF_P5_CLIENT=>VNF_P5_LIB [label="nfapi_vnf_config_create", URL="\ref nfapi_vnf_config_create"];
|
||||
* VNF_P5_CLIENT=>VNF_P5_LIB [label="nfapi_vnf_start", URL="\ref nfapi_vnf_start"];
|
||||
* VNF_P5_LIB note VNF_P5_LIB [label="Listening for PNF connection"];
|
||||
* PNF_P5_CLIENT note PNF_P5_CLIENT [label="P9 has provided the address of the VNF"];
|
||||
* PNF_P5_CLIENT=>PNF_P5_LIB [label="nfapi_pnf_config_create", URL="\ref nfapi_pnf_config_create"];
|
||||
* PNF_P5_CLIENT=>PNF_P5_LIB [label="nfapi_pnf_start", URL="\ref nfapi_pnf_start"];
|
||||
* PNF_P5_LIB note PNF_P5_LIB [label="PNF STATE : PNF IDLE"];
|
||||
* PNF_P5_LIB->VNF_P5_LIB [label="<connect>"];
|
||||
* VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_connection_indication", URL="\ref nfapi_vnf_config::pnf_connection_indication"];
|
||||
*
|
||||
* VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_pnf_param_req", URL="\ref nfapi_vnf_pnf_param_req"];
|
||||
* VNF_P5_LIB->PNF_P5_LIB [label="PNF_PARAM.request"];
|
||||
* PNF_P5_LIB=>PNF_P5_CLIENT [label="pnf_param_request", URL="\ref nfapi_pnf_config::pnf_param_req"];
|
||||
* PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_pnf_param_response", URL="\ref nfapi_pnf_pnf_param_resp"];
|
||||
* VNF_P5_LIB<-PNF_P5_LIB [label="PNF_PARAM.response"];
|
||||
* VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_param_response", URL="\ref nfapi_vnf_config::pnf_param_resp"];
|
||||
*
|
||||
* VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_pnf_config_req", URL="\ref nfapi_vnf_pnf_config_req"];
|
||||
* VNF_P5_LIB->PNF_P5_LIB [label="PNF_CONFIG.request"];
|
||||
* PNF_P5_LIB=>PNF_P5_CLIENT [label="pnf_config_request", URL="\ref nfapi_pnf_config::pnf_config_req"];
|
||||
* PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_pnf_config_response", URL="\ref nfapi_pnf_pnf_config_resp"];
|
||||
* PNF_P5_LIB note PNF_P5_LIB [label="PNF STATE : PNF CONFIGURED"];
|
||||
* VNF_P5_LIB<-PNF_P5_LIB [label="PNF_CONFIG.response"];
|
||||
* VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_config_response", URL="\ref nfapi_vnf_config::pnf_config_resp"];
|
||||
*
|
||||
* VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_pnf_start_req", URL="\ref nfapi_vnf_pnf_start_req"];
|
||||
* VNF_P5_LIB->PNF_P5_LIB [label="PNF_START.request"];
|
||||
* PNF_P5_LIB=>PNF_P5_CLIENT [label="pnf_start_request", URL="\ref nfapi_pnf_config::pnf_start_req"];
|
||||
* PNF_P5_CLIENT=>FAPI [label="<create>"];
|
||||
* FAPI note FAPI [label="FAPI STATE : IDLE"];
|
||||
* PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_pnf_start_response", URL="\ref nfapi_pnf_pnf_start_resp"];
|
||||
* PNF_P5_LIB note PNF_P5_LIB [label="PNF STATE : PNF RUNNING"];
|
||||
* VNF_P5_LIB<-PNF_P5_LIB [label="PNF_START.response"];
|
||||
* VNF_P5_LIB=>VNF_P5_CLIENT [label="pnf_start_response", URL="\ref nfapi_vnf_config::pnf_param_resp"];
|
||||
*
|
||||
* --- [ label="If vnf p7 instance not already running"];
|
||||
* VNF_P5_CLIENT=>VNF_P5_LIB [label="nfapi_vnf_allocate_phy", URL="\ref nfapi_vnf_allocate_phy"];
|
||||
* VNF_P5_CLIENT=>VNF_P7_CLIENT [label="<create>"];
|
||||
* VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_config_create", URL="\ref nfapi_vnf_p7_config_create"];
|
||||
* VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_start", URL="\ref nfapi_vnf_p7_start"];
|
||||
* ---;
|
||||
*
|
||||
* VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_param_request", URL="\ref nfapi_vnf_param_req"];
|
||||
* VNF_P5_LIB->PNF_P5_LIB [label="PARAM.request"];
|
||||
* PNF_P5_LIB=>PNF_P5_CLIENT [label="param_request", URL="\ref nfapi_pnf_config::param_req"];
|
||||
* PNF_P5_CLIENT=>FAPI [label="fapi_param_request"];
|
||||
* PNF_P5_CLIENT<=FAPI [label="fapi_param_response"];
|
||||
* PNF_P5_CLIENT=>PNF_P7_CLIENT [label="<create>"];
|
||||
* PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_create", URL="\ref nfapi_pnf_p7_config_create"];
|
||||
* PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_start", URL="\ref nfapi_pnf_p7_start"];
|
||||
* PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_param_response", URL="\ref nfapi_pnf_param_resp"];
|
||||
* VNF_P5_LIB<-PNF_P5_LIB [label="PARAM.response"];
|
||||
* VNF_P5_LIB=>VNF_P5_CLIENT [label="param_response", URL="\ref nfapi_vnf_config::param_resp"];
|
||||
*
|
||||
* VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_config_request", URL="\ref nfapi_vnf_config_req"];
|
||||
* VNF_P5_LIB->PNF_P5_LIB [label="CONFIG.request"];
|
||||
* PNF_P5_LIB=>PNF_P5_CLIENT [label="config_request", URL="\ref nfapi_pnf_config::config_req"];
|
||||
* PNF_P5_CLIENT=>FAPI [label="fapi_config_request"];
|
||||
* FAPI note FAPI [label="FAPI STATE : CONFIGURED"];
|
||||
* PNF_P5_CLIENT<=FAPI [label="fapi_config_response"];
|
||||
* PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_config_response", URL="\ref nfapi_pnf_param_resp"];
|
||||
* VNF_P5_LIB<-PNF_P5_LIB [label="CONFIG.response"];
|
||||
* VNF_P5_LIB=>VNF_P5_CLIENT [label="config_response", URL="\ref nfapi_vnf_config::config_resp"];
|
||||
*
|
||||
* VNF_P5_LIB<=VNF_P5_CLIENT [label="nfapi_vnf_start_request", URL="\ref nfapi_vnf_start_req"];
|
||||
* VNF_P5_LIB->PNF_P5_LIB [label="START.request"];
|
||||
* PNF_P5_LIB=>PNF_P5_CLIENT [label="start_request", URL="\ref nfapi_pnf_config::start_req"];
|
||||
* PNF_P5_CLIENT=>FAPI [label="fapi_start_request"];
|
||||
* FAPI note FAPI [label="FAPI STATE : RUNNING"];
|
||||
* FAPI note FAPI [label="FAPI will start sending subframe indications"];
|
||||
*
|
||||
* --- [ label="For each 'phy' subframe"];
|
||||
* FAPI=>PNF_P7_CLIENT [label="fapi_subframe_indication"];
|
||||
* PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_subframe_ind", URL="\ref nfapi_pnf_p7_subframe_ind"];
|
||||
* ---;
|
||||
* PNF_P7_CLIENT=>PNF_P5_CLIENT [label="<start_response>"];
|
||||
*
|
||||
* PNF_P5_LIB<=PNF_P5_CLIENT [label="nfapi_pnf_start_response", URL="\ref nfapi_pnf_start_resp"];
|
||||
* VNF_P5_LIB<-PNF_P5_LIB [label="START.response"];
|
||||
* VNF_P5_LIB=>VNF_P5_CLIENT [label="start_response", URL="\ref nfapi_vnf_config::start_resp"];
|
||||
* VNF_P5_CLIENT=>VNF_P7_CLIENT [label="<p7_add_pnf>"];
|
||||
* VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_add_pnf", URL="\ref nfapi_vnf_p7_add_pnf"];
|
||||
*
|
||||
* VNF_P7_LIB->PNF_P7_LIB [label="DL_NODE_SYNC"];
|
||||
* VNF_P7_LIB<-PNF_P7_LIB [label="UL_NODE_SYNC"];
|
||||
* VNF_P7_LIB<-PNF_P7_LIB [label="TIMING_INFO"];
|
||||
* VNF_P7_LIB note VNF_P7_LIB [label="When sync is achieved"];
|
||||
*
|
||||
* VNF_P7_LIB=>VNF_P7_CLIENT [label="sync_indication", URL="\ref nfapi_vnf_p7_config::sync_indication"];
|
||||
*
|
||||
* --- [ label="For each 'vnf phy' subframe"];
|
||||
* VNF_P7_LIB=>VNF_P7_CLIENT [label="subframe_indication(tti=x)", URL="\ref nfapi_vnf_p7_config::subframe_indication"];
|
||||
* VNF_P7_CLIENT=>MAC [label="subframe_indication"];
|
||||
* VNF_P7_CLIENT<=MAC [label="dl_config_req"];
|
||||
* VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_dl_config_req", URL="\ref nfapi_vnf_p7_dl_config_req"];
|
||||
* VNF_P7_LIB->PNF_P7_LIB [label="DL_CONFIG.request"];
|
||||
* PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"];
|
||||
* VNF_P7_CLIENT<=MAC [label="ul_config_req"];
|
||||
* VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_ul_config_req", URL="\ref nfapi_vnf_p7_ul_config_req"];
|
||||
* VNF_P7_LIB->PNF_P7_LIB [label="UL_CONFIG.request"];
|
||||
* PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"];
|
||||
* VNF_P7_CLIENT<=MAC [label="hi_dci0_req"];
|
||||
* VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_hi_dci0_req", URL="\ref nfapi_vnf_p7_hi_dci0_req"];
|
||||
* VNF_P7_LIB->PNF_P7_LIB [label="HI_DCI0.request"];
|
||||
* PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"];
|
||||
* VNF_P7_CLIENT<=MAC [label="tx_req"];
|
||||
* VNF_P7_CLIENT=>VNF_P7_LIB [label="nfapi_vnf_p7_tx_req", URL="\ref nfapi_vnf_p7_tx_req"];
|
||||
* VNF_P7_LIB->PNF_P7_LIB [label="TX.request"];
|
||||
* PNF_P7_LIB note PNF_P7_LIB [label="Store in subframe buffer for tti x"];
|
||||
* ---;
|
||||
*
|
||||
*
|
||||
* --- [ label="For each 'phy' subframe"];
|
||||
*
|
||||
* FAPI=>PNF_P7_CLIENT [label="harq_indication"];
|
||||
* PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_harq_ind", URL="\ref nfapi_pnf_p7_harq_ind"];
|
||||
* PNF_P7_LIB->VNF_P7_LIB [label="HARQ.ind"];
|
||||
* VNF_P7_LIB=>VNF_P7_CLIENT [label="harq_ind", URL="\ref nfapi_vnf_p7_config::harq_indication"];
|
||||
* VNF_P7_CLIENT=>MAC [label="harq_ind"];
|
||||
*
|
||||
* FAPI=>PNF_P7_CLIENT [label="subframe_indication(tti=x)"];
|
||||
* PNF_P7_CLIENT=>PNF_P7_LIB [label="nfapi_pnf_p7_subframe_ind", URL="\ref nfapi_pnf_p7_subframe_ind"];
|
||||
* PNF_P7_LIB note PNF_P7_LIB [label="Send data from subframe buffer for tti x"];
|
||||
* PNF_P7_LIB=>PNF_P7_CLIENT [label="dl_config_req", URL="\ref nfapi_pnf_p7_config::dl_config_req"];
|
||||
* PNF_P7_CLIENT=>FAPI [label="dl_config_req"];
|
||||
* PNF_P7_LIB=>PNF_P7_CLIENT [label="ul_config_req", URL="\ref nfapi_pnf_p7_config::ul_config_req"];
|
||||
* PNF_P7_CLIENT=>FAPI [label="ul_config_req"];
|
||||
* PNF_P7_LIB=>PNF_P7_CLIENT [label="hi_dci0_req", URL="\ref nfapi_pnf_p7_config::hi_dci0_req"];
|
||||
* PNF_P7_CLIENT=>FAPI [label="hi_dci0_req"];
|
||||
* PNF_P7_LIB=>PNF_P7_CLIENT [label="tx_req", URL="\ref nfapi_pnf_p7_config::tx_req"];
|
||||
* PNF_P7_CLIENT=>FAPI [label="tx_req"];
|
||||
* ---;
|
||||
*
|
||||
* \endmsc
|
||||
*
|
||||
* \section seq_diag_bca BCA
|
||||
*
|
||||
* -# The VNF_P5_CLIENT is created. If it left to the VRAN partner to define how that is done. The client is responsiable to creation of the thread with the correct priorities within the wider system.
|
||||
* -# The VNF_P5_CLIENT creates and initializes the VNF_P5_LIB (nfapi_vnf_config_create & nfapi_vnf_start) providing the address that it should listen on for incoming SCTP connections. It is expected that this would be provided by some VNF management system. The VNF_P5_CLIENT also provides information on the callbacks that the VNF_P5_LIB will use to inform the VNF_P5_CLIENT of the received messages
|
||||
* \code
|
||||
* nfapi_vnf_config_t* vnf_config = nfapi_vnf_config_create();
|
||||
* vnf_config->pnf_connection_indication = &pnf_connection_indication;
|
||||
* vnf_config->pnf_param_resp = &pnf_param_resp;
|
||||
* nfapi_vnf_start(vnf_config);
|
||||
* \endcode
|
||||
* -# It is FFS how the address information of the VNF P5 is passed to the PNF over P9, but assuming that has been done
|
||||
* -# The PNF_P5_CLIENT is created and then creates the PNF_P5_LIB (nfapi_pnf_init & nfapi_pnf_start) passing the address of the VNF to connect to. The PNF_P5_CLIENT also provides information on the callbacks that the PNF_P5_LIB will use to inform the PNF_P5_CLIENT of the received messages
|
||||
* \code
|
||||
* nfapi_pnf_config_t* pnf_config = nfapi_pnf_config_create();
|
||||
* pnf_config->pnf_param_req = &pnf_param_req;
|
||||
* nfapi_pnf_start(pnf_config);
|
||||
* \endcode
|
||||
* -# The PNF_P5_LIB attempts to establish connection to the VNF_P5 endpoint
|
||||
* -# The VNF_P5_LIB receives the STCP connection request and indicates this to the VNF_P5_CLIENT (pnf_connection_indication). The VNF_P5_CLIENT can decide to accept or reject the connection.
|
||||
* \code
|
||||
* int pnf_connection_indication(nfapi_vnf_config_t* config, int p5_idx) {
|
||||
* // send the PNF_PARAM.request
|
||||
* nfapi_pnf_param_request_t req;
|
||||
* memset(&req, 0, sizeof(req));
|
||||
* req.header.message_id = NFAPI_PNF_PARAM_REQUEST;
|
||||
* nfapi_vnf_pnf_param_req(config, p5_idx, req);
|
||||
* return 0;
|
||||
* }
|
||||
* \endcode
|
||||
|
||||
* -# The VNF and PNF then proceed to exchange the NFAPI PNF messages (PNF_PARAM, PNF_CONFIG and PNF_START). At each stage the LIB’s invoke callbacks on the CLIENT’s for them to handle message the return the appropriate response.
|
||||
* -# Finally the VNF will send the PNF_START.req which will invoke the PNF_P5_CLIENT nfapi_pnf_start_request callback. This is the point at which it is expect that the PNF_CLIENT will create the FAPI module. The PNF_P5_CLIENT will need to perform the translation between NFAPI structures and vendor specific FAPI structures for messages sent between the PNF_P5_LIB and the FAPI interface.
|
||||
* -# The PNF_START.response will sent back to the VNF and at this point the VNF_P5_CLIENT will need to decide which VNF_P7 instance will handle the P7 connection. i.e. it needs to determine the IP address and port number of the P7 VNF instance.
|
||||
* -# A new VNF_P7_CLIENT & VNF_P7_LIB should be configured and started if necessary.
|
||||
* -# The VNF_P5 will then send the PARAM.request to the PNF_P5 which will forward it onto the FAPI interface. This PARAM.request includes the VNF_P7 address. The PNF_P7_CLIENT must decide on the PNF P7 address. This information is used to create and initialize the PNF_P7_LIB. The PNF_P7 address is then returned by the PNF_P5 to the VNF_P5 in the PARAM.response.
|
||||
* -# The VNF_P5 will then exchange with the PNF_P5 the CONFIG.request/response which will be used to configure the PNF FAPI instance.
|
||||
* -# The VNF_P5 will then decide to start the PNF_P7 by sending the START.request.
|
||||
* -# The PNF_P5_CLIENT need to send the start request to the FAPI instance. The response which is the start of subframe indications from the FAPI. In receipt of the first subframe indication the PNF_P5_CLIENT will send the START.response to the VNF_P5 via the PNF_P5_LIB
|
||||
* -# The FAPI subframe indications should be forwarded to the PNF_P7_LIB by the PNF_P7_CLIENT. Until the VNF_P7 instance has sent the subframe configuration messages (dl_config, ul_config, etc) the PNF_P7_LIB will send ‘dummy’ subframe configuration messages. The contents of which are configurable by the PNF_P7_CLIENT.
|
||||
* -# When the VNF_P5_CLIENT receives the START.response it will need to ‘communicate’ with the VNF_P7_CLIENT to inform it that the PNF_P7 instance has started. The VNF_P7_CLIENT will call the nfapi_vnf_P7_add_pnf function passing the address details of the PNF_P7 instance.
|
||||
* -# The VNF_P7_LIB will then start the sync procedure to establish sub frame synchronization between the PNF_P7 and VNF_P7 instances. This involves sending the DL_NODE_SYNC and UL_NODE_SYNC to determine network latency and PNF processing latency to be able to request MAC generate sub frames in advance on when they are required by the FAPI interface.
|
||||
* -# When sync is achieved the VNF_P7_LIB will send the nfapi_sync_indication to the VNF_P7_CLIENT.
|
||||
* -# The VNF_P7_LIB will then start issuing sub frame indications to the VNF_P7_CLIENT. The logical intent is that they indications are sent every millisecond. However due to the scheduling jitter that may be seen by the VNF these subframe indications may be less than or more than 1ms apart. How this is handled is one of the critical functions of the VNF_P7_LIB and may require specialization or requirements on the VNF environment i.e. CPU pinning.
|
||||
* -# The VNF_P7_LIB will send the subframe_indication to the VNF_P7_CLIENT for ‘x’ subframe’s inadvance of the current TTI at the PNF. The delta ‘x’ will be determined by the sync procedure and how far in advance the FAPI needs to receive messages before RF transmission.
|
||||
* -# The VNF_P7_CLIENT is then responsible for communicating to the MAC layer to prepare the dl_config_request, ul_config_request, hi_dci0_request, tx_req in a timely manner and sending them to the VNF_P7_LIB
|
||||
* -# The VNF_P7_LIB will send them to the VNF_P7_LIB.
|
||||
* -# The PNF_P7_LIB will store these messages in a subframe buffer or playout buffer in advance of when they are required by FAPI.
|
||||
* -# The PNF_P7_LIB will monitor to see if these messages arrive too late and if they do trigger a TIMING_INFO response to the VNF_P7_LIB to reassess if the sync is still valid.
|
||||
* -# As some time in the future the FAPI will send a subframe indication for the TTI that the VNF_P7_LIB had previously requested.
|
||||
* -# The PNF_P7_LIB will then use the messages in the subframe buffer and send them too the FAPI interface for transmission. The PNF_P7_CLIENT will need to perform the translation between NFAPI structure and vendor specific FAPI structures
|
||||
* -# This subframe exchange will continue and allow high layer MAC and RRC function to bringup the cell and connect UE’s
|
||||
|
||||
*/
|
||||
87
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi.h
Normal file
87
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
#ifndef OPENAIRINTERFACE_NR_FAPI_H
|
||||
#define OPENAIRINTERFACE_NR_FAPI_H
|
||||
|
||||
#include "stdint.h"
|
||||
#include "string.h"
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
#include "nfapi.h"
|
||||
// #include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "vendor_ext.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include "assertions.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define INDENTED_PRINTF(format, ...) printf("%*s" format, depth * 2, "", ##__VA_ARGS__)
|
||||
#define INDENTED_GENERIC_PRINT(string, format, ...) INDENTED_PRINTF(string " = " format "\n", ##__VA_ARGS__)
|
||||
#define INDENTED_TLV_PRINT(tlv_name, tlv) INDENTED_GENERIC_PRINT("(0x%04x) " tlv_name, "0x%02x", tlv.tl.tag, tlv.value)
|
||||
#define INDENTED_TLV_FORMAT_PRINT(tlv_name, format, tlv) INDENTED_GENERIC_PRINT("(0x%04x) " tlv_name, format, tlv.tl.tag, tlv.value)
|
||||
|
||||
#define EQ_TLV(_tlv_a, _tlv_b) \
|
||||
do { \
|
||||
EQ(_tlv_a.tl.tag, _tlv_b.tl.tag); \
|
||||
EQ(_tlv_a.value, _tlv_b.value); \
|
||||
} while (0)
|
||||
|
||||
#define EQ(_a, _b) \
|
||||
do { \
|
||||
if ((_a) != (_b)) { \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define COPY_TL(_dst_tl, _src_tl) \
|
||||
do { \
|
||||
_dst_tl.tag = _src_tl.tag; \
|
||||
_dst_tl.length = _src_tl.length; \
|
||||
} while (0)
|
||||
|
||||
#define COPY_TLV(_dst, _src) \
|
||||
do { \
|
||||
COPY_TL(_dst.tl, _src.tl); \
|
||||
_dst.value = _src.value; \
|
||||
} while (0)
|
||||
|
||||
typedef struct {
|
||||
uint8_t num_msg;
|
||||
uint8_t opaque_handle;
|
||||
uint16_t message_id;
|
||||
uint32_t message_length;
|
||||
} fapi_message_header_t;
|
||||
|
||||
void copy_vendor_extension_value(nfapi_vendor_extension_tlv_t *dst, const nfapi_vendor_extension_tlv_t *src);
|
||||
|
||||
bool isFAPIMessageIDValid(uint16_t id);
|
||||
|
||||
int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen);
|
||||
|
||||
int fapi_nr_message_header_unpack(uint8_t **pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
#endif // OPENAIRINTERFACE_NR_FAPI_H
|
||||
57
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p5.h
Normal file
57
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p5.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 OPENAIRINTERFACE_NR_FAPI_P5_H
|
||||
#define OPENAIRINTERFACE_NR_FAPI_P5_H
|
||||
#include "stdint.h"
|
||||
#include "nfapi_interface.h"
|
||||
|
||||
int fapi_nr_p5_message_pack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pPackedBuf,
|
||||
uint32_t packedBufLen,
|
||||
nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
int fapi_nr_p5_message_unpack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
uint8_t pack_nr_param_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_param_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_param_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_config_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_config_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_start_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_start_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_start_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_start_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_stop_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_stop_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_stop_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_stop_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t pack_nr_error_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p4_p5_codec_config_t *config);
|
||||
uint8_t unpack_nr_error_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p4_p5_codec_config_t *config);
|
||||
#endif // OPENAIRINTERFACE_NR_FAPI_P5_H
|
||||
70
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
Normal file
70
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p5_utils.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.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 OPENAIRINTERFACE_NR_FAPI_P5_UTILS_H
|
||||
#define OPENAIRINTERFACE_NR_FAPI_P5_UTILS_H
|
||||
#include "stdio.h"
|
||||
#include "stdint.h"
|
||||
#include "nr_fapi.h"
|
||||
#include "nfapi/oai_integration/vendor_ext.h"
|
||||
|
||||
bool eq_param_request(const nfapi_nr_param_request_scf_t *unpacked_req, const nfapi_nr_param_request_scf_t *req);
|
||||
bool eq_param_response(const nfapi_nr_param_response_scf_t *unpacked_req, const nfapi_nr_param_response_scf_t *req);
|
||||
bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const nfapi_nr_config_request_scf_t *req);
|
||||
bool eq_config_response(const nfapi_nr_config_response_scf_t *unpacked_req, const nfapi_nr_config_response_scf_t *req);
|
||||
bool eq_start_request(const nfapi_nr_start_request_scf_t *unpacked_req, const nfapi_nr_start_request_scf_t *req);
|
||||
bool eq_start_response(const nfapi_nr_start_response_scf_t *unpacked_req, const nfapi_nr_start_response_scf_t *req);
|
||||
bool eq_stop_request(const nfapi_nr_stop_request_scf_t *unpacked_req, const nfapi_nr_stop_request_scf_t *req);
|
||||
bool eq_stop_indication(const nfapi_nr_stop_indication_scf_t *unpacked_req, const nfapi_nr_stop_indication_scf_t *req);
|
||||
bool eq_error_indication(const nfapi_nr_error_indication_scf_t *unpacked_req, const nfapi_nr_error_indication_scf_t *req);
|
||||
|
||||
void free_param_request(nfapi_nr_param_request_scf_t *msg);
|
||||
void free_param_response(nfapi_nr_param_response_scf_t *msg);
|
||||
void free_config_request(nfapi_nr_config_request_scf_t *msg);
|
||||
void free_config_response(nfapi_nr_config_response_scf_t *msg);
|
||||
void free_start_request(nfapi_nr_start_request_scf_t *msg);
|
||||
void free_start_response(nfapi_nr_start_response_scf_t *msg);
|
||||
void free_stop_request(nfapi_nr_stop_request_scf_t *msg);
|
||||
void free_stop_indication(nfapi_nr_stop_indication_scf_t *msg);
|
||||
void free_error_indication(nfapi_nr_error_indication_scf_t *msg);
|
||||
|
||||
void copy_param_request(const nfapi_nr_param_request_scf_t *src, nfapi_nr_param_request_scf_t *dst);
|
||||
void copy_param_response(const nfapi_nr_param_response_scf_t *src, nfapi_nr_param_response_scf_t *dst);
|
||||
void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_config_request_scf_t *dst);
|
||||
void copy_config_response(const nfapi_nr_config_response_scf_t *src, nfapi_nr_config_response_scf_t *dst);
|
||||
void copy_start_request(const nfapi_nr_start_request_scf_t *src, nfapi_nr_start_request_scf_t *dst);
|
||||
void copy_start_response(const nfapi_nr_start_response_scf_t *src, nfapi_nr_start_response_scf_t *dst);
|
||||
void copy_stop_request(const nfapi_nr_stop_request_scf_t *src, nfapi_nr_stop_request_scf_t *dst);
|
||||
void copy_stop_indication(const nfapi_nr_stop_indication_scf_t *src, nfapi_nr_stop_indication_scf_t *dst);
|
||||
void copy_error_indication(const nfapi_nr_error_indication_scf_t *src, nfapi_nr_error_indication_scf_t *dst);
|
||||
|
||||
void dump_param_request(const nfapi_nr_param_request_scf_t *msg);
|
||||
void dump_param_response(const nfapi_nr_param_response_scf_t *msg);
|
||||
void dump_config_request(const nfapi_nr_config_request_scf_t *msg);
|
||||
void dump_config_response(const nfapi_nr_config_response_scf_t *msg);
|
||||
void dump_start_request(const nfapi_nr_start_request_scf_t *msg);
|
||||
void dump_start_response(const nfapi_nr_start_response_scf_t *msg);
|
||||
void dump_stop_request(const nfapi_nr_stop_request_scf_t *msg);
|
||||
void dump_stop_indication(const nfapi_nr_stop_indication_scf_t *msg);
|
||||
void dump_error_indication(const nfapi_nr_error_indication_scf_t *msg);
|
||||
|
||||
|
||||
#endif // OPENAIRINTERFACE_NR_FAPI_P5_UTILS_H
|
||||
58
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p7.h
Normal file
58
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p7.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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 OPENAIRINTERFACE_NR_FAPI_P7_H
|
||||
#define OPENAIRINTERFACE_NR_FAPI_P7_H
|
||||
|
||||
int fapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config);
|
||||
|
||||
int fapi_nr_p7_message_unpack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
|
||||
uint8_t pack_dl_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_dl_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_ul_tti_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_ul_tti_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_slot_indication(uint8_t **ppReadPackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_nr_slot_indication_scf_t *msg,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_nr_slot_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_ul_dci_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_ul_dci_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_tx_data_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_tx_data_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_nr_rx_data_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_rx_data_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_nr_crc_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_crc_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end);
|
||||
uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
uint8_t pack_nr_slot_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
uint8_t unpack_nr_slot_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config);
|
||||
#endif // OPENAIRINTERFACE_NR_FAPI_P7_H
|
||||
94
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p7_utils.h
Normal file
94
l2-fapi-proxy/open-nFAPI/fapi/inc/nr_fapi_p7_utils.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
/*! \file nfapi/open-nFAPI/fapi/inc/p5/nr_fapi_p5_utils.h
|
||||
* \brief
|
||||
* \author Ruben S. Silva
|
||||
* \date 2024
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef OPENAIRINTERFACE_NR_FAPI_P7_UTILS_H
|
||||
#define OPENAIRINTERFACE_NR_FAPI_P7_UTILS_H
|
||||
#include "stdio.h"
|
||||
#include "stdint.h"
|
||||
#include "nr_fapi.h"
|
||||
|
||||
bool eq_dl_tti_request(const nfapi_nr_dl_tti_request_t *a, const nfapi_nr_dl_tti_request_t *b);
|
||||
bool eq_ul_tti_request(const nfapi_nr_ul_tti_request_t *a, const nfapi_nr_ul_tti_request_t *b);
|
||||
bool eq_slot_indication(const nfapi_nr_slot_indication_scf_t *a, const nfapi_nr_slot_indication_scf_t *b);
|
||||
bool eq_ul_dci_request(const nfapi_nr_ul_dci_request_t *a, const nfapi_nr_ul_dci_request_t *b);
|
||||
bool eq_tx_data_request(const nfapi_nr_tx_data_request_t *a, const nfapi_nr_tx_data_request_t *b);
|
||||
bool eq_rx_data_indication(const nfapi_nr_rx_data_indication_t *a, const nfapi_nr_rx_data_indication_t *b);
|
||||
bool eq_crc_indication(const nfapi_nr_crc_indication_t *a, const nfapi_nr_crc_indication_t *b);
|
||||
bool eq_uci_indication(const nfapi_nr_uci_indication_t *a, const nfapi_nr_uci_indication_t *b);
|
||||
bool eq_srs_indication(const nfapi_nr_srs_indication_t *a, const nfapi_nr_srs_indication_t *b);
|
||||
bool eq_rach_indication(const nfapi_nr_rach_indication_t *a, const nfapi_nr_rach_indication_t *b);
|
||||
|
||||
void free_dl_tti_request(nfapi_nr_dl_tti_request_t *msg);
|
||||
void free_ul_tti_request(nfapi_nr_ul_tti_request_t *msg);
|
||||
void free_slot_indication(nfapi_nr_slot_indication_scf_t *msg);
|
||||
void free_ul_dci_request(nfapi_nr_ul_dci_request_t *msg);
|
||||
void free_tx_data_request(nfapi_nr_tx_data_request_t *msg);
|
||||
void free_rx_data_indication(nfapi_nr_rx_data_indication_t *msg);
|
||||
void free_crc_indication(nfapi_nr_crc_indication_t *msg);
|
||||
void free_uci_indication(nfapi_nr_uci_indication_t *msg);
|
||||
void free_srs_indication(nfapi_nr_srs_indication_t *msg);
|
||||
void free_rach_indication(nfapi_nr_rach_indication_t *msg);
|
||||
|
||||
void copy_dl_tti_request(const nfapi_nr_dl_tti_request_t *src, nfapi_nr_dl_tti_request_t *dst);
|
||||
void copy_dl_tti_request_for_rnti(const nfapi_nr_dl_tti_request_t *src, nfapi_nr_dl_tti_request_t *dst, uint16_t rnti, int* valid_pdu_inds);
|
||||
void copy_ul_tti_request(const nfapi_nr_ul_tti_request_t *src, nfapi_nr_ul_tti_request_t *dst);
|
||||
void copy_ul_tti_request_for_rnti(const nfapi_nr_ul_tti_request_t *src, nfapi_nr_ul_tti_request_t *dst, uint16_t rnti);
|
||||
void copy_slot_indication(const nfapi_nr_slot_indication_scf_t *src, nfapi_nr_slot_indication_scf_t *dst);
|
||||
void copy_ul_dci_request(const nfapi_nr_ul_dci_request_t *src, nfapi_nr_ul_dci_request_t *dst);
|
||||
void copy_ul_dci_request_for_rnti(const nfapi_nr_ul_dci_request_t *src, nfapi_nr_ul_dci_request_t *dst, uint16_t rnti);
|
||||
void copy_tx_data_request(const nfapi_nr_tx_data_request_t *src, nfapi_nr_tx_data_request_t *dst);
|
||||
void copy_tx_data_request_for_rnti(const nfapi_nr_tx_data_request_t *src, nfapi_nr_tx_data_request_t *dst, int *valid_pdu_inds);
|
||||
void copy_rx_data_indication(const nfapi_nr_rx_data_indication_t *src, nfapi_nr_rx_data_indication_t *dst);
|
||||
void copy_crc_indication(const nfapi_nr_crc_indication_t *src, nfapi_nr_crc_indication_t *dst);
|
||||
void copy_uci_indication(const nfapi_nr_uci_indication_t *src, nfapi_nr_uci_indication_t *dst);
|
||||
void copy_srs_indication(const nfapi_nr_srs_indication_t *src, nfapi_nr_srs_indication_t *dst);
|
||||
void copy_rach_indication(const nfapi_nr_rach_indication_t *src, nfapi_nr_rach_indication_t *dst);
|
||||
|
||||
|
||||
size_t get_tx_data_request_size(const nfapi_nr_tx_data_request_t *msg);
|
||||
size_t get_rx_data_indication_size(const nfapi_nr_rx_data_indication_t *msg);
|
||||
size_t get_crc_indication_size(const nfapi_nr_crc_indication_t *msg);
|
||||
size_t get_uci_indication_size(const nfapi_nr_uci_indication_t *msg);
|
||||
size_t get_srs_indication_size(const nfapi_nr_srs_indication_t *msg);
|
||||
size_t get_rach_indication_size(nfapi_nr_rach_indication_t *msg);
|
||||
|
||||
void dump_dl_tti_request(const nfapi_nr_dl_tti_request_t *msg);
|
||||
void dump_ul_tti_request(const nfapi_nr_ul_tti_request_t *msg);
|
||||
void dump_slot_indication(const nfapi_nr_slot_indication_scf_t *msg);
|
||||
void dump_ul_dci_request(const nfapi_nr_ul_dci_request_t *msg);
|
||||
void dump_tx_data_request(const nfapi_nr_tx_data_request_t *msg);
|
||||
void dump_rx_data_indication(const nfapi_nr_rx_data_indication_t *msg);
|
||||
void dump_crc_indication(const nfapi_nr_crc_indication_t *msg);
|
||||
void dump_uci_indication(const nfapi_nr_uci_indication_t *msg);
|
||||
void dump_srs_indication(const nfapi_nr_srs_indication_t *msg);
|
||||
void dump_rach_indication(const nfapi_nr_rach_indication_t *msg);
|
||||
|
||||
#endif // OPENAIRINTERFACE_NR_FAPI_P7_UTILS_H
|
||||
192
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi.c
Normal file
192
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi.c
Normal file
@@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
#include "nr_fapi.h"
|
||||
|
||||
void copy_vendor_extension_value(nfapi_vendor_extension_tlv_t *dst, const nfapi_vendor_extension_tlv_t *src)
|
||||
{
|
||||
nfapi_tl_t *dst_tlv = (nfapi_tl_t *)dst;
|
||||
nfapi_tl_t *src_tlv = (nfapi_tl_t *)src;
|
||||
|
||||
switch (dst_tlv->tag) {
|
||||
case VENDOR_EXT_TLV_2_TAG: {
|
||||
vendor_ext_tlv_2 *dst_ve = (vendor_ext_tlv_2 *)dst_tlv;
|
||||
vendor_ext_tlv_2 *src_ve = (vendor_ext_tlv_2 *)src_tlv;
|
||||
|
||||
dst_ve->dummy = src_ve->dummy;
|
||||
} break;
|
||||
case VENDOR_EXT_TLV_1_TAG: {
|
||||
vendor_ext_tlv_1 *dst_ve = (vendor_ext_tlv_1 *)dst_tlv;
|
||||
vendor_ext_tlv_1 *src_ve = (vendor_ext_tlv_1 *)src_tlv;
|
||||
|
||||
dst_ve->dummy = src_ve->dummy;
|
||||
} break;
|
||||
default:
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Unknown Vendor Extension tag %d\n", dst_tlv->tag);
|
||||
}
|
||||
}
|
||||
|
||||
bool isFAPIMessageIDValid(const uint16_t id)
|
||||
{
|
||||
// SCF 222.10.04 Table 3-5 PHY API message types
|
||||
return (id >= NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST && id <= 0xFF) || id == NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE
|
||||
|| id == NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC || id == NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC
|
||||
|| id == NFAPI_NR_PHY_MSG_TYPE_TIMING_INFO;
|
||||
}
|
||||
|
||||
int check_nr_fapi_unpack_length(nfapi_nr_phy_msg_type_e msgId, uint32_t unpackedBufLen)
|
||||
{
|
||||
int retLen = 0;
|
||||
|
||||
// check for size of nFAPI struct without the nFAPI specific parameters
|
||||
switch (msgId) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_param_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
|
||||
retLen = sizeof(fapi_message_header_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_param_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t) - sizeof(nfapi_nr_nfapi_t))
|
||||
retLen = sizeof(nfapi_nr_param_request_scf_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_config_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t) - sizeof(nfapi_nr_nfapi_t))
|
||||
retLen = sizeof(nfapi_nr_config_request_scf_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_config_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
|
||||
retLen = sizeof(nfapi_nr_config_response_scf_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_start_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
|
||||
retLen = sizeof(fapi_message_header_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_start_response_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
|
||||
retLen = sizeof(fapi_message_header_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_stop_request_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
|
||||
retLen = sizeof(fapi_message_header_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_stop_indication_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
|
||||
retLen = sizeof(fapi_message_header_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_error_indication_scf_t) - sizeof(nfapi_vendor_extension_tlv_t))
|
||||
retLen = sizeof(fapi_message_header_t);
|
||||
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_dl_tti_request_t))
|
||||
retLen = sizeof(nfapi_nr_dl_tti_request_t);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_ul_tti_request_t))
|
||||
retLen = sizeof(nfapi_nr_ul_tti_request_t);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_slot_indication_scf_t))
|
||||
retLen = sizeof(nfapi_nr_slot_indication_scf_t);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_ul_dci_request_t))
|
||||
retLen = sizeof(nfapi_nr_ul_dci_request_t);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_tx_data_request_t))
|
||||
retLen = sizeof(nfapi_nr_tx_data_request_t);
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_rx_data_indication_t))
|
||||
retLen = sizeof(nfapi_nr_rx_data_indication_t);
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_crc_indication_t))
|
||||
retLen = sizeof(nfapi_nr_crc_indication_t);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_rach_indication_t))
|
||||
retLen = sizeof(nfapi_nr_rach_indication_t);
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_uci_indication_t))
|
||||
retLen = sizeof(nfapi_nr_uci_indication_t);
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_srs_indication_t))
|
||||
retLen = sizeof(nfapi_nr_srs_indication_t);
|
||||
break;
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_NODE_SYNC:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_dl_node_sync_t))
|
||||
retLen = sizeof(nfapi_nr_dl_node_sync_t);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_NODE_SYNC:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_ul_node_sync_t))
|
||||
retLen = sizeof(nfapi_nr_ul_node_sync_t);
|
||||
break;
|
||||
|
||||
case NFAPI_NR_PHY_MSG_TYPE_VENDOR_EXT_SLOT_RESPONSE:
|
||||
if (unpackedBufLen >= sizeof(nfapi_nr_slot_response_t))
|
||||
retLen = sizeof(nfapi_nr_slot_response_t);
|
||||
break;
|
||||
default:
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Unknown message ID %d\n", __FUNCTION__, msgId);
|
||||
break;
|
||||
}
|
||||
|
||||
return retLen;
|
||||
}
|
||||
|
||||
int fapi_nr_message_header_unpack(uint8_t **pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p4_p5_codec_config_t *config)
|
||||
{
|
||||
uint8_t **pReadPackedMessage = pMessageBuf;
|
||||
nfapi_nr_p4_p5_message_header_t *header = pUnpackedBuf;
|
||||
fapi_message_header_t fapi_msg = {0};
|
||||
|
||||
if (pMessageBuf == NULL || pUnpackedBuf == NULL || messageBufLen < NFAPI_HEADER_LENGTH
|
||||
|| unpackedBufLen < sizeof(fapi_message_header_t)) {
|
||||
return -1;
|
||||
}
|
||||
uint8_t *end = *pMessageBuf + messageBufLen;
|
||||
// process the header
|
||||
int result =
|
||||
(pull8(pReadPackedMessage, &fapi_msg.num_msg, end) && pull8(pReadPackedMessage, &fapi_msg.opaque_handle, end)
|
||||
&& pull16(pReadPackedMessage, &header->message_id, end) && pull32(pReadPackedMessage, &header->message_length, end));
|
||||
return (result);
|
||||
}
|
||||
1772
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p5.c
Normal file
1772
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p5.c
Normal file
File diff suppressed because it is too large
Load Diff
1508
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
Normal file
1508
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p5_utils.c
Normal file
File diff suppressed because it is too large
Load Diff
2479
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p7.c
Normal file
2479
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p7.c
Normal file
File diff suppressed because it is too large
Load Diff
3113
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p7_utils.c
Normal file
3113
l2-fapi-proxy/open-nFAPI/fapi/src/nr_fapi_p7_utils.c
Normal file
File diff suppressed because it is too large
Load Diff
29
l2-fapi-proxy/open-nFAPI/integration_tests/Makefile.am
Normal file
29
l2-fapi-proxy/open-nFAPI/integration_tests/Makefile.am
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#vnf unit test
|
||||
AM_CPPFLAGS = -I../nfapi/inc -I../nfapi/public_inc -I../common/public_inc -I../vnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
|
||||
|
||||
export LD_LIBRARY_PATH=/opt/gcc-4.7.3/lib
|
||||
check_PROGRAMS= nfapi_integration_tests
|
||||
nfapi_integration_tests_SOURCES = main.cpp ../common/src/debug.c
|
||||
nfapi_integration_tests_LDADD= -L$(libdir) -lpthread -lrt -lcunit
|
||||
|
||||
|
||||
|
||||
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
|
||||
TESTS=nfapi_integration_tests
|
||||
EXTRA_DIST=$(TESTS)
|
||||
269
l2-fapi-proxy/open-nFAPI/integration_tests/main.cpp
Normal file
269
l2-fapi-proxy/open-nFAPI/integration_tests/main.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CUnit.h"
|
||||
#include "Basic.h"
|
||||
#include "Automated.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
int start_vnf_proc(int port)
|
||||
{
|
||||
char port_str[10];
|
||||
sprintf(port_str, "%d", port);
|
||||
|
||||
const char *argv[] = {"vnfsim", port_str, "../xml/vnf_A.xml", NULL};
|
||||
int pid = fork();
|
||||
|
||||
if(pid == 0)
|
||||
{
|
||||
int result = execv("../vnf_sim/vnfsim", (char* const*)argv); //, env_args);
|
||||
if(result == -1)
|
||||
{
|
||||
printf("Failed to exec vnf process %d\n", errno);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
|
||||
int start_pnf_proc(const char* addr, int port, const char* file)
|
||||
{
|
||||
char port_str[10];
|
||||
sprintf(port_str, "%d", port);
|
||||
|
||||
char filename[256];
|
||||
sprintf(filename, "../xml/%s", file);
|
||||
|
||||
const char * argv[] = {"pnfsim", addr, port_str, filename, NULL};
|
||||
int pid = fork();
|
||||
|
||||
if(pid == 0)
|
||||
{
|
||||
int result = execv("../pnf_sim/pnfsim", (char* const*)argv); //, env_args);
|
||||
if(result == -1)
|
||||
{
|
||||
printf("Failed to exec pnf process %d\n", errno);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
|
||||
int kill_proc(int pid)
|
||||
{
|
||||
kill(pid, SIGKILL);
|
||||
|
||||
int status;
|
||||
int waitpid_result = waitpid(pid, &status, 0);
|
||||
|
||||
return waitpid_result;
|
||||
}
|
||||
|
||||
|
||||
void test_1()
|
||||
{
|
||||
|
||||
int pnf_port = 5655;
|
||||
const char* pnf_addr = "localhost";
|
||||
|
||||
printf("**** starting vnf *****\n");
|
||||
int vnf_pid = start_vnf_proc(pnf_port);
|
||||
|
||||
printf("**** starting pnf *****\n");
|
||||
int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
|
||||
|
||||
|
||||
sleep(10);
|
||||
|
||||
printf ("*** Terminating ****\n");
|
||||
kill_proc(vnf_pid);
|
||||
kill_proc(pnf1_pid);
|
||||
}
|
||||
void test_1a()
|
||||
{
|
||||
|
||||
int pnf_port = 5655;
|
||||
const char* pnf_addr = "localhost";
|
||||
|
||||
printf("**** starting vnf *****\n");
|
||||
int vnf_pid = start_vnf_proc(pnf_port);
|
||||
|
||||
printf("**** starting pnf *****\n");
|
||||
int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_2_A.xml");
|
||||
|
||||
|
||||
sleep(10);
|
||||
|
||||
printf ("*** Terminating ****\n");
|
||||
kill_proc(vnf_pid);
|
||||
kill_proc(pnf1_pid);
|
||||
}
|
||||
|
||||
|
||||
void test_2()
|
||||
{
|
||||
int pnf_port = 5655;
|
||||
const char* pnf_addr = "127.0.0.1";
|
||||
|
||||
int vnf_pid = start_vnf_proc(pnf_port);
|
||||
sleep(2);
|
||||
|
||||
int pnf1_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
|
||||
int pnf2_pid = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
|
||||
|
||||
sleep(2);
|
||||
|
||||
kill_proc(pnf2_pid);
|
||||
kill_proc(pnf1_pid);
|
||||
kill_proc(vnf_pid);
|
||||
}
|
||||
|
||||
void test_32()
|
||||
{
|
||||
int pnf_count = 32;
|
||||
int pnf_pid[pnf_count];
|
||||
|
||||
int pnf_port = 5655;
|
||||
const char* pnf_addr = "127.0.0.1";
|
||||
|
||||
int vnf_pid = start_vnf_proc(pnf_port);
|
||||
sleep(2);
|
||||
|
||||
for(int i = 0; i < pnf_count; ++i)
|
||||
{
|
||||
pnf_pid[i] = start_pnf_proc(pnf_addr, pnf_port, "pnf_phy_1_A.xml");
|
||||
}
|
||||
|
||||
sleep(5);
|
||||
|
||||
printf ("*** Terminating pnfs\n");
|
||||
|
||||
for(int i = 0; i < pnf_count; ++i)
|
||||
{
|
||||
kill_proc(pnf_pid[i]);
|
||||
}
|
||||
printf ("*** Terminating vnf\n");
|
||||
kill_proc(vnf_pid);
|
||||
}
|
||||
|
||||
|
||||
int init_suite()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int clean_suite()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
CU_pSuite pSuite = NULL;
|
||||
|
||||
/* initialize the CUnit test registry */
|
||||
if ( CUE_SUCCESS != CU_initialize_registry() )
|
||||
return CU_get_error();
|
||||
|
||||
/* add a suite to the registry */
|
||||
pSuite = CU_add_suite( "integration_test_suite", init_suite, clean_suite );
|
||||
if ( NULL == pSuite )
|
||||
{
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
//(NULL == CU_add_test(pSuite, "vnf_test_start_connect_2", vnf_test_start_connect_2))
|
||||
/* add the tests to the suite */
|
||||
if ( (NULL == CU_add_test(pSuite, "test_1a", test_1a))
|
||||
// (NULL == CU_add_test(pSuite, "test_2", test_2)) ||
|
||||
// (NULL == CU_add_test(pSuite, "test_32", test_32))
|
||||
)
|
||||
{
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
}
|
||||
|
||||
// Run all tests using the basic interface
|
||||
CU_basic_set_mode(CU_BRM_VERBOSE);
|
||||
CU_set_output_filename("vnf_unit_test_results.xml");
|
||||
CU_basic_run_tests();
|
||||
|
||||
CU_pSuite s = CU_get_registry()->pSuite;
|
||||
int count = 0;
|
||||
while(s)
|
||||
{
|
||||
CU_pTest t = s->pTest;
|
||||
while(t)
|
||||
{
|
||||
count++;
|
||||
t = t->pNext;
|
||||
}
|
||||
s = s->pNext;
|
||||
}
|
||||
|
||||
printf("%d..%d\n", 1, count);
|
||||
|
||||
|
||||
|
||||
s = CU_get_registry()->pSuite;
|
||||
count = 1;
|
||||
while(s)
|
||||
{
|
||||
CU_pTest t = s->pTest;
|
||||
while(t)
|
||||
{
|
||||
int pass = 1;
|
||||
CU_FailureRecord* failures = CU_get_failure_list();
|
||||
while(failures)
|
||||
{
|
||||
if(strcmp(failures->pSuite->pName, s->pName) == 0 &&
|
||||
strcmp(failures->pTest->pName, t->pName) == 0)
|
||||
{
|
||||
pass = 0;
|
||||
failures = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
failures = failures->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
if(pass)
|
||||
printf("ok %d - %s:%s\n", count, s->pName, t->pName);
|
||||
else
|
||||
printf("not ok %d - %s:%s\n", count, s->pName, t->pName);
|
||||
|
||||
count++;
|
||||
t = t->pNext;
|
||||
}
|
||||
s = s->pNext;
|
||||
}
|
||||
|
||||
CU_cleanup_registry();
|
||||
return CU_get_error();
|
||||
|
||||
}
|
||||
30
l2-fapi-proxy/open-nFAPI/nfapi/Makefile.am
Normal file
30
l2-fapi-proxy/open-nFAPI/nfapi/Makefile.am
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(BOOST_CPPFLAGS) -Wall -Werror -g
|
||||
|
||||
noinst_LIBRARIES = libnfapi.a
|
||||
|
||||
libnfapi_a_SOURCES = src/nfapi.c src/nfapi_p5.c src/nfapi_p7.c src/nfapi_p4.c
|
||||
libnfapi_a_CFLAGS =$(AM_CFLAGS)
|
||||
|
||||
lib_LTLIBRARIES = libnfapi.la
|
||||
libnfapi_la_SOURCES = src/nfapi.c src/nfapi_p5.c src/nfapi_p7.c src/nfapi_p4.c
|
||||
|
||||
|
||||
LDADD= ../pnf/src/libnfapi_pnf.a ../vnf/src/libnfapi_vnf.a ../common/bin/libnfapi_common.a
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#ifndef _FAPI_NR_UE_CONSTANTS_H_
|
||||
#define _FAPI_NR_UE_CONSTANTS_H_
|
||||
|
||||
// constants defined by specification 38.331
|
||||
#define FAPI_NR_MAX_NUM_DL_ALLOCATIONS 16
|
||||
#define FAPI_NR_MAX_NUM_UL_ALLOCATIONS 16
|
||||
#define FAPI_NR_MAX_NUM_SERVING_CELLS 32
|
||||
#define FAPI_NR_MAX_NUM_ZP_CSI_RS_RESOURCE_PER_SET 16
|
||||
#define FAPI_NR_MAX_NUM_CANDIDATE_BEAMS 16
|
||||
#define FAPI_NR_MAX_RA_OCCASION_PER_CSIRS 64
|
||||
// Constants Defined in 38.213
|
||||
#define FAPI_NR_MAX_CORESET_PER_BWP 3
|
||||
#define FAPI_NR_MAX_SS_PER_BWP 10
|
||||
#define FAPI_NR_MAX_SS FAPI_NR_MAX_SS_PER_BWP*NR_MAX_NUM_BWP
|
||||
|
||||
|
||||
/// RX_IND
|
||||
#define FAPI_NR_RX_PDU_TYPE_SSB 0x01
|
||||
#define FAPI_NR_RX_PDU_TYPE_SIB 0x02
|
||||
#define FAPI_NR_RX_PDU_TYPE_DLSCH 0x03
|
||||
#define FAPI_NR_DCI_IND 0x04
|
||||
#define FAPI_NR_RX_PDU_TYPE_RAR 0x05
|
||||
#define FAPI_NR_CSIRS_IND 0x06
|
||||
|
||||
#define FAPI_NR_SIBS_MASK_SIB1 0x1
|
||||
|
||||
|
||||
/// DCI_IND
|
||||
#define FAPI_NR_DCI_TYPE_0_0 0x01
|
||||
#define FAPI_NR_DCI_TYPE_0_1 0x02
|
||||
#define FAPI_NR_DCI_TYPE_1_0 0x03
|
||||
#define FAPI_NR_DCI_TYPE_1_1 0x04
|
||||
#define FAPI_NR_DCI_TYPE_2_0 0x05
|
||||
#define FAPI_NR_DCI_TYPE_2_1 0x06
|
||||
#define FAPI_NR_DCI_TYPE_2_2 0x07
|
||||
#define FAPI_NR_DCI_TYPE_2_3 0x08
|
||||
|
||||
|
||||
/// TX_REQ
|
||||
|
||||
|
||||
/// DL_CONFIG_REQ
|
||||
|
||||
#define FAPI_NR_DL_CONFIG_LIST_NUM 10
|
||||
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_DCI 0x01
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_DLSCH 0x02
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH 0x03
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_SI_DLSCH 0x04
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_P_DLSCH 0x05
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_CSI_RS 0x06
|
||||
#define FAPI_NR_DL_CONFIG_TYPE_CSI_IM 0x07
|
||||
#define FAPI_NR_CONFIG_TA_COMMAND 0x08
|
||||
#define FAPI_NR_DL_NTN_CONFIG_PARAMS 0x09
|
||||
#define FAPI_NR_DL_CONFIG_TYPES 0x09
|
||||
|
||||
|
||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED 0x01
|
||||
#define FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED 0x02
|
||||
|
||||
#define PRECODER_GRANULARITY_SAME_AS_REG_BUNDLE 0x01
|
||||
#define PRECODER_GRANULARITY_ALL_CONTIGUOUS_RBS 0x02
|
||||
|
||||
/// UL_CONFIG_REQ
|
||||
#define FAPI_NR_UL_CONFIG_LIST_NUM 10
|
||||
|
||||
#define FAPI_NR_UL_CONFIG_TYPE_DONE 0x00
|
||||
#define FAPI_NR_UL_CONFIG_TYPE_PRACH 0x01
|
||||
#define FAPI_NR_UL_CONFIG_TYPE_PUCCH 0x02
|
||||
#define FAPI_NR_UL_CONFIG_TYPE_PUSCH 0x03
|
||||
#define FAPI_NR_UL_CONFIG_TYPE_SRS 0x04
|
||||
#define FAPI_NR_UL_CONFIG_TYPES 0x04
|
||||
|
||||
#define FAPI_NR_END 0xff
|
||||
#endif
|
||||
717
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
Normal file
717
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/fapi_nr_ue_interface.h
Normal file
@@ -0,0 +1,717 @@
|
||||
/*Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _FAPI_NR_UE_INTERFACE_H_
|
||||
#define _FAPI_NR_UE_INTERFACE_H_
|
||||
#include <pthread.h>
|
||||
|
||||
#include "stddef.h"
|
||||
#include "common/platform_types.h"
|
||||
#include "fapi_nr_ue_constants.h"
|
||||
#include "PHY/impl_defs_top.h"
|
||||
#include "PHY/impl_defs_nr.h"
|
||||
#include "common/utils/nr/nr_common.h"
|
||||
|
||||
#define NFAPI_UE_MAX_NUM_CB 8
|
||||
#define NFAPI_MAX_NUM_UL_PDU 255
|
||||
#define NFAPI_MAX_NUM_CSI_RATEMATCH 4
|
||||
|
||||
/*
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef signed int int32_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed char int8_t;
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
RLM_no_monitoring = 0,
|
||||
RLM_out_of_sync = 1,
|
||||
RLM_in_sync = 2
|
||||
} rlm_t;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_FORMAT_0_0_AND_1_0,
|
||||
NFAPI_NR_FORMAT_0_1_AND_1_1,
|
||||
} nfapi_nr_dci_formats_e;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t rsrp;
|
||||
int rsrp_dBm;
|
||||
uint8_t rank_indicator;
|
||||
uint16_t i1;
|
||||
uint8_t i2;
|
||||
uint8_t cqi;
|
||||
rlm_t radiolink_monitoring;
|
||||
} fapi_nr_csirs_measurements_t;
|
||||
|
||||
typedef struct {
|
||||
/// frequency_domain_resource;
|
||||
uint8_t frequency_domain_resource[6];
|
||||
uint8_t StartSymbolIndex;
|
||||
uint8_t duration;
|
||||
uint8_t CceRegMappingType; // interleaved or noninterleaved
|
||||
uint8_t RegBundleSize; // valid if CCE to REG mapping type is interleaved type
|
||||
uint8_t InterleaverSize; // valid if CCE to REG mapping type is interleaved type
|
||||
uint8_t ShiftIndex; // valid if CCE to REG mapping type is interleaved type
|
||||
uint8_t CoreSetType;
|
||||
uint8_t precoder_granularity;
|
||||
uint16_t pdcch_dmrs_scrambling_id;
|
||||
uint16_t scrambling_rnti;
|
||||
uint8_t tci_state_pdcch;
|
||||
uint8_t tci_present_in_dci;
|
||||
} fapi_nr_coreset_t;
|
||||
|
||||
//
|
||||
// Top level FAPI messages
|
||||
//
|
||||
|
||||
|
||||
|
||||
//
|
||||
// P7
|
||||
//
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
nfapi_nr_dci_formats_e dci_format;
|
||||
uint8_t coreset_type;
|
||||
int ss_type;
|
||||
// n_CCE index of first CCE for PDCCH reception
|
||||
int n_CCE;
|
||||
// N_CCE is L, or number of CCEs for DCI
|
||||
int N_CCE;
|
||||
int cset_start;
|
||||
uint8_t payloadSize;
|
||||
uint8_t payloadBits[16] __attribute__((aligned(16))); // will be cast as uint64
|
||||
} fapi_nr_dci_indication_pdu_t;
|
||||
|
||||
|
||||
///
|
||||
typedef struct {
|
||||
uint16_t SFN;
|
||||
uint8_t slot;
|
||||
uint16_t number_of_dcis;
|
||||
fapi_nr_dci_indication_pdu_t dci_list[10];
|
||||
} fapi_nr_dci_indication_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t harq_pid;
|
||||
uint8_t ack_nack;
|
||||
uint32_t pdu_length;
|
||||
uint8_t* pdu;
|
||||
} fapi_nr_pdsch_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
bool decoded_pdu;
|
||||
uint8_t pdu[3];
|
||||
uint8_t additional_bits;
|
||||
uint8_t ssb_index;
|
||||
uint8_t ssb_length;
|
||||
uint16_t cell_id;
|
||||
uint16_t ssb_start_subcarrier;
|
||||
short rsrp_dBm;
|
||||
long arfcn;
|
||||
rlm_t radiolink_monitoring; // -1 no monitoring, 0 out_of_sync, 1 in_sync
|
||||
// SINR value times 10 as reporting granularity is 0.5
|
||||
float sinr_dB;
|
||||
} fapi_nr_ssb_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t pdu_length;
|
||||
uint8_t* pdu;
|
||||
uint32_t sibs_mask;
|
||||
} fapi_nr_sib_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t pdu_type;
|
||||
union {
|
||||
fapi_nr_pdsch_pdu_t pdsch_pdu;
|
||||
fapi_nr_ssb_pdu_t ssb_pdu;
|
||||
fapi_nr_sib_pdu_t sib_pdu;
|
||||
fapi_nr_csirs_measurements_t csirs_measurements;
|
||||
};
|
||||
} fapi_nr_rx_indication_body_t;
|
||||
|
||||
///
|
||||
#define NFAPI_RX_IND_MAX_PDU 100
|
||||
typedef struct {
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
uint16_t number_pdus;
|
||||
fapi_nr_rx_indication_body_t rx_indication_body[NFAPI_RX_IND_MAX_PDU];
|
||||
} fapi_nr_rx_indication_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t ul_cqi;
|
||||
uint16_t timing_advance;
|
||||
uint16_t rnti;
|
||||
} fapi_nr_tx_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t pdu_length;
|
||||
uint8_t* fapiTxPdu;
|
||||
} fapi_nr_tx_request_body_t;
|
||||
|
||||
///
|
||||
typedef struct {
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
fapi_nr_tx_config_t tx_config;
|
||||
uint16_t number_of_pdus;
|
||||
fapi_nr_tx_request_body_t tx_request_body[NFAPI_MAX_NUM_UL_PDU];
|
||||
} fapi_nr_tx_request_t;
|
||||
|
||||
/// This struct replaces:
|
||||
/// PRACH-ConfigInfo from 38.331 RRC spec
|
||||
/// PRACH-ConfigSIB or PRACH-Config
|
||||
typedef struct {
|
||||
/// PHY cell ID
|
||||
uint16_t phys_cell_id;
|
||||
/// Num PRACH occasions
|
||||
uint8_t num_prach_ocas;
|
||||
/// PRACH format
|
||||
uint8_t prach_format;
|
||||
/// Num RA
|
||||
uint8_t num_ra;
|
||||
uint8_t prach_slot;
|
||||
uint8_t prach_start_symbol;
|
||||
/// 38.211 (NCS 38.211 6.3.3.1).
|
||||
uint16_t num_cs;
|
||||
/// Parameter: prach-rootSequenceIndex, see TS 38.211 (6.3.3.2).
|
||||
uint16_t root_seq_id;
|
||||
/// Parameter: High-speed-flag, see TS 38.211 (6.3.3.1). 1 corresponds to Restricted set and 0 to Unrestricted set.
|
||||
uint8_t restricted_set;
|
||||
/// see TS 38.211 (6.3.3.2).
|
||||
uint16_t freq_msg1;
|
||||
/// Preamble index for PRACH (0-63)
|
||||
uint8_t ra_PreambleIndex;
|
||||
/// PRACH TX power (TODO possibly modify to uint)
|
||||
int16_t prach_tx_power;
|
||||
} fapi_nr_ul_config_prach_pdu;
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
uint16_t bwp_size;
|
||||
uint16_t bwp_start;
|
||||
uint8_t format_type;
|
||||
uint8_t start_symbol_index;
|
||||
uint8_t nr_of_symbols;
|
||||
uint16_t prb_start;
|
||||
uint16_t prb_size;
|
||||
uint32_t hopping_id;
|
||||
uint8_t freq_hop_flag;
|
||||
uint8_t group_hop_flag;
|
||||
uint8_t sequence_hop_flag;
|
||||
uint16_t second_hop_prb;
|
||||
uint16_t initial_cyclic_shift;
|
||||
uint8_t time_domain_occ_idx;
|
||||
uint8_t add_dmrs_flag;
|
||||
uint16_t dmrs_scrambling_id;
|
||||
uint16_t data_scrambling_id;
|
||||
uint8_t dmrs_cyclic_shift;
|
||||
uint8_t pi_2bpsk;
|
||||
uint8_t mcs;
|
||||
uint8_t pre_dft_occ_idx;
|
||||
uint8_t pre_dft_occ_len;
|
||||
int16_t pucch_tx_power;
|
||||
uint32_t n_bit;
|
||||
uint64_t payload;
|
||||
} fapi_nr_ul_config_pucch_pdu;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t rv_index;
|
||||
uint8_t harq_process_id;
|
||||
bool new_data_indicator;
|
||||
uint32_t tb_size;
|
||||
uint16_t num_cb;
|
||||
uint8_t cb_present_and_position[(NFAPI_UE_MAX_NUM_CB+7) / 8];
|
||||
|
||||
} nfapi_nr_ue_pusch_data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// payloads with fixed array size
|
||||
// no place to free the dinamically allocated
|
||||
// vector without L1 implementation
|
||||
uint16_t harq_ack_bit_length;
|
||||
uint64_t harq_payload;
|
||||
uint16_t csi_part1_bit_length;
|
||||
uint64_t csi_part1_payload;
|
||||
uint16_t csi_part2_bit_length;
|
||||
uint64_t csi_part2_payload;
|
||||
uint8_t alpha_scaling; // 0 = 0.5, 1 = 0.65, 2 = 0.8, 3 = 1
|
||||
uint8_t beta_offset_harq_ack;
|
||||
uint8_t beta_offset_csi1;
|
||||
uint8_t beta_offset_csi2;
|
||||
|
||||
} nfapi_nr_ue_pusch_uci_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t ptrs_port_index;//PT-RS antenna ports [TS38.214, sec6.2.3.1 and 38.212, section 7.3.1.1.2] Bitmap occupying the 12 LSBs with: bit 0: antenna port 0 bit 11: antenna port 11 and for each bit 0: PTRS port not used 1: PTRS port used
|
||||
uint8_t ptrs_dmrs_port;//DMRS port corresponding to PTRS.
|
||||
uint8_t ptrs_re_offset;//PT-RS resource element offset value taken from 0~11
|
||||
} nfapi_nr_ue_ptrs_ports_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t num_ptrs_ports;
|
||||
nfapi_nr_ue_ptrs_ports_t* ptrs_ports_list;
|
||||
uint8_t ptrs_time_density;
|
||||
uint8_t ptrs_freq_density;
|
||||
uint8_t ul_ptrs_power;
|
||||
|
||||
}nfapi_nr_ue_pusch_ptrs_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t low_papr_group_number;//Group number for Low PAPR sequence generation.
|
||||
uint16_t low_papr_sequence_number;//[TS38.211, sec 5.2.2] For DFT-S-OFDM.
|
||||
uint8_t ul_ptrs_sample_density;//Number of PTRS groups [But I suppose this sentence is misplaced, so as the next one. --Chenyu]
|
||||
uint8_t ul_ptrs_time_density_transform_precoding;//Number of samples per PTRS group
|
||||
|
||||
} nfapi_nr_ue_dfts_ofdm_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t beam_idx;//Index of the digital beam weight vector pre-stored at cell configuration. The vector maps this input port to output TXRUs. Value: 0->65535
|
||||
|
||||
}nfapi_nr_ue_dig_bf_interface_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
nfapi_nr_ue_dig_bf_interface_t* dig_bf_interface_list;
|
||||
|
||||
} nfapi_nr_ue_ul_beamforming_number_of_prgs_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t num_prgs;
|
||||
uint16_t prg_size;
|
||||
//watchout: dig_bf_interface here, in table 3-43 it's dig_bf_interfaces
|
||||
uint8_t dig_bf_interface;
|
||||
nfapi_nr_ue_ul_beamforming_number_of_prgs_t* prgs_list;//
|
||||
|
||||
} nfapi_nr_ue_ul_beamforming_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t pdu_bit_map;//Bitmap indicating presence of optional PDUs (see above)
|
||||
uint16_t rnti;
|
||||
uint32_t handle;//An opaque handling returned in the RxData.indication and/or UCI.indication message
|
||||
//BWP
|
||||
uint16_t bwp_size;
|
||||
uint16_t bwp_start;
|
||||
uint8_t subcarrier_spacing;
|
||||
uint8_t cyclic_prefix;
|
||||
//pusch information always include
|
||||
uint16_t target_code_rate;
|
||||
uint8_t qam_mod_order;
|
||||
uint8_t mcs_index;
|
||||
uint8_t mcs_table;
|
||||
uint8_t transform_precoding;
|
||||
uint16_t data_scrambling_id;
|
||||
uint8_t nrOfLayers;
|
||||
uint8_t Tpmi;
|
||||
//DMRS
|
||||
uint16_t ul_dmrs_symb_pos;
|
||||
uint8_t dmrs_config_type;
|
||||
uint16_t ul_dmrs_scrambling_id;
|
||||
uint8_t scid;
|
||||
uint8_t num_dmrs_cdm_grps_no_data;
|
||||
uint16_t dmrs_ports;//DMRS ports. [TS38.212 7.3.1.1.2] provides description between DCI 0-1 content and DMRS ports. Bitmap occupying the 11 LSBs with: bit 0: antenna port 1000 bit 11: antenna port 1011 and for each bit 0: DMRS port not used 1: DMRS port used
|
||||
//Pusch Allocation in frequency domain [TS38.214, sec 6.1.2.2]
|
||||
uint8_t resource_alloc;
|
||||
uint8_t rb_bitmap[36];
|
||||
uint16_t rb_start;
|
||||
uint16_t rb_size;
|
||||
uint8_t vrb_to_prb_mapping;
|
||||
uint8_t frequency_hopping;
|
||||
uint16_t tx_direct_current_location;//The uplink Tx Direct Current location for the carrier. Only values in the value range of this field between 0 and 3299, which indicate the subcarrier index within the carrier corresponding 1o the numerology of the corresponding uplink BWP and value 3300, which indicates "Outside the carrier" and value 3301, which indicates "Undetermined position within the carrier" are used. [TS38.331, UplinkTxDirectCurrentBWP IE]
|
||||
uint8_t uplink_frequency_shift_7p5khz;
|
||||
//Resource Allocation in time domain
|
||||
uint8_t start_symbol_index;
|
||||
uint8_t nr_of_symbols;
|
||||
uint32_t tbslbrm;
|
||||
uint8_t ldpcBaseGraph;
|
||||
uint8_t ulsch_indicator;
|
||||
//Optional Data only included if indicated in pduBitmap
|
||||
nfapi_nr_ue_pusch_data_t pusch_data;
|
||||
nfapi_nr_ue_pusch_uci_t pusch_uci;
|
||||
nfapi_nr_ue_pusch_ptrs_t pusch_ptrs;
|
||||
nfapi_nr_ue_dfts_ofdm_t dfts_ofdm;
|
||||
//beamforming
|
||||
nfapi_nr_ue_ul_beamforming_t beamforming;
|
||||
//OAI specific
|
||||
int16_t tx_power;
|
||||
fapi_nr_tx_request_body_t tx_request_body;
|
||||
} nfapi_nr_ue_pusch_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
} fapi_nr_ul_srs_parms_v4;
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti; // UE RNTI, Value: 1->65535
|
||||
uint32_t handle; // An opaque handling returned in the SRS.indication
|
||||
uint16_t bwp_size; // Bandwidth part size [3GPP TS 38.213, sec 12]. Number of contiguous PRBs allocated to the BWP, Value: 1->275
|
||||
uint16_t bwp_start; // Bandwidth part start RB index from reference CRB [3GPP TS 38.213, sec 12], Value: 0->274
|
||||
uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
|
||||
uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
|
||||
uint8_t num_ant_ports; // Number of antenna ports N_SRS_ap [3GPP TS 38.211, Sec 6.4.1.4.1], Value: 0 = 1 port, 1 = 2 ports, 2 = 4 ports
|
||||
uint8_t num_symbols; // Number of symbols N_SRS_symb [3GPP TS 38.211, Sec 6.4.1.4.1], Value: 0 = 1 symbol, 1 = 2 symbols, 2 = 4 symbols
|
||||
uint8_t num_repetitions; // Repetition factor R [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 = 1, 1 = 2, 2 = 4
|
||||
uint8_t time_start_position; // Starting position in the time domain l_0 [3GPP TS 38.211, Sec 6.4.1.4.1], Note: the MAC undertakes the translation from startPosition to l_0, Value: 0 --> 13
|
||||
uint8_t config_index; // SRS bandwidth config index C_SRS [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 63
|
||||
uint16_t sequence_id; // SRS sequence ID n_SRS_ID [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 --> 1023
|
||||
uint8_t bandwidth_index; // SRS bandwidth index B_SRS [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 3
|
||||
uint8_t comb_size; // Transmission comb size K_TC [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 = comb size 2, 1 = comb size 4, 2 = comb size 8 (Rel16)
|
||||
uint8_t comb_offset; // Transmission comb offset K'_TC[3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 1 (combSize = 0), Value: 0 --> 3 (combSize = 1), Value: 0 --> 7 (combSize = 2)
|
||||
uint8_t cyclic_shift; // Cyclic shift n_CS_SRS [3GPP TS 38.211, Sec 6.4.1.4.2], Value: 0 --> 7 (combSize = 0), Value: 0 --> 11 (combSize = 1), Value: 0 --> 5 (combSize = 2)
|
||||
uint8_t frequency_position; // Frequency domain position n_RRC [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 67
|
||||
uint16_t frequency_shift; // Frequency domain shift n_shift [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 268
|
||||
uint8_t frequency_hopping; // Frequency hopping b_hop [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0 --> 3
|
||||
uint8_t group_or_sequence_hopping; // Group or sequence hopping configuration (RRC parameter groupOrSequenceHopping in SRSResource IE), Value: 0 = No hopping, 1 = Group hopping groupOrSequenceHopping, 2 = Sequence hopping
|
||||
uint8_t resource_type; // Type of SRS resource allocation [3GPP TS 38.211, Sec 6.4.1.4.3], Value: 0: aperiodic, 1: semi-persistent, 2: periodic
|
||||
uint16_t t_srs; // SRS-Periodicity in slots [3GPP TS 38.211, Sec 6.4.1.4.4], Value: 1,2,3,4,5,8,10,16,20,32,40,64,80,160,320,640,1280,2560
|
||||
uint16_t t_offset; // Slot offset value [3GPP TS 38.211, Sec 6.4.1.4.3], Value:0->2559
|
||||
nfapi_nr_ue_ul_beamforming_t beamforming;
|
||||
int16_t tx_power;
|
||||
} fapi_nr_ul_config_srs_pdu;
|
||||
|
||||
typedef struct {
|
||||
int pdu_type;
|
||||
union {
|
||||
fapi_nr_ul_config_prach_pdu prach_config_pdu;
|
||||
fapi_nr_ul_config_pucch_pdu pucch_config_pdu;
|
||||
nfapi_nr_ue_pusch_pdu_t pusch_config_pdu;
|
||||
fapi_nr_ul_config_srs_pdu srs_config_pdu;
|
||||
};
|
||||
pthread_mutex_t* lock;
|
||||
int* privateNBpdus;
|
||||
} fapi_nr_ul_config_request_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
int frame;
|
||||
int slot;
|
||||
int number_pdus;
|
||||
fapi_nr_ul_config_request_pdu_t ul_config_list[FAPI_NR_UL_CONFIG_LIST_NUM + 1]; // +1 to have space for iterator ending
|
||||
pthread_mutex_t mutex_ul_config;
|
||||
} fapi_nr_ul_config_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
uint16_t BWPSize;
|
||||
uint16_t BWPStart;
|
||||
uint8_t SubcarrierSpacing;
|
||||
fapi_nr_coreset_t coreset;
|
||||
uint8_t number_of_candidates;
|
||||
uint16_t CCE[64];
|
||||
uint8_t L[64];
|
||||
// 3GPP TS 38.212 Sec. 7.3.1.0, 3GPP TS 138.131 sec. 6.3.2 (SearchSpace)
|
||||
// The maximum number of DCI lengths allowed by the spec are 4, with max 3 for C-RNTI.
|
||||
// But a given search space may only support a maximum of 2 DCI formats at a time
|
||||
// depending on its search space type configured by RRC. Hence for blind decoding, UE
|
||||
// needs to monitor only upto 2 DCI lengths for a given search space.
|
||||
uint8_t num_dci_options; // Num DCIs the UE actually needs to decode (1 or 2)
|
||||
uint8_t dci_length_options[2];
|
||||
nfapi_nr_dci_formats_e dci_format_options[2];
|
||||
uint8_t ss_type_options[2];
|
||||
} fapi_nr_dl_config_dci_dl_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
fapi_nr_dl_config_dci_dl_pdu_rel15_t dci_config_rel15;
|
||||
} fapi_nr_dl_config_dci_pdu;
|
||||
|
||||
typedef struct {
|
||||
uint8_t subcarrier_spacing; // subcarrierSpacing [3GPP TS 38.211, sec 4.2], Value:0->4
|
||||
uint8_t cyclic_prefix; // Cyclic prefix type [3GPP TS 38.211, sec 4.2], 0: Normal; 1: Extended
|
||||
uint16_t start_rb; // PRB where this CSI resource starts related to common resource block #0 (CRB#0). Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSIFrequencyOccupation], Value: 0 ->274
|
||||
uint16_t nr_of_rbs; // Number of PRBs across which this CSI resource spans. Only multiples of 4 are allowed. [3GPP TS 38.331, sec 6.3.2 parameter CSI-FrequencyOccupation], Value: 24 -> 276
|
||||
uint8_t csi_type; // CSI Type [3GPP TS 38.211, sec 7.4.1.5], Value: 0:TRS; 1:CSI-RS NZP; 2:CSI-RS ZP
|
||||
uint8_t row; // Row entry into the CSI Resource location table. [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 1-18
|
||||
uint16_t freq_domain; // Bitmap defining the frequencyDomainAllocation [3GPP TS 38.211, sec 7.4.1.5.3] [3GPP TS 38.331 CSIResourceMapping], Value: Up to the 12 LSBs, actual size is determined by the Row parameter
|
||||
uint8_t symb_l0; // The time domain location l0 and firstOFDMSymbolInTimeDomain [3GPP TS 38.211, sec 7.4.1.5.3], Value: 0->13
|
||||
uint8_t symb_l1; // The time domain location l1 and firstOFDMSymbolInTimeDomain2 [3GPP TS 38.211, sec 7.4.1.5.3], Value: 2->12
|
||||
uint8_t cdm_type; // The cdm-Type field [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: noCDM; 1: fd-CDM2; 2: cdm4-FD2-TD2; 3: cdm8-FD2-TD4
|
||||
uint8_t freq_density; // The density field, p and comb offset (for dot5). [3GPP TS 38.211, sec 7.4.1.5.3 and table 7.4.1.5.3-1], Value: 0: dot5 (even RB); 1: dot5 (odd RB); 2: one; 3: three
|
||||
uint16_t scramb_id; // ScramblingID of the CSI-RS [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->1023
|
||||
uint8_t power_control_offset; // Ratio of PDSCH EPRE to NZP CSI-RSEPRE [3GPP TS 38.214, sec 5.2.2.3.1], Value: 0->23 representing -8 to 15 dB in 1dB steps; 255: L1 is configured with ProfileSSS
|
||||
uint8_t power_control_offset_ss; // Ratio of NZP CSI-RS EPRE to SSB/PBCH block EPRE [3GPP TS 38.214, sec 5.2.2.3.1], Values: 0: -3dB; 1: 0dB; 2: 3dB; 3: 6dB; 255: L1 is configured with ProfileSSS
|
||||
uint8_t measurement_bitmap; // bit 0 RSRP, bit 1 RI, bit 2 LI, bit 3 PMI, bit 4 CQI, bit 5 i1
|
||||
} fapi_nr_dl_config_csirs_pdu_rel15_t;
|
||||
|
||||
typedef enum{vrb_to_prb_mapping_non_interleaved = 0, vrb_to_prb_mapping_interleaved = 1} vrb_to_prb_mapping_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t BWPSize;
|
||||
uint16_t BWPStart;
|
||||
uint8_t SubcarrierSpacing;
|
||||
uint8_t resource_alloc;
|
||||
uint8_t rb_bitmap[36];
|
||||
uint16_t number_rbs;
|
||||
uint16_t start_rb;
|
||||
uint16_t number_symbols;
|
||||
uint16_t start_symbol;
|
||||
// TODO this is a workaround to make it work
|
||||
// implementation is also a bunch of workarounds
|
||||
uint16_t rb_offset;
|
||||
uint16_t dlDmrsSymbPos;
|
||||
uint8_t dmrsConfigType;
|
||||
uint8_t prb_bundling_size_ind;
|
||||
uint8_t rate_matching_ind;
|
||||
uint8_t zp_csi_rs_trigger;
|
||||
uint8_t mcs;
|
||||
bool new_data_indicator;
|
||||
uint8_t rv;
|
||||
uint16_t targetCodeRate;
|
||||
uint8_t qamModOrder;
|
||||
uint32_t TBS;
|
||||
uint8_t tb2_mcs;
|
||||
bool tb2_new_data_indicator;
|
||||
uint8_t tb2_rv;
|
||||
uint8_t harq_process_nbr;
|
||||
vrb_to_prb_mapping_t vrb_to_prb_mapping;
|
||||
uint8_t dai;
|
||||
double scaling_factor_S;
|
||||
uint8_t pucch_resource_id;
|
||||
uint8_t pdsch_to_harq_feedback_time_ind;
|
||||
uint8_t n_dmrs_cdm_groups;
|
||||
uint16_t dmrs_ports;
|
||||
uint8_t n_front_load_symb;
|
||||
uint8_t tci_state;
|
||||
uint8_t cbgti;
|
||||
uint8_t codeBlockGroupFlushIndicator;
|
||||
// to be check the fields needed to L1 with NR_DL_UE_HARQ_t and NR_UE_DLSCH_t
|
||||
// PTRS [TS38.214, sec 5.1.6.3]
|
||||
/// PT-RS antenna ports [TS38.214, sec 5.1.6.3] [TS38.211, table 7.4.1.2.2-1] Bitmap occupying the 6 LSBs with: bit 0: antenna port 1000 bit 5: antenna port 1005 and for each bit 0: PTRS port not used 1: PTRS port used
|
||||
uint8_t PTRSPortIndex;
|
||||
/// PT-RS time density [TS38.214, table 5.1.6.3-1] 0: 1 1: 2 2: 4
|
||||
uint8_t PTRSTimeDensity;
|
||||
/// PT-RS frequency density [TS38.214, table 5.1.6.3-2] 0: 2 1: 4
|
||||
uint8_t PTRSFreqDensity;
|
||||
/// PT-RS resource element offset [TS38.211, table 7.4.1.2.2-1] Value: 0->3
|
||||
uint8_t PTRSReOffset;
|
||||
/// PT-RS-to-PDSCH EPRE ratio [TS38.214, table 4.1-2] Value :0->3
|
||||
uint8_t nEpreRatioOfPDSCHToPTRS;
|
||||
/// MCS table for this DLSCH
|
||||
uint8_t mcs_table;
|
||||
uint32_t tbslbrm;
|
||||
uint8_t nscid;
|
||||
uint16_t dlDmrsScramblingId;
|
||||
uint16_t dlDataScramblingId;
|
||||
uint16_t pduBitmap;
|
||||
uint32_t k1_feedback;
|
||||
uint8_t ldpcBaseGraph;
|
||||
uint8_t numCsiRsForRateMatching;
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t csiRsForRateMatching[NFAPI_MAX_NUM_CSI_RATEMATCH];
|
||||
} fapi_nr_dl_config_dlsch_pdu_rel15_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t rnti;
|
||||
fapi_nr_dl_config_dlsch_pdu_rel15_t dlsch_config_rel15;
|
||||
} fapi_nr_dl_config_dlsch_pdu;
|
||||
|
||||
typedef struct {
|
||||
uint16_t bwp_size;
|
||||
uint16_t bwp_start;
|
||||
uint8_t subcarrier_spacing;
|
||||
uint16_t start_rb;
|
||||
uint16_t nr_of_rbs;
|
||||
uint8_t k_csiim[4];
|
||||
uint8_t l_csiim[4];
|
||||
} fapi_nr_dl_config_csiim_pdu_rel15_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
fapi_nr_dl_config_csirs_pdu_rel15_t csirs_config_rel15;
|
||||
} fapi_nr_dl_config_csirs_pdu;
|
||||
|
||||
|
||||
typedef struct {
|
||||
fapi_nr_dl_config_csiim_pdu_rel15_t csiim_config_rel15;
|
||||
} fapi_nr_dl_config_csiim_pdu;
|
||||
|
||||
typedef struct {
|
||||
int ta_frame;
|
||||
int ta_slot;
|
||||
int ta_command;
|
||||
bool is_rar;
|
||||
} fapi_nr_ta_command_pdu;
|
||||
|
||||
typedef struct {
|
||||
// N_common_ta_adj represents common round-trip-time between gNB and SAT received in SIB19 (ms)
|
||||
double N_common_ta_adj;
|
||||
// N_UE_TA_adj calculated round-trip-time between UE and SAT (ms)
|
||||
double N_UE_TA_adj;
|
||||
// drift rate of common ta in µs/s
|
||||
double ntn_ta_commondrift;
|
||||
// cell scheduling offset expressed in terms of 15kHz SCS
|
||||
long cell_specific_k_offset;
|
||||
|
||||
double ntn_total_time_advance_ms;
|
||||
} fapi_nr_dl_ntn_config_command_pdu;
|
||||
|
||||
typedef struct {
|
||||
uint8_t pdu_type;
|
||||
union {
|
||||
fapi_nr_dl_config_dci_pdu dci_config_pdu;
|
||||
fapi_nr_dl_config_dlsch_pdu dlsch_config_pdu;
|
||||
fapi_nr_dl_config_csirs_pdu csirs_config_pdu;
|
||||
fapi_nr_dl_config_csiim_pdu csiim_config_pdu;
|
||||
fapi_nr_ta_command_pdu ta_command_pdu;
|
||||
fapi_nr_dl_ntn_config_command_pdu ntn_config_command_pdu;
|
||||
};
|
||||
} fapi_nr_dl_config_request_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
uint8_t number_pdus;
|
||||
fapi_nr_dl_config_request_pdu_t dl_config_list[FAPI_NR_DL_CONFIG_LIST_NUM];
|
||||
} fapi_nr_dl_config_request_t;
|
||||
|
||||
#define FAPI_NR_CONFIG_REQUEST_MASK_PBCH 0x01
|
||||
#define FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_COMMON 0x02
|
||||
#define FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_COMMON 0x04
|
||||
#define FAPI_NR_CONFIG_REQUEST_MASK_DL_BWP_DEDICATED 0x08
|
||||
#define FAPI_NR_CONFIG_REQUEST_MASK_UL_BWP_DEDICATED 0x10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t dl_bandwidth;//Carrier bandwidth for DL in MHz [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
|
||||
uint16_t sl_bandwidth; //Carrier bandwidth for SL in MHz [38.101, sec 5.3.5] Values: 10, 20, 30, and 40
|
||||
uint32_t dl_frequency; //Absolute frequency of DL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
|
||||
uint32_t sl_frequency; //Absolute frequency of SL point A in KHz [38.331, sec6.3.5 and 38.211 sec 8.2.7]
|
||||
uint16_t dl_k0[5];//𝑘_{0}^{𝜇} for each of the numerologies [38.211, sec 5.3.1] Value: 0 ->23699
|
||||
uint16_t dl_grid_size[5];//Grid size 𝑁_{𝑔𝑟𝑖𝑑}^{𝑠𝑖𝑧𝑒,𝜇} for each of the numerologies [38.211, sec 4.4.2] Value: 0->275 0 = this numerology not used
|
||||
uint16_t num_tx_ant;//Number of Tx antennas
|
||||
uint16_t uplink_bandwidth;//Carrier bandwidth for UL in MHz. [38.104, sec 5.3.2] Values: 5, 10, 15, 20, 25, 30, 40,50, 60, 70, 80,90,100,200,400
|
||||
uint32_t uplink_frequency;//Absolute frequency of UL point A in KHz [38.104, sec5.2 and 38.211 sec 4.4.4.2] Value: 450000 -> 52600000
|
||||
uint16_t ul_k0[5];//𝑘0 𝜇 for each of the numerologies [38.211, sec 5.3.1] Value: : 0 ->23699
|
||||
uint16_t ul_grid_size[5];//Grid size 𝑁𝑔𝑟𝑖𝑑 𝑠𝑖𝑧𝑒,𝜇 for each of the numerologies [38.211, sec 4.4.2]. Value: 0->275 0 = this numerology not used
|
||||
uint16_t sl_grid_size[5];
|
||||
uint16_t num_rx_ant;//
|
||||
uint8_t frequency_shift_7p5khz;//Indicates presence of 7.5KHz frequency shift. Value: 0 = false 1 = true
|
||||
|
||||
} fapi_nr_ue_carrier_config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007
|
||||
uint8_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD
|
||||
uint32_t N_TA_offset;
|
||||
} fapi_nr_cell_config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ss_pbch_power;//SSB Block Power Value: TBD (-60..50 dBm)
|
||||
uint8_t bch_payload;//Defines option selected for generation of BCH payload, see Table 3-13 (v0.0.011 Value: 0: MAC generates the full PBCH payload 1: PHY generates the timing PBCH bits 2: PHY generates the full PBCH payload
|
||||
uint8_t scs_common;//subcarrierSpacing for common, used for initial access and broadcast message. [38.211 sec 4.2] Value:0->3
|
||||
|
||||
} fapi_nr_ssb_config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t ssb_mask;//Bitmap for actually transmitted SSB. MSB->LSB of first 32 bit number corresponds to SSB 0 to SSB 31 MSB->LSB of second 32 bit number corresponds to SSB 32 to SSB 63 Value for each bit: 0: not transmitted 1: transmitted
|
||||
|
||||
} fapi_nr_ssb_mask_size_2_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int8_t beam_id[64];//BeamID for each SSB in SsbMask. For example, if SSB mask bit 26 is set to 1, then BeamId[26] will be used to indicate beam ID of SSB 26. Value: from 0 to 63
|
||||
|
||||
} fapi_nr_ssb_mask_size_64_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t ssb_offset_point_a;//Offset of lowest subcarrier of lowest resource block used for SS/PBCH block. Given in PRB [38.211, section 4.4.4.2] Value: 0->2199
|
||||
uint8_t beta_pss;//PSS EPRE to SSS EPRE in a SS/PBCH block [38.213, sec 4.1] Values: 0 = 0dB
|
||||
uint8_t ssb_period;//SSB periodicity in msec Value: 0: ms5 1: ms10 2: ms20 3: ms40 4: ms80 5: ms160
|
||||
uint8_t ssb_subcarrier_offset;//ssbSubcarrierOffset or 𝑘𝑆𝑆𝐵 (38.211, section 7.4.3.1) Value: 0->31
|
||||
uint32_t MIB;//MIB payload, where the 24 MSB are used and represent the MIB in [38.331 MIB IE] and represent 0 1 2 3 1 , , , ,..., A− a a a a a [38.212, sec 7.1.1]
|
||||
fapi_nr_ssb_mask_size_2_t ssb_mask_list[2];
|
||||
fapi_nr_ssb_mask_size_64_t* ssb_beam_id_list;//64
|
||||
uint8_t ss_pbch_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
|
||||
uint8_t multiple_cells_ss_pbch_in_a_carrier;//Indicates that multiple cells will be supported in a single carrier 0 = disabled 1 = enabled
|
||||
|
||||
} fapi_nr_ssb_table_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t slot_config; //For each symbol in each slot a uint8_t value is provided indicating: 0: DL slot 1: UL slot 2: Guard slot
|
||||
} fapi_nr_max_num_of_symbol_per_slot_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
fapi_nr_max_num_of_symbol_per_slot_t *max_num_of_symbol_per_slot_list;
|
||||
} fapi_nr_max_tdd_periodicity_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t tdd_period_in_slots;
|
||||
fapi_nr_max_tdd_periodicity_t* max_tdd_periodicity_list;
|
||||
} fapi_nr_tdd_table_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t num_prach_fd_occasions;
|
||||
uint16_t prach_root_sequence_index;//Starting logical root sequence index, 𝑖, equivalent to higher layer parameter prach-RootSequenceIndex [38.211, sec 6.3.3.1] Value: 0 -> 837
|
||||
uint8_t num_root_sequences;//Number of root sequences for a particular FD occasion that are required to generate the necessary number of preambles
|
||||
uint16_t k1;//Frequency offset (from UL bandwidth part) for each FD. [38.211, sec 6.3.3.2] Value: from 0 to 272
|
||||
uint8_t prach_zero_corr_conf;//PRACH Zero CorrelationZone Config which is used to dervive 𝑁𝑐𝑠 [38.211, sec 6.3.3.1] Value: from 0 to 15
|
||||
uint8_t num_unused_root_sequences;//Number of unused sequences available for noise estimation per FD occasion. At least one unused root sequence is required per FD occasion.
|
||||
uint8_t* unused_root_sequences_list;//Unused root sequence or sequences per FD occasion. Required for noise estimation.
|
||||
|
||||
} fapi_nr_num_prach_fd_occasions_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t prach_sequence_length;//RACH sequence length. Only short sequence length is supported for FR2. [38.211, sec 6.3.3.1] Value: 0 = Long sequence 1 = Short sequence
|
||||
uint8_t prach_sub_c_spacing; // Subcarrier spacing of PRACH. [38.211 sec 4.2] Value: 0: 15 kHz 1: 30 kHz 2: 60 kHz 3: 120 kHz
|
||||
// 4: 1.25 kHz 5: 5 kHz
|
||||
uint8_t restricted_set_config;//PRACH restricted set config Value: 0: unrestricted 1: restricted set type A 2: restricted set type B
|
||||
uint8_t num_prach_fd_occasions;//Corresponds to the parameter 𝑀 in [38.211, sec 6.3.3.2] which equals the higher layer parameter msg1FDM Value: 1,2,4,8
|
||||
fapi_nr_num_prach_fd_occasions_t* num_prach_fd_occasions_list;
|
||||
uint8_t ssb_per_rach;//SSB-per-RACH-occasion Value: 0: 1/8 1:1/4, 2:1/2 3:1 4:2 5:4, 6:8 7:16
|
||||
uint8_t prach_multiple_carriers_in_a_band;//0 = disabled 1 = enabled
|
||||
uint8_t root_seq_computed; // flag set and used only in PHY to indicate if table is computed with this config
|
||||
|
||||
} fapi_nr_prach_config_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t target_Nid_cell;
|
||||
bool ssb_bw_scan;
|
||||
} fapi_nr_synch_request_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t config_mask;
|
||||
|
||||
fapi_nr_ue_carrier_config_t carrier_config;
|
||||
fapi_nr_cell_config_t cell_config;
|
||||
fapi_nr_ssb_config_t ssb_config;
|
||||
fapi_nr_ssb_table_t ssb_table;
|
||||
fapi_nr_tdd_table_t tdd_table;
|
||||
fapi_nr_prach_config_t prach_config;
|
||||
|
||||
} fapi_nr_config_request_t;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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 NFAPI_COMMON_INTERFACE_H
|
||||
#define NFAPI_COMMON_INTERFACE_H
|
||||
|
||||
typedef struct {
|
||||
uint16_t tag;
|
||||
uint16_t length;
|
||||
} nfapi_tl_t;
|
||||
|
||||
/*! Configuration options for the p7 pack unpack functions
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct nfapi_p7_codec_config {
|
||||
/*! Optional call back to allow the user to define the memory allocator.
|
||||
* \param size The size of the memory to allocate
|
||||
* \return a pointer to a valid memory block or 0 if it has failed.
|
||||
*
|
||||
* If not set the nfapi unpack functions will use malloc
|
||||
*/
|
||||
void* (*allocate)(size_t size);
|
||||
|
||||
/*! Optional call back to allow the user to define the memory deallocator.
|
||||
* \param ptr A poiner to a memory block allocated by the allocate callback
|
||||
*
|
||||
* If not set the client should use free
|
||||
*/
|
||||
void (*deallocate)(void* ptr);
|
||||
|
||||
/*! Optional call back function to handle unpacking vendor extension tlv.
|
||||
* \param tl A pointer to a decoded tag length structure
|
||||
* \param ppReadPackedMsg A handle to the read buffer.
|
||||
* \param end The end of the read buffer
|
||||
* \param ve A handle to a vendor extention structure that the call back should allocate if the structure can be decoded
|
||||
* \param config A pointer to the p7 codec configuration
|
||||
* \return return 0 if packed successfully, -1 if failed.
|
||||
*
|
||||
* If not set the tlv will be skipped
|
||||
*
|
||||
* Client should use the help methods in nfapi.h to decode the vendor extention.
|
||||
*
|
||||
* \todo Add code example
|
||||
*/
|
||||
int (*unpack_vendor_extension_tlv)(nfapi_tl_t* tl,
|
||||
uint8_t** ppReadPackedMsg,
|
||||
uint8_t* end,
|
||||
void** ve,
|
||||
struct nfapi_p7_codec_config* config);
|
||||
|
||||
/*! Optional call back function to handle packing vendor extension tlv.
|
||||
* \param ve A pointer to a vendor extention structure.
|
||||
* \param ppWritePackedMsg A handle to the write buffer
|
||||
* \param end The end of the write buffer. The callee should make sure not to write beyond the end
|
||||
* \param config A pointer to the p7 codec configuration
|
||||
* \return return 0 if packed successfully, -1 if failed.
|
||||
*
|
||||
* If not set the the tlv will be skipped
|
||||
*
|
||||
* Client should use the help methods in nfapi.h to encode the vendor extention
|
||||
*
|
||||
* \todo Add code example
|
||||
*/
|
||||
int (*pack_vendor_extension_tlv)(void* ve, uint8_t** ppWritePackedMsg, uint8_t* end, struct nfapi_p7_codec_config* config);
|
||||
|
||||
/*! Optional call back function to handle unpacking vendor extension messages.
|
||||
* \param header A pointer to a decode P7 message header for the vendor extention message
|
||||
* \param ppReadPackedMsg A handle to the encoded data buffer
|
||||
* \param end A pointer to the end of the encoded data buffer
|
||||
* \param config A pointer to the p7 codec configuration
|
||||
* \return 0 if unpacked successfully, -1 if failed
|
||||
*
|
||||
* If not set the message will be ignored
|
||||
*
|
||||
* If the message if is unknown the function should return -1
|
||||
*/
|
||||
int (*unpack_p7_vendor_extension)(void* header, uint8_t** ppReadPackedMsg, uint8_t* end, struct nfapi_p7_codec_config* config);
|
||||
|
||||
/*! Optional call back function to handle packing vendor extension messages.
|
||||
* \param header A poiner to a P7 message structure for the venfor extention message
|
||||
* \param ppWritePackedmsg A handle to the buffer to write the encoded message into
|
||||
* \param end A pointer to the end of the buffer
|
||||
* \param cofig A pointer to the p7 codec configuration
|
||||
* \return 0 if packed successfully, -1 if failed
|
||||
*
|
||||
* If not set the the message will be ingored
|
||||
*
|
||||
* If the message if is unknown the function should return -1
|
||||
*/
|
||||
int (*pack_p7_vendor_extension)(void* header, uint8_t** ppWritePackedmsg, uint8_t* end, struct nfapi_p7_codec_config* config);
|
||||
|
||||
/*! Optional user data that will be passed back with callbacks
|
||||
*/
|
||||
void* user_data;
|
||||
|
||||
} nfapi_p7_codec_config_t;
|
||||
|
||||
/*! Configuration options for the p4 & p5 pack unpack functions
|
||||
*
|
||||
*/
|
||||
typedef struct nfapi_p4_p5_codec_config {
|
||||
/*! Optional call back to allow the user to define the memory allocator.
|
||||
* \param size The size of the memory to allocate
|
||||
* \return a pointer to a valid memory block or 0 if it has failed.
|
||||
*
|
||||
* If not set the nfapi unpack functions will use malloc
|
||||
*/
|
||||
void* (*allocate)(size_t size);
|
||||
|
||||
/*! Optional call back to allow the user to define the memory deallocator.
|
||||
* \param ptr A poiner to a memory block allocated by the allocate callback
|
||||
*
|
||||
* If not set free will be used
|
||||
*/
|
||||
void (*deallocate)(void* ptr);
|
||||
|
||||
/*! Optional call back function to handle unpacking vendor extension tlv.
|
||||
* \param tl A pointer to a decoded tag length structure
|
||||
* \param ppReadPackedMsg A handle to the data buffer to decode
|
||||
* \param end A pointer to the end of the buffer
|
||||
* \param ve A handle to a vendor extention structure that will be allocated by this callback
|
||||
* \param config A pointer to the P4/P5 codec configuration
|
||||
* \return 0 if unpacked successfully, -1 if failed
|
||||
*
|
||||
* If not set the tlv will be skipped
|
||||
*/
|
||||
int (*unpack_vendor_extension_tlv)(nfapi_tl_t* tl,
|
||||
uint8_t** ppReadPackedMsg,
|
||||
uint8_t* end,
|
||||
void** ve,
|
||||
struct nfapi_p4_p5_codec_config* config);
|
||||
|
||||
/*! Optional call back function to handle packing vendor extension tlv.
|
||||
* \param ve
|
||||
* \param ppWritePackedMsg A handle to the data buffer pack the tlv into
|
||||
* \param end A pointer to the end of the buffer
|
||||
* \param config A pointer to the P4/P5 codec configuration
|
||||
* \return 0 if packed successfully, -1 if failed
|
||||
*
|
||||
* If not set the the tlv will be skipped
|
||||
*/
|
||||
int (*pack_vendor_extension_tlv)(void* ve, uint8_t** ppWritePackedMsg, uint8_t* end, struct nfapi_p4_p5_codec_config* config);
|
||||
|
||||
/*! Optional call back function to handle unpacking vendor extension messages.
|
||||
* \param header A pointer to a decode P4/P5 message header
|
||||
* \param ppReadPackgedMsg A handle to the data buffer to decode
|
||||
* \param end A pointer to the end of the buffer
|
||||
* \param config A pointer to the P4/P5 codec configuration
|
||||
* \return 0 if packed successfully, -1 if failed
|
||||
*
|
||||
* If not set the message will be ignored
|
||||
*/
|
||||
int (*unpack_p4_p5_vendor_extension)(void* header,
|
||||
uint8_t** ppReadPackedMsg,
|
||||
uint8_t* end,
|
||||
struct nfapi_p4_p5_codec_config* config);
|
||||
|
||||
/*! Optional call back function to handle packing vendor extension messages.
|
||||
* \param header A pointer to the P4/P5 message header to be encoded
|
||||
* \param ppWritePackedMsg A handle to the data buffer pack the message into
|
||||
* \param end A pointer to the end of the buffer
|
||||
* \param config A pointer to the P4/P5 codec configuration
|
||||
* \return 0 if packed successfully, -1 if failed
|
||||
*
|
||||
* If not set the the message will be ingored
|
||||
*/
|
||||
int (*pack_p4_p5_vendor_extension)(void* header,
|
||||
uint8_t** ppwritepackedmsg,
|
||||
uint8_t* end,
|
||||
struct nfapi_p4_p5_codec_config* config);
|
||||
|
||||
/*! Optional user data that will be passed back with callbacks
|
||||
*/
|
||||
void* user_data;
|
||||
|
||||
} nfapi_p4_p5_codec_config_t;
|
||||
|
||||
#endif // NFAPI_COMMON_INTERFACE_H
|
||||
3893
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nfapi_interface.h
Normal file
3893
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nfapi_interface.h
Normal file
File diff suppressed because it is too large
Load Diff
262
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
Normal file
262
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nfapi_nr_interface.h
Normal file
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
nfapi_nr_interface.h
|
||||
-------------------
|
||||
AUTHOR : Raymond Knopp, Guy de Souza, WEI-TAI CHEN
|
||||
COMPANY : EURECOM, NTUST
|
||||
EMAIL : Lionel.Gauthier@eurecom.fr, desouza@eurecom.fr, kroempa@gmail.com
|
||||
*/
|
||||
|
||||
#ifndef _NFAPI_NR_INTERFACE_H_
|
||||
#define _NFAPI_NR_INTERFACE_H_
|
||||
#include "nfapi_common_interface.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define NFAPI_NR_P5_HEADER_LENGTH 10
|
||||
#define NFAPI_NR_P7_HEADER_LENGTH 18
|
||||
|
||||
//These TLVs are used exclusively by nFAPI
|
||||
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV4_TAG 0x0100
|
||||
#define NFAPI_NR_NFAPI_P7_VNF_ADDRESS_IPV6_TAG 0x0101
|
||||
#define NFAPI_NR_NFAPI_P7_VNF_PORT_TAG 0x0102
|
||||
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV4_TAG 0x0103
|
||||
#define NFAPI_NR_NFAPI_P7_PNF_ADDRESS_IPV6_TAG 0x0104
|
||||
#define NFAPI_NR_NFAPI_P7_PNF_PORT_TAG 0x0105
|
||||
#define NFAPI_NR_NFAPI_DL_TTI_TIMING_OFFSET 0x0106
|
||||
#define NFAPI_NR_NFAPI_UL_TTI_TIMING_OFFSET 0x0107
|
||||
#define NFAPI_NR_NFAPI_UL_DCI_TIMING_OFFSET 0x0108
|
||||
#define NFAPI_NR_NFAPI_TX_DATA_TIMING_OFFSET 0x0109
|
||||
#define NFAPI_NR_NFAPI_TIMING_WINDOW_TAG 0x011E
|
||||
#define NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG 0x011F
|
||||
#define NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG 0x0120
|
||||
#define NFAPI_NR_FAPI_NUM_BEAMS_PERIOD_VENDOR_EXTENSION_TAG 0xA000
|
||||
#define NFAPI_NR_FAPI_ANALOG_BF_VENDOR_EXTENSION_TAG 0xA001
|
||||
#define NFAPI_NR_FAPI_TOTAL_NUM_BEAMS_VENDOR_EXTENSION_TAG 0xA002
|
||||
#define NFAPI_NR_FAPI_ANALOG_BEAM_VENDOR_EXTENSION_TAG 0xA003
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint16_t phy_id;
|
||||
uint16_t message_id;
|
||||
uint32_t message_length;
|
||||
uint16_t spare;
|
||||
} nfapi_nr_p4_p5_message_header_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t phy_id;
|
||||
uint16_t message_id;
|
||||
uint32_t message_length;
|
||||
uint16_t m_segment_sequence; /* This consists of 3 fields - namely, M, Segement & Sequence number*/
|
||||
uint32_t checksum;
|
||||
uint32_t transmit_timestamp;
|
||||
} nfapi_nr_p7_message_header_t;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_CCE_REG_MAPPING_INTERLEAVED=1,
|
||||
NFAPI_NR_CCE_REG_MAPPING_NON_INTERLEAVED=0
|
||||
} nfapi_nr_cce_reg_mapping_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_CSET_CONFIG_MIB_SIB1 = 0,
|
||||
NFAPI_NR_CSET_CONFIG_PDCCH_CONFIG, // implicit assumption of coreset Id other than 0
|
||||
} nfapi_nr_coreset_config_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_DMRS_TYPE1,
|
||||
NFAPI_NR_DMRS_TYPE2
|
||||
} nfapi_nr_dmrs_type_e;
|
||||
|
||||
typedef enum {
|
||||
NFAPI_NR_SRS_BEAMMANAGEMENT = 0,
|
||||
NFAPI_NR_SRS_CODEBOOK = 1,
|
||||
NFAPI_NR_SRS_NONCODEBOOK = 2,
|
||||
NFAPI_NR_SRS_ANTENNASWITCH = 3
|
||||
} nfapi_nr_srs_usage_e;
|
||||
|
||||
/*! \brief Encodes an NFAPI P5 message to a buffer
|
||||
* \param pMessageBuf A pointer to a nfapi p5 message structure
|
||||
* \param messageBufLen The size of the p5 message structure
|
||||
* \param pPackedBuf A pointer to the buffer that the p5 message will be packed into
|
||||
* \param packedBufLen The size of the buffer
|
||||
* \param config A pointer to the nfapi configuration structure
|
||||
* \return != 0 means success, -1 means failure.
|
||||
*
|
||||
* The function will encode a nFAPI P5 message structure pointed to be pMessageBuf into a byte stream pointed to by pPackedBuf.
|
||||
* The function returns the message length that was packed
|
||||
*/
|
||||
int nfapi_nr_p5_message_pack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pPackedBuf,
|
||||
uint32_t packedBufLen,
|
||||
nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
/*! \brief Packs a NFAPI P5 message body
|
||||
* \param header A pointer to the header of the P5 message
|
||||
* \param ppWritePackedMsg A pointer to the buffer where to pack the P5 message
|
||||
* \param end Pointer to the end of the packing buffer
|
||||
* \param config A pointer to the nfapi configuration structure
|
||||
* \return 1 means success, 0 means failure.
|
||||
*
|
||||
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
|
||||
*/
|
||||
uint8_t pack_nr_p5_message_body(nfapi_nr_p4_p5_message_header_t *header,
|
||||
uint8_t **ppWritePackedMsg,
|
||||
uint8_t *end,
|
||||
nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
/*! \brief Decodes an NFAPI P5 message header
|
||||
* \param pMessageBuf A pointer to an encoded P5 message header
|
||||
* \param messageBufLen The size of the encoded P5 message header
|
||||
* \param pUnpackedBuf A pointer to the nfapi_message_header
|
||||
* \param unpackedBufLen The size of nfapi_message_header structure.
|
||||
* \param config A pointer to the nfapi configuration structure
|
||||
* \return 10 ( size of the unpacked header ) on success, -1 on failure.
|
||||
*
|
||||
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 header structure pointed to by pUnpackedBuf
|
||||
*/
|
||||
int nfapi_nr_p5_message_header_unpack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
/*! \brief Decodes a NFAPI P5 message
|
||||
* \param pMessageBuf A pointer to an encoded P5 message
|
||||
* \param messageBufLen The size of the encoded P5 message
|
||||
* \param pUnpackedBuf A pointer to the nfapi_message_header
|
||||
* \param unpackedBufLen The size of nfapi_message_header structure.
|
||||
* \param config A pointer to the nfapi configuration structure
|
||||
* \return != -1 means success, -1 means failure.
|
||||
*
|
||||
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p5 message structure pointer to by pUnpackedBuf
|
||||
*/
|
||||
int nfapi_nr_p5_message_unpack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p4_p5_codec_config_t *config);
|
||||
|
||||
/*! \brief Encodes an NFAPI P7 message to a buffer
|
||||
* \param pMessageBuf A pointer to a nfapi p7 message structure
|
||||
* \param pPackedBuf A pointer to the buffer that the p7 message will be packed into
|
||||
* \param packedBufLen The size of the buffer
|
||||
* \param config A pointer to the nfapi configuration structure
|
||||
* \return != -1 means success, -1 means failure.
|
||||
*
|
||||
* The function will encode a nFAPI P7 message structure pointed to be pMessageBuf into a byte stream pointed to by pPackedBuf.
|
||||
* The function returns the message length packed
|
||||
*/
|
||||
int nfapi_nr_p7_message_pack(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen, nfapi_p7_codec_config_t *config);
|
||||
|
||||
/*! \brief Decodes an NFAPI P7 message header
|
||||
* \param pMessageBuf A pointer to an encoded P7 message header
|
||||
* \param messageBufLen The size of the encoded P7 message header
|
||||
* \param pUnpackedBuf A pointer to the nfapi_message_header
|
||||
* \param unpackedBufLen The size of nfapi_message_header structure.
|
||||
* \param config A pointer to the nfapi configuration structure
|
||||
* \return 0 means success, -1 means failure.
|
||||
*
|
||||
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi_p7_message_header structure pointer to by
|
||||
pUnpackedBuf
|
||||
|
||||
*/
|
||||
int nfapi_nr_p7_message_header_unpack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
|
||||
/*! \brief Decodes a NFAPI P7 message
|
||||
* \param pMessageBuf A pointer to an encoded P7 message
|
||||
* \param messageBufLen The size of the encoded P7 message
|
||||
* \param pUnpackedBuf A pointer to the nfapi_message_header
|
||||
* \param unpackedBufLen The size of nfapi_message_header structure.
|
||||
* \param config A pointer to the nfapi configuration structure
|
||||
* \return 0 means success, -1 means failure.
|
||||
*
|
||||
* The function will decode a byte stream pointed to by pMessageBuf into a nfapi p7 message structure pointer to by pUnpackedBuf
|
||||
*/
|
||||
int nfapi_nr_p7_message_unpack(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen,
|
||||
nfapi_p7_codec_config_t *config);
|
||||
|
||||
/*! \brief Peeks the SFN and Slot of an (n)FAPI P7 message
|
||||
* \param pMessageBuf A pointer to an encoded P7 message header
|
||||
* \param messageBufLen The size of the encoded P7 message header
|
||||
* \param SFN A pointer to store the peeked SFN
|
||||
* \param Slot A pointer to store the peeked Slot
|
||||
* \return true on success, false, otherwise.
|
||||
*
|
||||
* The function will decode the encoded SFN and Slot from an encoded P7 (n)FAPI message
|
||||
|
||||
*/
|
||||
bool peek_nr_nfapi_p7_sfn_slot(void *pMessageBuf, uint32_t messageBufLen, uint16_t *SFN, uint16_t *Slot);
|
||||
|
||||
/*! \brief Calculates the checksum of a message
|
||||
*
|
||||
* \param buffer Pointer to the packed message
|
||||
* \param len The length of the message
|
||||
* \return The checksum. If there is an error the function with return -1
|
||||
*/
|
||||
uint32_t nfapi_nr_p7_calculate_checksum(uint8_t *buffer, uint32_t len);
|
||||
|
||||
/*! \brief Calculates & updates the checksum in the message
|
||||
*
|
||||
* \param buffer Pointer to the packed message
|
||||
* \param len The length of the message
|
||||
* \return 0 means success, -1 means failure.
|
||||
*/
|
||||
int nfapi_nr_p7_update_checksum(uint8_t *buffer, uint32_t len);
|
||||
|
||||
/*! \brief Updates the transmition time stamp in the p7 message header
|
||||
*
|
||||
* \param buffer Pointer to the packed message
|
||||
* \param timestamp The time stamp value
|
||||
* \return 0 means success, -1 means failure.
|
||||
*/
|
||||
int nfapi_nr_p7_update_transmit_timestamp(uint8_t *buffer, uint32_t timestamp);
|
||||
|
||||
/*! \brief Encodes a nfapi_nr_srs_normalized_channel_iq_matrix_t to a buffer
|
||||
*
|
||||
* \param pMessageBuf A pointer to a nfapi_nr_srs_normalized_channel_iq_matrix_t structure
|
||||
* \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_normalized_channel_iq_matrix_t will be packed into
|
||||
* \param packedBufLen The size of the buffer
|
||||
* \return number of bytes written to the buffer
|
||||
*/
|
||||
int pack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen);
|
||||
|
||||
/*! \brief Decodes a nfapi_nr_srs_normalized_channel_iq_matrix_t from a buffer
|
||||
*
|
||||
* \param pMessageBuf A pointer to an encoded nfapi_nr_srs_normalized_channel_iq_matrix_t
|
||||
* \param messageBufLen The size of the encoded nfapi_nr_srs_normalized_channel_iq_matrix_t
|
||||
* \param pUnpackedBuf A pointer to the nfapi_nr_srs_normalized_channel_iq_matrix_t
|
||||
* \param unpackedBufLen The size of nfapi_nr_srs_normalized_channel_iq_matrix_t structure.
|
||||
* \return 0 means success, -1 means failure.
|
||||
*/
|
||||
int unpack_nr_srs_normalized_channel_iq_matrix(void *pMessageBuf,
|
||||
uint32_t messageBufLen,
|
||||
void *pUnpackedBuf,
|
||||
uint32_t unpackedBufLen);
|
||||
|
||||
/*! \brief Encodes a nfapi_nr_srs_beamforming_report_t to a buffer
|
||||
*
|
||||
* \param pMessageBuf A pointer to a nfapi_nr_srs_beamforming_report_t structure
|
||||
* \param pPackedBuf A pointer to the buffer that the nfapi_nr_srs_beamforming_report_t will be packed into
|
||||
* \param packedBufLen The size of the buffer
|
||||
* \return number of bytes written to the buffer
|
||||
*/
|
||||
int pack_nr_srs_beamforming_report(void *pMessageBuf, void *pPackedBuf, uint32_t packedBufLen);
|
||||
|
||||
/*! \brief Decodes a nfapi_nr_srs_beamforming_report_t from a buffer
|
||||
*
|
||||
* \param pMessageBuf A pointer to an encoded nfapi_nr_srs_beamforming_report_t
|
||||
* \param messageBufLen The size of the encoded nfapi_nr_srs_beamforming_report_t
|
||||
* \param pUnpackedBuf A pointer to the nfapi_nr_srs_beamforming_report_t
|
||||
* \param unpackedBufLen The size of nfapi_nr_srs_beamforming_report_t structure.
|
||||
* \return 0 means success, -1 means failure.
|
||||
*/
|
||||
int unpack_nr_srs_beamforming_report(void *pMessageBuf, uint32_t messageBufLen, void *pUnpackedBuf, uint32_t unpackedBufLen);
|
||||
|
||||
#endif
|
||||
1919
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
Normal file
1919
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h
Normal file
File diff suppressed because it is too large
Load Diff
49
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h
Normal file
49
l2-fapi-proxy/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
/*! \file nfapi/open-nFAPI/nfapi/public_inc/nr_nfapi_p7.h
|
||||
* \brief
|
||||
* \author Ruben S. Silva
|
||||
* \date 2024
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
|
||||
#ifndef OPENAIRINTERFACE_NR_NFAPI_P7_H
|
||||
#define OPENAIRINTERFACE_NR_NFAPI_P7_H
|
||||
#include "nfapi_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
void *nfapi_p7_allocate(size_t size, nfapi_p7_codec_config_t *config);
|
||||
|
||||
uint8_t pack_ue_release_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
|
||||
uint8_t pack_ue_release_response(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
|
||||
uint8_t pack_nr_dl_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
|
||||
uint8_t pack_nr_ul_node_sync(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
|
||||
uint8_t pack_nr_timing_info(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config);
|
||||
|
||||
#endif // OPENAIRINTERFACE_NR_NFAPI_P7_H
|
||||
@@ -0,0 +1,389 @@
|
||||
#ifndef _SIDELINK_NR_UE_INTERFACE_H_
|
||||
#define _SIDELINK_NR_UE_INTERFACE_H_
|
||||
|
||||
#include "fapi_nr_ue_interface.h"
|
||||
|
||||
#define SL_NR_RX_CONFIG_LIST_NUM 1
|
||||
#define SL_NR_TX_CONFIG_LIST_NUM 1
|
||||
#define SL_NR_RX_IND_MAX_PDU 1
|
||||
#define SL_NR_MAX_PSCCH_SCI_LENGTH_IN_BYTES 8
|
||||
#define SL_NR_MAX_PSSCH_SCI_LENGTH_IN_BYTES 8
|
||||
#define SL_NR_MAX_SCI_LENGTH_IN_BYTES 8
|
||||
|
||||
typedef enum sl_sci_format_type_enum {
|
||||
SL_SCI_INVALID_FORMAT,
|
||||
SL_SCI_FORMAT_1A_ON_PSCCH,
|
||||
SL_SCI_FORMAT_2_ON_PSSCH,
|
||||
} sl_sci_format_type_enum_t;
|
||||
|
||||
//Type of Contents of SL-RX indication from PHY to MAC
|
||||
typedef enum sl_rx_pdu_type_enum {
|
||||
SL_NR_RX_PDU_TYPE_NONE,
|
||||
SL_NR_RX_PDU_TYPE_SSB,
|
||||
SL_NR_RX_PDU_TYPE_SLSCH
|
||||
} sl_rx_pdu_type_enum_t;
|
||||
|
||||
//Type of SL-RX CONFIG requests from MAC to PHY
|
||||
typedef enum sl_nr_rx_config_type_enum {
|
||||
SL_NR_CONFIG_TYPE_RX_PSBCH = 1,
|
||||
SL_NR_CONFIG_TYPE_RX_PSCCH,
|
||||
SL_NR_CONFIG_TYPE_RX_PSSCH_SCI,
|
||||
SL_NR_CONFIG_TYPE_RX_PSSCH_SLSCH,
|
||||
SL_NR_CONFIG_TYPE_RX_PSFCH,
|
||||
SL_NR_CONFIG_TYPE_RX_MAXIMUM
|
||||
} sl_nr_rx_config_type_enum_t;
|
||||
|
||||
//Type of SL-TX CONFIG requests from MAC to PHY
|
||||
typedef enum sl_nr_tx_config_type_enum {
|
||||
SL_NR_CONFIG_TYPE_TX_PSBCH = SL_NR_CONFIG_TYPE_RX_MAXIMUM + 1,
|
||||
SL_NR_CONFIG_TYPE_TX_PSCCH_PSSCH,
|
||||
SL_NR_CONFIG_TYPE_TX_PSFCH,
|
||||
SL_NR_CONFIG_TYPE_TX_MAXIMUM
|
||||
} sl_nr_tx_config_type_enum_t;
|
||||
|
||||
//PHY Indicates MAC about the SCI-indication
|
||||
//During blind decoding, SCI-1A can be decoded in every subchannel.
|
||||
typedef struct {
|
||||
sl_sci_format_type_enum_t sci_format_type; // SCI FORMAT 1A or SCI FORMAT 2
|
||||
// lowest subchannel index in the resource pool where the SCI-1A was detected
|
||||
// Not used for SCI-2
|
||||
uint16_t subch_index;
|
||||
//RSRP sent in case of sense pscch
|
||||
int16_t pscch_rsrp;
|
||||
//Length of SCI decoded
|
||||
uint16_t sci_payloadlen;
|
||||
//Derived from PSCCH CRC Refer 38.211 section 8.3.1.1
|
||||
//Will be passed on if PSSCH decoding needs to be done.
|
||||
//Filled only if PSCCH decoded
|
||||
uint16_t Nid;
|
||||
// Payload of the received SCIs
|
||||
uint8_t sci_payloadBits[SL_NR_MAX_SCI_LENGTH_IN_BYTES];
|
||||
} sl_nr_sci_indication_pdu_t;
|
||||
|
||||
// PHY indicates MAC about the received SCIs using this API
|
||||
typedef struct {
|
||||
uint16_t sfn;
|
||||
uint8_t slot;
|
||||
uint16_t number_of_SCIs;
|
||||
//If response to sensing - then this will be set to TRUE
|
||||
uint8_t sensing_result;
|
||||
//in case pssch sensing is requested.
|
||||
int16_t pssch_rsrp;
|
||||
sl_nr_sci_indication_pdu_t sci_pdu;
|
||||
} sl_nr_sci_indication_t;
|
||||
|
||||
// IF UE Rx PSBCH, PHY indicates MAC with received MIB and PSBCH RSRP
|
||||
typedef struct sl_nr_ssb_pdu {
|
||||
uint8_t psbch_payload[4];
|
||||
int16_t rsrp_dbm;
|
||||
uint16_t rx_slss_id;
|
||||
bool decode_status;
|
||||
} sl_nr_ssb_pdu_t;
|
||||
|
||||
//Use the same structure of pdsch pdu for slsch pdu
|
||||
typedef fapi_nr_pdsch_pdu_t sl_nr_slsch_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
sl_rx_pdu_type_enum_t pdu_type;
|
||||
union {
|
||||
sl_nr_ssb_pdu_t ssb_pdu;
|
||||
sl_nr_slsch_pdu_t rx_slsch_pdu;
|
||||
};
|
||||
} sl_nr_rx_indication_body_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
uint16_t number_pdus;
|
||||
sl_nr_rx_indication_body_t rx_indication_body[SL_NR_RX_IND_MAX_PDU];
|
||||
} sl_nr_rx_indication_t;
|
||||
|
||||
typedef struct sl_nr_rx_config_pscch_pdu {
|
||||
// Starting RE of the lowest subchannel in a resource where PSCCH
|
||||
// freq domain allocation starts
|
||||
uint16_t pscch_startrb;
|
||||
// Number of symbols used for PSCCH
|
||||
uint16_t pscch_numsym;
|
||||
// Number of RBS used for PSCCH
|
||||
uint16_t pscch_numrbs;
|
||||
// Scrambling Id used for Generation of PSCCH DMRS Symbols
|
||||
uint32_t pscch_dmrs_scrambling_id;
|
||||
// num subchannels in a resource pool
|
||||
uint16_t num_subch;
|
||||
// Size of subchannels in RBs
|
||||
uint16_t subchannel_size;
|
||||
// PSCCH PSSCH RX: this is set to 1 - Blind decoding for SCI1A done on every subchannel
|
||||
// PSCCH SENSING: this is equal to number of subchannels forming a resource.
|
||||
uint16_t l_subch;
|
||||
//number of symbols for Sidelink transmission on PSSCH/PSCCH
|
||||
//(Total Sidelink symbols available - number of psfch symbols configured - 2)
|
||||
//Guard symbol + AGC symbol are also excluded
|
||||
//Indicates the number of symbols for PSCCH+PSSCH txn
|
||||
uint8_t pssch_numsym;
|
||||
//sci 1A length used to decode on PSCCH.
|
||||
uint8_t sci_1a_length;
|
||||
//This paramter is set if PSCCH RX is triggered on TX resource pool
|
||||
// as part of TX pool sensing procedure.
|
||||
uint8_t sense_pscch;
|
||||
} sl_nr_rx_config_pscch_pdu_t;
|
||||
|
||||
typedef struct sl_nr_rx_config_pssch_sci_pdu {
|
||||
// Expected Length of SCI2 in bits
|
||||
uint8_t sci2_len;
|
||||
// Used to determine number of SCI2 modulated symbols
|
||||
uint8_t sci2_beta_offset;
|
||||
// Used to determine number of SCI2 modulated symbols
|
||||
//Values will be sl-scaling*100 (sl-scaling values 0.5, 0.65, 0.8, 1)
|
||||
uint8_t sci2_alpha_times_100;
|
||||
|
||||
uint16_t targetCodeRate;
|
||||
uint8_t mod_order;
|
||||
uint8_t num_layers;
|
||||
|
||||
//DMRS SYMBOL MASK. If bit set to 1 indicates it is a DMRS symbol. LSB is symbol 0
|
||||
// Table from SPEC 38.211, Table 8.4.1.1.2-1
|
||||
uint16_t dmrs_symbol_position;
|
||||
|
||||
// Derived from PSCCH CRC Refer 38.211 section 8.3.1.1
|
||||
// to be used for PSSCH DMRS and PSSCH 38.211 Scrambling
|
||||
uint16_t Nid;
|
||||
|
||||
// Starting RE of the lowest subchannel.
|
||||
//In Sym with PSCCH - Start of PSCCH
|
||||
//In Sym without PSCCH - Start of PSSCH
|
||||
// freq domain allocation starts
|
||||
uint16_t startrb;
|
||||
// Number of symbols used for PSCCH
|
||||
uint16_t pscch_numsym;
|
||||
// Number of RBS used for PSCCH
|
||||
uint16_t pscch_numrbs;
|
||||
// num subchannels in a resource pool
|
||||
uint16_t num_subch;
|
||||
// Size of subchannels in RBs
|
||||
uint16_t subchannel_size;
|
||||
// In case of PSCCH PSSCH RX: this is always 1. Blind decoding done for every channel
|
||||
// In case of RESOURCE SENSING: this is equal to number of subchannels forming a resource.
|
||||
uint16_t l_subch;
|
||||
//number of symbols for Sidelink transmission on PSSCH/PSCCH
|
||||
//(Total Sidelink symbols available - number of psfch symbols configured - 2)
|
||||
//Guard symbol + AGC symbol are also excluded
|
||||
//Indicates the number of symbols for PSCCH+PSSCH txn
|
||||
uint8_t pssch_numsym;
|
||||
|
||||
//This paramter is set if PSSCH sensing (PSSCH DMRS RSRP measurement)
|
||||
// is triggred as part of TX pool sensing procedure.
|
||||
uint8_t sense_pssch;
|
||||
|
||||
} sl_nr_rx_config_pssch_sci_pdu_t;
|
||||
|
||||
typedef struct sl_nr_rx_config_pssch_pdu {
|
||||
uint32_t tbslbrm;
|
||||
// Transport block size determined by MAC
|
||||
uint32_t tb_size;
|
||||
uint16_t target_coderate;
|
||||
uint8_t harq_pid;
|
||||
uint8_t mod_order;
|
||||
uint8_t mcs;
|
||||
uint8_t mcs_table;
|
||||
uint8_t num_layers;
|
||||
//REdundancy version to be used for transmission
|
||||
uint8_t rv_index;
|
||||
uint8_t ndi;
|
||||
} sl_nr_rx_config_pssch_pdu_t;
|
||||
|
||||
typedef struct {
|
||||
sl_nr_rx_config_type_enum_t pdu_type; // indicates the type of RX config request
|
||||
union {
|
||||
sl_nr_rx_config_pscch_pdu_t rx_pscch_config_pdu;
|
||||
sl_nr_rx_config_pssch_sci_pdu_t rx_sci2_config_pdu;
|
||||
sl_nr_rx_config_pssch_pdu_t rx_pssch_config_pdu;
|
||||
};
|
||||
} sl_nr_rx_config_request_pdu_t;
|
||||
|
||||
// MAC commands PHY to perform an action on RX RESOURCE POOL or RX PSBCH using this RX CONFIG
|
||||
// at this TTI as indicated in sfn, slot
|
||||
typedef struct {
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
uint8_t number_pdus;
|
||||
sl_nr_rx_config_request_pdu_t sl_rx_config_list[SL_NR_RX_CONFIG_LIST_NUM];
|
||||
} sl_nr_rx_config_request_t;
|
||||
|
||||
//MAC commands PHY to transmit Data on PSCCH, PSSCH.
|
||||
typedef struct sl_nr_tx_config_pscch_pssch_pdu {
|
||||
|
||||
//SCI 1A Payload Prepared by MAC, to be sent on PSCCH
|
||||
uint8_t pscch_sci_payload[SL_NR_MAX_PSCCH_SCI_LENGTH_IN_BYTES];
|
||||
//SCI 1A Payload Length in bits
|
||||
uint8_t pscch_sci_payload_len;
|
||||
//SCI 2 Payload Prepared by MAC and to be sent on PSSCH
|
||||
uint8_t sci2_payload[SL_NR_MAX_PSSCH_SCI_LENGTH_IN_BYTES];
|
||||
//SCI 2 Payload Length in bits
|
||||
uint8_t sci2_payload_len;
|
||||
|
||||
// Starting RE of the lowest subchannel.
|
||||
//In Sym with PSCCH - Start of PSCCH
|
||||
//In Sym without PSCCH - Start of PSSCH
|
||||
// freq domain allocation starts
|
||||
uint16_t startrb;
|
||||
// Number of symbols used for PSCCH
|
||||
uint16_t pscch_numsym;
|
||||
// Number of RBS used for PSCCH
|
||||
uint16_t pscch_numrbs;
|
||||
// Scrambling Id used for Generation of PSCCH DMRS Symbols
|
||||
uint32_t pscch_dmrs_scrambling_id;
|
||||
// num subchannels in a resource pool
|
||||
uint16_t num_subch;
|
||||
// Size of subchannels in RBs
|
||||
uint16_t subchannel_size;
|
||||
//PSCCH PSSCH TX: Size of subchannels in a PSSCH resource (l_subch)
|
||||
uint16_t l_subch;
|
||||
//number of symbols for Sidelink transmission on PSSCH/PSCCH
|
||||
//(Total Sidelink symbols available - number of psfch symbols configured - 2)
|
||||
//Guard symbol + AGC symbol are also excluded
|
||||
//Indicates the number of symbols for PSCCH+PSSCH txn
|
||||
uint8_t pssch_numsym;
|
||||
|
||||
//.... Other Parameters for SCI-2 and PSSCH
|
||||
|
||||
// Used to determine number of SCI2 modulated symbols
|
||||
uint8_t sci2_beta_offset;
|
||||
//Values will be sl-scaling*100 (sl-scaling values 0.5, 0.65, 0.8, 1)
|
||||
uint8_t sci2_alpha_times_100;
|
||||
|
||||
uint32_t tbslbrm;
|
||||
uint32_t tb_size;
|
||||
uint16_t target_coderate;
|
||||
uint8_t harq_pid;
|
||||
uint8_t mod_order;
|
||||
uint8_t mcs;
|
||||
uint8_t mcs_table;
|
||||
uint8_t num_layers;
|
||||
uint8_t rv_index;
|
||||
uint8_t ndi;
|
||||
|
||||
//DMRS SYMBOL MASK. If bit set to 1 indicates it is a DMRS symbol. LSB is symbol 0
|
||||
// Table from SPEC 38.211, Table 8.4.1.1.2-1
|
||||
uint16_t dmrs_symbol_position;
|
||||
|
||||
|
||||
//....TBD.. any additional parameters
|
||||
|
||||
//TX Power for PSSCH in symbol without PSCCH.
|
||||
// Power for PSCCH and power for PSSCH in symbol with PSCCH is calculated
|
||||
// from this value according to 38.213 section 16
|
||||
int16_t pssch_tx_power;
|
||||
|
||||
} sl_nr_tx_config_pscch_pssch_pdu_t;
|
||||
|
||||
// MAC indicates PHY to send PSBCH.
|
||||
typedef struct sl_nr_tx_config_psbch_pdu {
|
||||
|
||||
uint8_t psbch_payload[4]; // payload containing sl-MIB
|
||||
uint16_t tx_slss_id; // slss_id selected by RRC and to be used for MIB transmission on PSBCH
|
||||
int16_t psbch_tx_power; // TX Power used for sending PSBCH
|
||||
|
||||
} sl_nr_tx_config_psbch_pdu_t;
|
||||
|
||||
// MAC commands PHY to perform an action on TX RESOURCE POOL or TX PSBCH using this TX CONFIG
|
||||
typedef struct {
|
||||
sl_nr_tx_config_type_enum_t pdu_type; // indicates the type of TX config request
|
||||
union {
|
||||
sl_nr_tx_config_psbch_pdu_t tx_psbch_config_pdu;
|
||||
sl_nr_tx_config_pscch_pssch_pdu_t tx_pscch_pssch_config_pdu;
|
||||
};
|
||||
} sl_nr_tx_config_request_pdu_t;
|
||||
|
||||
// MAC commands PHY to perform an action on TX RESOURCE POOL or TX PSBCH using this TX CONFIG
|
||||
// at this TTI as indicated in sfn, slot
|
||||
typedef struct {
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
uint8_t number_pdus;
|
||||
sl_nr_tx_config_request_pdu_t tx_config_list[SL_NR_TX_CONFIG_LIST_NUM];
|
||||
} sl_nr_tx_config_request_t;
|
||||
|
||||
typedef enum sl_sync_source_enum {
|
||||
|
||||
SL_SYNC_SOURCE_NONE = 0,
|
||||
SL_SYNC_SOURCE_GNBENB, // NR-CELL as sync source
|
||||
SL_SYNC_SOURCE_GNSS, // GPS as sync source
|
||||
SL_SYNC_SOURCE_SYNC_REF_UE, // another SYNC REF UE as sync source
|
||||
SL_SYNC_SOURCE_LOCAL_TIMING, // if LOCAL UE timing is sync source , if above options are not available
|
||||
SL_SYNC_SOURCE_MAX
|
||||
|
||||
} sl_sync_source_enum_t ;
|
||||
|
||||
|
||||
typedef struct sl_nr_ue_bwp_config {
|
||||
|
||||
uint16_t sl_bwp_start; // BWP start RB
|
||||
uint16_t sl_bwp_size; // BWP Size in number of RBs
|
||||
uint16_t sl_ssb_offset_point_a; // offset in REs from PointA to indicate SSB location
|
||||
uint16_t sl_dc_location; // DC location in SL-BWP
|
||||
uint8_t sl_num_symbols; // number of sidelink symbols in a non PSBCH sidelink slot
|
||||
uint8_t sl_start_symbol;// start sidelink symbol in a non PSBCH sidelink slot
|
||||
uint8_t sl_scs; // sub carrier spacing of SL-BWP and SL-SSB
|
||||
uint8_t sl_cyclic_prefix; // cyclic prefix of SL-BWP and SL-SSB 0- normal, 1-extended which is not supported
|
||||
|
||||
} sl_nr_bwp_config_t;
|
||||
|
||||
typedef struct sl_nr_ue_sync_source_config {
|
||||
|
||||
// Sync source selected by the UE
|
||||
sl_sync_source_enum_t sync_source;
|
||||
|
||||
// if GNSS is sync source - used in DFN calculation from GNSS timing
|
||||
//field sl-OffsetDFN, Section 5.8.12 in 38.331
|
||||
// value from 0 to 1000,
|
||||
uint16_t gnss_dfn_offset;
|
||||
|
||||
//Only sent if sync_source is set to SYNC_SOURCE_SYNC_REF_UE
|
||||
//Valid values can be 0-671
|
||||
uint16_t rx_slss_id;
|
||||
|
||||
} sl_nr_sync_source_config_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// REference Rel16 38.101, 38.331
|
||||
//For NR-Sidelink operation on PC5 interface
|
||||
//Sidelink bandwidth configured - 10, 20, 30, and 40Mhz
|
||||
uint16_t sl_bandwidth;
|
||||
//Absolute frequency of SL point A in KHz
|
||||
//n38 (2570-2620 Mhz), n47 (5855-5925 Mhz) are defined.
|
||||
uint64_t sl_frequency;
|
||||
|
||||
//Only 1 SCS-SpecificCarrier allowed for NR-SL communication
|
||||
uint16_t sl_grid_size;// bandwidth for each numerology
|
||||
uint16_t sl_num_tx_ant;//Number of Tx antennae - value 1
|
||||
uint16_t sl_num_rx_ant;//Number of Rx antennae - value 1
|
||||
|
||||
//Indicates presence of 7.5KHz frequency shift wrt LTE anchor cell.
|
||||
//Value: 0 = false 1 = true
|
||||
uint8_t sl_frequency_shift_7p5khz;
|
||||
//Indicates presence of +/-5Khz shift wrt FREF for V2X reference frequencies.
|
||||
//Possible values: {-1,0,1}
|
||||
int8_t sl_value_N;
|
||||
|
||||
} sl_nr_carrier_config_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
// Mask indicating which of the below configs are changed
|
||||
// Bit0 - carrier_config, Bit1 - syncsource cfg
|
||||
// Bit2 - tdd config, Bit3 - bwp config
|
||||
uint32_t config_mask;
|
||||
|
||||
sl_nr_carrier_config_t sl_carrier_config;
|
||||
sl_nr_sync_source_config_t sl_sync_source;
|
||||
//TDD config either from SL-PRECONFIG or read from SL-MIB
|
||||
//In case of TDD-config available from gNB, tdd_table from NR PHY config will be used
|
||||
fapi_nr_tdd_table_t tdd_table;
|
||||
//only 1 SL-BWP can be configured in REL16, REL17
|
||||
sl_nr_bwp_config_t sl_bwp_config;
|
||||
|
||||
} sl_nr_phy_config_request_t;
|
||||
|
||||
|
||||
#endif
|
||||
1838
l2-fapi-proxy/open-nFAPI/nfapi/src/nfapi_p4.c
Normal file
1838
l2-fapi-proxy/open-nFAPI/nfapi/src/nfapi_p4.c
Normal file
File diff suppressed because it is too large
Load Diff
2622
l2-fapi-proxy/open-nFAPI/nfapi/src/nfapi_p5.c
Normal file
2622
l2-fapi-proxy/open-nFAPI/nfapi/src/nfapi_p5.c
Normal file
File diff suppressed because it is too large
Load Diff
6368
l2-fapi-proxy/open-nFAPI/nfapi/src/nfapi_p7.c
Normal file
6368
l2-fapi-proxy/open-nFAPI/nfapi/src/nfapi_p7.c
Normal file
File diff suppressed because it is too large
Load Diff
36
l2-fapi-proxy/open-nFAPI/nfapi/tests/Makefile.am
Normal file
36
l2-fapi-proxy/open-nFAPI/nfapi/tests/Makefile.am
Normal file
@@ -0,0 +1,36 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#nfapi unit test
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
|
||||
AM_CFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
|
||||
|
||||
check_PROGRAMS= test_nfapi
|
||||
test_nfapi_SOURCES = nfapi_cunit_main.c ../src/nfapi.c ../src/nfapi_p7.c ../../common/src/debug.c ../src/nfapi_p5.c ../src/nfapi_p4.c
|
||||
test_nfapi_LDADD=$(top_builddir)/pnf/libnfapi_pnf.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit
|
||||
|
||||
|
||||
#jTEST_LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh --ingore-exit
|
||||
#TEST_ENVIRONMENT = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh
|
||||
|
||||
#AM_TESTS_ENVIRONMENT = env AM_TAP_AWK='$(AWK)' $(SHELL);
|
||||
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
|
||||
#AM_LOG_FLAGS = -- test_nfapi
|
||||
|
||||
TESTS=$(check_PROGRAMS)
|
||||
EXTRA_DIST = $(TESTS)
|
||||
5511
l2-fapi-proxy/open-nFAPI/nfapi/tests/nfapi_cunit_main.c
Normal file
5511
l2-fapi-proxy/open-nFAPI/nfapi/tests/nfapi_cunit_main.c
Normal file
File diff suppressed because it is too large
Load Diff
32
l2-fapi-proxy/open-nFAPI/pnf/Makefile.am
Normal file
32
l2-fapi-proxy/open-nFAPI/pnf/Makefile.am
Normal file
@@ -0,0 +1,32 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/pnf/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -g -Wall -Werror
|
||||
|
||||
|
||||
noinst_LIBRARIES = libnfapi_pnf.a
|
||||
|
||||
libnfapi_pnf_a_SOURCES = src/pnf.c\
|
||||
src/pnf_interface.c\
|
||||
src/pnf_p7.c\
|
||||
src/pnf_p7_interface.c
|
||||
|
||||
LDADD = -lsctp
|
||||
|
||||
|
||||
|
||||
51
l2-fapi-proxy/open-nFAPI/pnf/inc/pnf.h
Normal file
51
l2-fapi-proxy/open-nFAPI/pnf/inc/pnf.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _PNF_H_
|
||||
#define _PNF_H_
|
||||
|
||||
#include "nfapi_pnf_interface.h"
|
||||
|
||||
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
|
||||
|
||||
typedef struct {
|
||||
|
||||
nfapi_pnf_config_t _public;
|
||||
|
||||
int p5_sock;
|
||||
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
|
||||
|
||||
uint8_t sctp;
|
||||
|
||||
uint8_t terminate;
|
||||
|
||||
} pnf_t;
|
||||
|
||||
|
||||
int pnf_connect(pnf_t *pnf);
|
||||
int pnf_message_pump(pnf_t *pnf);
|
||||
int pnf_nr_message_pump(pnf_t *pnf);
|
||||
|
||||
int pnf_nr_pack_and_send_p5_message(pnf_t* pnf, nfapi_nr_p4_p5_message_header_t* msg, uint32_t msg_len);
|
||||
int pnf_pack_and_send_p5_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
|
||||
int pnf_pack_and_send_p4_message(pnf_t* pnf, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
|
||||
int pnf_send_message(pnf_t* pnf, uint8_t* msg, uint32_t msg_len, uint16_t stream_id);
|
||||
|
||||
nfapi_pnf_phy_config_t* nfapi_pnf_phy_config_find(nfapi_pnf_config_t* config, uint16_t phy_id);
|
||||
|
||||
#endif // _PNF_H_
|
||||
|
||||
174
l2-fapi-proxy/open-nFAPI/pnf/inc/pnf_p7.h
Normal file
174
l2-fapi-proxy/open-nFAPI/pnf/inc/pnf_p7.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef _PNF_P7_H_
|
||||
#define _PNF_P7_H_
|
||||
|
||||
#define TIMEHR_SEC(_time_hr) ((uint32_t)(_time_hr) >> 20)
|
||||
#define TIMEHR_USEC(_time_hr) ((uint32_t)(_time_hr) & 0xFFFFF)
|
||||
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
|
||||
|
||||
#include "nfapi_pnf_interface.h"
|
||||
|
||||
#define NFAPI_MAX_PACKED_MESSAGE_SIZE 32768
|
||||
|
||||
typedef struct {
|
||||
uint16_t dl_conf_ontime;
|
||||
uint16_t dl_tti_ontime;
|
||||
uint16_t dl_conf_late;
|
||||
uint16_t dl_tti_late;
|
||||
uint16_t ul_conf_ontime;
|
||||
uint16_t ul_tti_ontime;
|
||||
uint16_t ul_conf_late;
|
||||
uint16_t ul_tti_late;
|
||||
uint16_t hi_dci0_ontime;
|
||||
uint16_t hi_dci0_late;
|
||||
uint16_t ul_dci_ontime;
|
||||
uint16_t ul_dci_late;
|
||||
uint16_t tx_ontime;
|
||||
uint16_t tx_late;
|
||||
uint16_t tx_data_ontime;
|
||||
uint16_t tx_data_late;
|
||||
} pnf_p7_stats_t;
|
||||
|
||||
|
||||
typedef struct pnf_p7_arr_time {
|
||||
uint16_t ontime;
|
||||
uint16_t late;
|
||||
} pnf_p7_arr_time_t;
|
||||
typedef struct pnf_p7_dir {
|
||||
uint32_t bytes;
|
||||
} pnf_p7_dir_t;
|
||||
typedef struct {
|
||||
pnf_p7_arr_time_t dl_tti;
|
||||
pnf_p7_arr_time_t ul_tti;
|
||||
pnf_p7_arr_time_t ul_dci;
|
||||
pnf_p7_arr_time_t tx_data;
|
||||
pnf_p7_dir_t dl;
|
||||
pnf_p7_dir_t ul;
|
||||
} pnf_p7_nr_stats_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t* buffer;
|
||||
uint32_t length;
|
||||
} pnf_p7_rx_message_segment_t;
|
||||
|
||||
typedef struct pnf_p7_rx_message pnf_p7_rx_message_t;
|
||||
|
||||
typedef struct pnf_p7_rx_message {
|
||||
uint8_t sequence_number;
|
||||
uint8_t num_segments_received;
|
||||
uint8_t num_segments_expected;
|
||||
|
||||
// the spec allows of upto 128 segments, this does seem excessive
|
||||
pnf_p7_rx_message_segment_t segments[128];
|
||||
|
||||
uint32_t rx_hr_time;
|
||||
|
||||
pnf_p7_rx_message_t* next;
|
||||
} pnf_p7_rx_message_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
pnf_p7_rx_message_t* msg_queue;
|
||||
|
||||
} pnf_p7_rx_reassembly_queue_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
||||
nfapi_pnf_p7_config_t _public;
|
||||
|
||||
//private data
|
||||
int p7_sock;
|
||||
|
||||
uint8_t terminate;
|
||||
|
||||
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
|
||||
uint8_t* rx_message_buffer;
|
||||
uint16_t rx_message_buffer_size;
|
||||
|
||||
pthread_mutex_t mutex; // should we allow the client to specifiy
|
||||
pthread_mutex_t pack_mutex; // should we allow the client to specifiy
|
||||
|
||||
nfapi_pnf_p7_subframe_buffer_t subframe_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
|
||||
nfapi_pnf_p7_slot_buffer_t slot_buffer[30/*NFAPI_MAX_TIMING_WINDOW_SIZE*/];
|
||||
uint32_t sequence_number;
|
||||
uint16_t max_num_segments;
|
||||
|
||||
pnf_p7_rx_reassembly_queue_t reassembly_queue;
|
||||
|
||||
uint8_t* reassemby_buffer;
|
||||
uint32_t reassemby_buffer_size;
|
||||
|
||||
uint16_t sfn_sf;
|
||||
uint32_t sf_start_time_hr;
|
||||
int32_t sfn_sf_shift;
|
||||
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
int mu;
|
||||
uint16_t sfn_slot;
|
||||
uint32_t slot_start_time_hr;
|
||||
int32_t slot_shift;
|
||||
|
||||
uint8_t timing_info_period_counter;
|
||||
uint8_t timing_info_aperiodic_send; // 0:false 1:true
|
||||
|
||||
uint32_t timing_info_ms_counter; // number of ms since last timing info
|
||||
|
||||
uint32_t dl_config_jitter;
|
||||
uint32_t ul_config_jitter;
|
||||
uint32_t hi_dci0_jitter;
|
||||
uint32_t tx_jitter;
|
||||
|
||||
//P7 NR
|
||||
uint32_t dl_tti_jitter;
|
||||
uint32_t ul_tti_jitter;
|
||||
uint32_t ul_dci_jitter;
|
||||
uint32_t tx_data_jitter;
|
||||
|
||||
uint32_t tick;
|
||||
pnf_p7_stats_t stats;
|
||||
pnf_p7_nr_stats_t nr_stats;
|
||||
|
||||
} pnf_p7_t;
|
||||
|
||||
int pnf_p7_message_pump(pnf_p7_t* pnf_p7);
|
||||
int pnf_nr_p7_message_pump(pnf_p7_t* pnf_p7);
|
||||
int pnf_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_p7_message_header_t* msg, uint32_t msg_len);
|
||||
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len);
|
||||
int pnf_p7_send_message(pnf_p7_t* pnf_p7, uint8_t* msg, uint32_t msg_len);
|
||||
|
||||
|
||||
int pnf_p7_slot_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
|
||||
int pnf_p7_subframe_ind(pnf_p7_t* config, uint16_t phy_id, uint16_t sfn_sf);
|
||||
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind);
|
||||
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind);
|
||||
pnf_p7_rx_message_t* pnf_p7_rx_reassembly_queue_add_segment(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint16_t sequence_number, uint16_t segment_number, uint8_t m, uint8_t* data, uint16_t data_len);
|
||||
void pnf_p7_rx_reassembly_queue_remove_msg(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, pnf_p7_rx_message_t* msg);
|
||||
void pnf_p7_rx_reassembly_queue_remove_old_msgs(pnf_p7_t* pnf_p7, pnf_p7_rx_reassembly_queue_t* queue, uint32_t rx_hr_time, uint32_t delta);
|
||||
|
||||
int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_header_t* header, uint32_t msg_len);
|
||||
|
||||
#endif /* _PNF_P7_H_ */
|
||||
|
||||
882
l2-fapi-proxy/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
Normal file
882
l2-fapi-proxy/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h
Normal file
@@ -0,0 +1,882 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NFAPI_PNF_INTERFACE_H_
|
||||
#define _NFAPI_PNF_INTERFACE_H_
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "nfapi_interface.h"
|
||||
#include "debug.h"
|
||||
// #include <openair2/PHY_INTERFACE/IF_Module.h>
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
// #include "openair1/PHY/defs_gNB.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/*! This enum is used to describe the states of the pnf
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NFAPI_PNF_IDLE = 0,
|
||||
NFAPI_PNF_CONFIGURED,
|
||||
NFAPI_PNF_RUNNING
|
||||
} nfapi_pnf_state_e;
|
||||
|
||||
/*! This enum is used to describe the states of a phy instance of a pnf
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
NFAPI_PNF_PHY_IDLE = 0,
|
||||
NFAPI_PNF_PHY_CONFIGURED = 1,
|
||||
NFAPI_PNF_PHY_RUNNING = 2
|
||||
} nfapi_pnf_phy_state_e;
|
||||
|
||||
typedef struct nfapi_pnf_phy_config nfapi_pnf_phy_config_t;
|
||||
|
||||
/*! Configuration information for a pnf phy instance
|
||||
*/
|
||||
typedef struct nfapi_pnf_phy_config
|
||||
{
|
||||
/*! The PHY id*/
|
||||
uint16_t phy_id;
|
||||
|
||||
/*! The state of the PNF PHY instance*/
|
||||
nfapi_pnf_phy_state_e state;
|
||||
|
||||
/*! Optional user defined data that will be passed back in the callbacks*/
|
||||
void* user_data;
|
||||
|
||||
/*! Pointer for use in a linked list */
|
||||
struct nfapi_pnf_phy_config* next;
|
||||
} nfapi_pnf_phy_config_t;
|
||||
|
||||
typedef struct nfapi_pnf_config nfapi_pnf_config_t;
|
||||
|
||||
/*! Configuration information for the pnf created by calling nfapi_pnf_create
|
||||
*/
|
||||
typedef struct nfapi_pnf_config
|
||||
{
|
||||
/*! A user define callback to override the default memory allocation
|
||||
* \param size The size of the data buffer to allocate
|
||||
* \return A pointer to a data buffer
|
||||
*/
|
||||
void* (*malloc)(size_t size);
|
||||
|
||||
/*! A user define callback to override the default memory deallocation
|
||||
* \param ptr Pointer to a data buffer to be deallocated
|
||||
*/
|
||||
void (*free)(void* ptr);
|
||||
|
||||
/*! A user define callback to handle trace from the pnf
|
||||
* \param level The trace level
|
||||
* \param message The trace string
|
||||
*
|
||||
* This is a vardic function.
|
||||
*/
|
||||
void (*trace)(nfapi_trace_level_t level, const char* message, ...);
|
||||
|
||||
/*! The ip address of the VNF
|
||||
*
|
||||
*/
|
||||
const char* vnf_ip_addr;
|
||||
|
||||
/*! The ip port of the VNF
|
||||
*/
|
||||
int vnf_p5_port;
|
||||
|
||||
/*! The state of the PNF */
|
||||
nfapi_pnf_state_e state;
|
||||
|
||||
/*! List of PHY instances configured for this PNF */
|
||||
nfapi_pnf_phy_config_t* phys;
|
||||
|
||||
/*! Configuation option of the p4 p5 encode decode functions */
|
||||
nfapi_p4_p5_codec_config_t codec_config;
|
||||
|
||||
/*! Optional user defined data that will be passed back in the callbacks*/
|
||||
void* user_data;
|
||||
|
||||
|
||||
/*! A callback for the PNF_PARAM.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param req A data structure for the decoded PNF_PARAM.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the PNF_PARAM.response after receiving the
|
||||
* PNF_PARAM.request. This can be done in the call back.
|
||||
*/
|
||||
int (*pnf_nr_param_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_request_t* req);
|
||||
int (*pnf_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_param_request_t* req);
|
||||
|
||||
/*! A callback for the PNF_CONFIG.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the PNF_CONFIG.response after receiving the
|
||||
* PNF_CONFIG.request. This can be done in the call back.
|
||||
*/
|
||||
int (*pnf_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_config_request_t* req);
|
||||
int (*pnf_nr_config_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_request_t* req);
|
||||
|
||||
/*! A callback for the PNF_START.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param req A data structure for the decoded PNF_CONFIG.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the PNF_START.response after receiving the
|
||||
* PNF_START.request. This can be done in the call back.
|
||||
*/
|
||||
int (*pnf_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_start_request_t* req);
|
||||
int (*pnf_nr_start_req)(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_request_t* req);
|
||||
|
||||
/*! A callback for the PNF_STOP.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param req A data structure for the decoded PNF_STOP.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the PNF_STOP.response after receiving the
|
||||
* PNF_STOP.request. This can be done in the call back.
|
||||
*/
|
||||
int (*pnf_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_stop_request_t* req);
|
||||
|
||||
/*! A callback for the PARAM.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded PARAM.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the PARAM.response after receiving the
|
||||
* PARAM.request. This can be done in the call back.
|
||||
*/
|
||||
int (*param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_param_request_t* req);
|
||||
int (*nr_param_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_param_request_scf_t* req);
|
||||
|
||||
/*! A callback for the CONFIG.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded CONFIG.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the CONFIG.response after receiving the
|
||||
* CONFIG.request. This can be done in the call back.
|
||||
*/
|
||||
int (*config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_config_request_t* req);
|
||||
int (*nr_config_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_config_request_scf_t* req);
|
||||
|
||||
/*! A callback for the START.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded START.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the START.response after the client has received the
|
||||
* first subframe indication from FAPI.
|
||||
*/
|
||||
int (*start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_start_request_t* req);
|
||||
int (*nr_start_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_start_request_scf_t* req);
|
||||
/*! A callback for the STOP.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded STOP.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the STOP.response after receiving the
|
||||
* STOP.request. This can be done in the call back.
|
||||
*/
|
||||
int (*stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_stop_request_t* req);
|
||||
int (*nr_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nr_stop_request_scf_t* req);
|
||||
|
||||
/*! A callback for the MEASUREMENT.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded MEASUREMENT.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the MEASUREMENT.response after receiving the
|
||||
* MEASUREMENT.request. This can be done in the call back.
|
||||
*/
|
||||
int (*measurement_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_measurement_request_t* req);
|
||||
|
||||
/*! A callback for the RSSI.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded RSSI.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the RSSI.response after receiving the
|
||||
* RSSI.request. This can be done in the call back.
|
||||
*/
|
||||
int (*rssi_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_rssi_request_t* req);
|
||||
|
||||
/*! A callback for the CELL_SEARCH.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded CELL_SEARCH.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the CELL_SEARCH.response after receiving the
|
||||
* CELL_SEARCH.request. This can be done in the call back.
|
||||
*/
|
||||
int (*cell_search_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_cell_search_request_t* req);
|
||||
|
||||
/*! A callback for the BROADCAST_DETECT.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded BROADCAST_DETECT.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the BROADCAST_DETECT.response after receiving the
|
||||
* BROADCAST_DETECT.request. This can be done in the call back.
|
||||
*/
|
||||
int (*broadcast_detect_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_broadcast_detect_request_t* req);
|
||||
|
||||
/*! A callback for the SYSTEM_INFORMATION_SCHEDULE.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded SYSTEM_INFORMATION_SCHEDULE.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the SYSTEM_INFORMATION_SCHEDULE.response after receiving the
|
||||
* SYSTEM_INFORMATION_SCHEDULE.request. This can be done in the call back.
|
||||
*/
|
||||
int (*system_information_schedule_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_schedule_request_t* req);
|
||||
|
||||
/*! A callback for the SYSTEM_INFORMATION.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded SYSTEM_INFORMATION.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the SYSTEM_INFORMATION.response after receiving the
|
||||
* SYSTEM_INFORMATION.request. This can be done in the call back.
|
||||
*/
|
||||
int (*system_information_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_system_information_request_t* req);
|
||||
|
||||
/*! A callback for the NMM_STOP.request
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param phy A pointer to the pnf phy configuration
|
||||
* \param req A data structure for the decoded NMM_STOP.request. This will have
|
||||
* been allocated on the stack
|
||||
* \return not currently used
|
||||
*
|
||||
* The client is expected to send the NMM_STOP.response after receiving the
|
||||
* NMM_STOP.request. This can be done in the call back.
|
||||
*/
|
||||
int (*nmm_stop_req)(nfapi_pnf_config_t* config, nfapi_pnf_phy_config_t* phy, nfapi_nmm_stop_request_t* req);
|
||||
|
||||
/*! A callback for any vendor extension messages recevied
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \param msg A pointer to the decode P4/P5 message
|
||||
* \return not current used
|
||||
*/
|
||||
int (*vendor_ext)(nfapi_pnf_config_t* config, void* msg);
|
||||
|
||||
/*! A callback to allocate vendor extension message
|
||||
* \param message_id The message id from the decode P4/P5 message header
|
||||
* \param msg_size A pointer a the size of the allocated message structure. The callee should set this
|
||||
* \return A pointer to a allocated P4/P5 message structure
|
||||
*/
|
||||
void* (*allocate_p4_p5_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
|
||||
|
||||
/*! A callback to deallocate vendor extension message
|
||||
* \param header A pointer to an P4/P5 message structure
|
||||
*/
|
||||
void (*deallocate_p4_p5_vendor_ext)(void* header);
|
||||
|
||||
|
||||
|
||||
} nfapi_pnf_config_t;
|
||||
|
||||
/*! Create a pnf configuration
|
||||
* \return A pointer to a pnf configuration struture
|
||||
*
|
||||
* This function will create and initialize a pnf instance. It is expected that
|
||||
* the client will set the callback and parameters need before calling nfapi_pnf_start
|
||||
*
|
||||
* 0 will be returned if it fails.
|
||||
*
|
||||
* \code
|
||||
* nfapi_pnf_config_t* config = nfapi_pnf_config_create(void);
|
||||
* \endcode
|
||||
*/
|
||||
nfapi_pnf_config_t* nfapi_pnf_config_create(void);
|
||||
|
||||
/*! Delete a pnf configuration
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \return 0 is success, -1 for failure
|
||||
*/
|
||||
int nfapi_pnf_config_destroy(nfapi_pnf_config_t* config);
|
||||
|
||||
/*! Start the PNF library.
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \return 0 is success, -1 for failure
|
||||
*
|
||||
* This function will not return until nfapi_pnf_stop is called
|
||||
*
|
||||
* \code
|
||||
* // Create the pnf config
|
||||
* nfapi_pnf_config_t* config = nfapi_pnf_config_create();
|
||||
*
|
||||
* // Assumed that the vnf_address and vnf_port are provided over the P9 interface
|
||||
* config->vnf_ip_addr = vnf_address;
|
||||
* config->vnf_p5_port = vnf_port;
|
||||
*
|
||||
* // Set the required callbacks
|
||||
* config->pnf_param_req = &pnf_param_request;
|
||||
* ...
|
||||
*
|
||||
* // Call start for the PNF to initiate a connection to the VNF
|
||||
* nfai_pnf_start(config);
|
||||
*
|
||||
* \endcode
|
||||
*/
|
||||
int nfapi_pnf_start(nfapi_pnf_config_t* config);
|
||||
int nfapi_nr_pnf_start(nfapi_pnf_config_t* config);
|
||||
|
||||
/*! Stop the PNF library.
|
||||
* \param config A pointer to the pnf configuration
|
||||
* \return 0 is success, -1 for failure
|
||||
*
|
||||
* This function will cause the nfapi_pnf_start function to return
|
||||
*/
|
||||
int nfapi_pnf_stop(nfapi_pnf_config_t* config);
|
||||
|
||||
/*! Send the PNF_PARAM.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp);
|
||||
int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp);
|
||||
|
||||
|
||||
/*! Send the PNF_CONFIG.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp);
|
||||
int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp);
|
||||
|
||||
/*! Send the PNF_START.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp);
|
||||
int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp);
|
||||
/*! Send the PNF_STOP.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp);
|
||||
|
||||
/*! Send the PARAM.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp);
|
||||
int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp);
|
||||
|
||||
/*! Send the CONFIG.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp);
|
||||
int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp);
|
||||
/*! Send the START.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp);
|
||||
int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp);
|
||||
|
||||
/*! Send the STOP.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp);
|
||||
|
||||
/*! Send the MEASUREMENT.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_measurement_resp(nfapi_pnf_config_t* config, nfapi_measurement_response_t* resp);
|
||||
|
||||
/*! Send the RSSI.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_rssi_resp(nfapi_pnf_config_t* config, nfapi_rssi_response_t* resp);
|
||||
|
||||
/*! Send the RSSI.indication
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param ind A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_rssi_ind(nfapi_pnf_config_t* config, nfapi_rssi_indication_t* ind);
|
||||
|
||||
/*! Send the CELL_SEARCH.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_cell_search_resp(nfapi_pnf_config_t* config, nfapi_cell_search_response_t* resp);
|
||||
|
||||
/*! Send the CELL_SEARCH.indication
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param ind A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_cell_search_ind(nfapi_pnf_config_t* config, nfapi_cell_search_indication_t* ind);
|
||||
|
||||
/*! Send the BROADCAST_DETECT.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_broadcast_detect_resp(nfapi_pnf_config_t* config, nfapi_broadcast_detect_response_t* resp);
|
||||
|
||||
/*! Send the BROADCAST_DETECT.indication
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param ind A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_broadcast_detect_ind(nfapi_pnf_config_t* config, nfapi_broadcast_detect_indication_t* ind);
|
||||
|
||||
/*! Send the SYSTEM_INFORMATION_SCHEDULE.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_system_information_schedule_resp(nfapi_pnf_config_t* config, nfapi_system_information_schedule_response_t* resp);
|
||||
|
||||
/*! Send the SYSTEM_INFORMATION_SCHEDULE.indication
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param ind A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_system_information_schedule_ind(nfapi_pnf_config_t* config, nfapi_system_information_schedule_indication_t* ind);
|
||||
|
||||
/*! Send the SYSTEM_INFORMATION.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_system_information_resp(nfapi_pnf_config_t* config, nfapi_system_information_response_t* resp);
|
||||
|
||||
/*! Send the SYSTEM_INFORMATION.indication
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param ind A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_system_information_ind(nfapi_pnf_config_t* config, nfapi_system_information_indication_t* ind);
|
||||
|
||||
/*! Send the NMM_STOP.response
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param resp A pointer to the message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_nmm_stop_resp(nfapi_pnf_config_t* config, nfapi_nmm_stop_response_t* resp);
|
||||
|
||||
/*! Send a vendor extension message
|
||||
* \param config A pointer to a pnf configuraiton
|
||||
* \param msg A pointer to the vendor extention message structure
|
||||
* \param msg_len The size of the vendor extention message structure
|
||||
* \return 0 for success, -1 for failure
|
||||
*
|
||||
*/
|
||||
int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len);
|
||||
|
||||
//--------------------------
|
||||
|
||||
/*! A subframe buffer structure which can be used by the client to
|
||||
* to configure the dummy information
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t sfn_sf;
|
||||
|
||||
nfapi_dl_config_request_t* dl_config_req;
|
||||
nfapi_ul_config_request_t* ul_config_req;
|
||||
nfapi_hi_dci0_request_t* hi_dci0_req;
|
||||
nfapi_tx_request_t* tx_req;
|
||||
nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
|
||||
nfapi_ue_release_request_t* ue_release_req;
|
||||
} nfapi_pnf_p7_subframe_buffer_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//uint16_t sfn_slot
|
||||
uint16_t sfn;
|
||||
uint16_t slot;
|
||||
nfapi_nr_dl_tti_request_t* dl_tti_req;
|
||||
nfapi_nr_ul_tti_request_t* ul_tti_req;
|
||||
nfapi_nr_ul_dci_request_t* ul_dci_req;
|
||||
nfapi_nr_tx_data_request_t* tx_data_req;
|
||||
|
||||
//TODO: check these two later
|
||||
//nfapi_lbt_dl_config_request_t* lbt_dl_config_req;
|
||||
//nfapi_ue_release_request_t* ue_release_req;
|
||||
} nfapi_pnf_p7_slot_buffer_t;
|
||||
|
||||
typedef struct L1_rxtx_proc_t L1_rxtx_proc_t;
|
||||
|
||||
/// Context data structure for RX/TX portion of slot processing
|
||||
typedef struct gNB_L1_rxtx_proc_t gNB_L1_rxtx_proc_t;
|
||||
|
||||
typedef struct nfapi_pnf_p7_config nfapi_pnf_p7_config_t;
|
||||
|
||||
/*! The nfapi PNF PHY P7 configuration information created using the nfapi_pnf_p7_create function
|
||||
*/
|
||||
typedef struct nfapi_pnf_p7_config
|
||||
{
|
||||
/*! A user define callback to override the default memory allocation
|
||||
* \param size The size of the buffer to allocate
|
||||
* \return An allocated buffer. 0 in the case of failure
|
||||
*
|
||||
* If not set malloc will be used
|
||||
*/
|
||||
void* (*malloc)(size_t size);
|
||||
|
||||
/*! A user define callback to override the default memory deallocation
|
||||
* \param ptr Pointer to a buffer to dellocate
|
||||
*
|
||||
* If not set free will be used
|
||||
*/
|
||||
void (*free)(void* ptr);
|
||||
|
||||
/*! A user define callback to handle trace from the pnf
|
||||
* \param level The trace level
|
||||
* \param message The message string
|
||||
*/
|
||||
void (*trace)(nfapi_trace_level_t level, const char* message, ...);
|
||||
|
||||
/*! The PHY id*/
|
||||
uint16_t phy_id;
|
||||
|
||||
// remote
|
||||
/*! The VNF P7 UDP port */
|
||||
int remote_p7_port;
|
||||
/*! The VNF P7 UDP address */
|
||||
char* remote_p7_addr;
|
||||
|
||||
// local
|
||||
/*! The PNF P7 UDP port */
|
||||
int local_p7_port;
|
||||
/*! The PNF P7 UDP address */
|
||||
char* local_p7_addr;
|
||||
|
||||
/*! Flag to indicate of the pnf should use the P7 checksum */
|
||||
uint8_t checksum_enabled;
|
||||
|
||||
/*! The maxium size of a P7 segement. If a message is large that this it
|
||||
* will be segmented. Note: u32 to cover 4G and 5G */
|
||||
uint32_t segment_size;
|
||||
|
||||
/*! The dummy subframe buffer structure that should be used in case there
|
||||
* are no 'valid' subframe messages */
|
||||
nfapi_pnf_p7_subframe_buffer_t dummy_subframe;
|
||||
|
||||
nfapi_pnf_p7_slot_buffer_t dummy_slot; // defining a slot equivalent for now
|
||||
|
||||
/*! Configuration options for the p7 pack unpack functions*/
|
||||
nfapi_p7_codec_config_t codec_config;
|
||||
|
||||
/*! Optional userdata that will be passed back in the callbacks*/
|
||||
void* user_data;
|
||||
|
||||
// tdb : if these should be public
|
||||
uint16_t subframe_buffer_size;
|
||||
uint16_t slot_buffer_size;
|
||||
uint8_t timing_info_mode_periodic; // 0:false 1:true
|
||||
uint8_t timing_info_mode_aperiodic; // 0:false 1:true
|
||||
uint8_t timing_info_period; // 1..225 in subframes
|
||||
|
||||
/*! A callback for the DL_CONFIG.request
|
||||
* \param config A poiner to the PNF P7 config
|
||||
* \param req A pointer to the dl config request message structure
|
||||
* \return not currently used
|
||||
*/
|
||||
int (*dl_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req);
|
||||
int (*dl_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_dl_config_request_t* req);
|
||||
|
||||
/*! A callback for the UL_CONFIG.request
|
||||
* \param config A poiner to the PNF P7 config
|
||||
* \param req A pointer to the ul config request message structure
|
||||
* \return not currently used
|
||||
*/
|
||||
int (*ul_tti_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req);
|
||||
int (*ul_config_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_ul_config_request_t* req);
|
||||
|
||||
/*! A callback for the HI_DCI0.request
|
||||
* \param config A poiner to the PNF P7 config
|
||||
* \param req A pointer to the hi dci0 request message structure
|
||||
* \return not currently used
|
||||
*/
|
||||
int (*ul_dci_req_fn)(gNB_L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req);
|
||||
int (*hi_dci0_req)(L1_rxtx_proc_t *proc,nfapi_pnf_p7_config_t* config, nfapi_hi_dci0_request_t* req);
|
||||
|
||||
/*! A callback for the TX_REQ.request
|
||||
* \param config A poiner to the PNF P7 config
|
||||
* \param req A pointer to the tx request message structure
|
||||
* \return not currently used
|
||||
*
|
||||
* The TX request contains pointers to the downlink PDUs to be sent. In the case that the FAPI interface
|
||||
* will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0
|
||||
* and then use the p7 codec config free function to release the pdu's when appropriate.
|
||||
*/
|
||||
int (*tx_data_req_fn)(nfapi_pnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req);
|
||||
int (*tx_req)(nfapi_pnf_p7_config_t* config, nfapi_tx_request_t* req);
|
||||
|
||||
/*! A callback for the LBT_DL_CONFIG.request
|
||||
* \param config A poiner to the PNF P7 config
|
||||
* \param req A pointer to the lbt dl request message structure
|
||||
* \return not currently used
|
||||
*/
|
||||
int (*lbt_dl_config_req)(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req);
|
||||
|
||||
/*! A callback for the UE_RELEASE_REQ.request
|
||||
* \param config A poiner to the PNF P7 config
|
||||
* \param req A pointer to the release rnti request message structure
|
||||
* \return not currently used
|
||||
*
|
||||
* The release request contains pointers to the release rnti to be sent. In the case that the FAPI interface
|
||||
* will 'keep' the pointers until they are transmitted the callee should set the pointers in the req to 0
|
||||
* and then use the p7 codec config free function to release the rnti when appropriate.
|
||||
*/
|
||||
int (*ue_release_req)(nfapi_pnf_p7_config_t* config, nfapi_ue_release_request_t* req);
|
||||
|
||||
/*! A callback for vendor extension messages
|
||||
* \param config A poiner to the PNF P7 config
|
||||
* \param msg A pointer to a decode vendor extention message
|
||||
* \return not currently used
|
||||
*/
|
||||
int (*vendor_ext)(nfapi_pnf_p7_config_t* config, void* msg);
|
||||
|
||||
/*! A callback to allocate vendor extension message
|
||||
* \param message_id The vendor extention message id from the decode message header
|
||||
* \param msg_size A pointer to size of the allocate vendor extention message. Set by the callee
|
||||
* \return A pointer to an allocated vendor extention message structure. 0 if failed
|
||||
*
|
||||
*
|
||||
*/
|
||||
void* (*allocate_p7_vendor_ext)(uint16_t message_id, uint16_t* msg_size);
|
||||
|
||||
/*! A callback to deallocate vendor extension message
|
||||
* \param header A pointer to a p7 vendor extention message
|
||||
*/
|
||||
void (*deallocate_p7_vendor_ext)(void* header);
|
||||
|
||||
|
||||
|
||||
} nfapi_pnf_p7_config_t;
|
||||
|
||||
/*! Create and initialise a nfapi_pnf_p7_config structure
|
||||
* \return A pointer to a PNF P7 config structure
|
||||
*/
|
||||
nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create(void);
|
||||
|
||||
/*! Delete an nfapi_pnf_p7_config structure
|
||||
* \param config
|
||||
*/
|
||||
int nfapi_pnf_p7_config_destroy(nfapi_pnf_p7_config_t* config);
|
||||
|
||||
|
||||
/*! Start the PNF P7 library.
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \return 0 means success, -1 means failure
|
||||
*
|
||||
* This function will not return until nfapi_pnf_p7_stop is called.
|
||||
*/
|
||||
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config);
|
||||
int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config);
|
||||
|
||||
/*! Stop the PNF P7 library.
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \return 0 means success, -1 means failure
|
||||
*
|
||||
* This function will cause the nfapi_pnf_p7_start to return
|
||||
*/
|
||||
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config);
|
||||
|
||||
/*! NR Slot indication
|
||||
* message copied from nfapi_pnf_p7_subframe_ind
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param phy_id The phy_id for the phy instance
|
||||
* \param sfn_sf The SFN and SF in the format of FAPI
|
||||
* \return 0 means success, -1 means failure
|
||||
*
|
||||
* The client should call the subframe indication every 1ms. The PNF will
|
||||
* respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer
|
||||
*
|
||||
* If messages are not in the subframe buffer, they dummy subframe messages will be sent
|
||||
*/
|
||||
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot);
|
||||
|
||||
|
||||
/*! Subframe indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param phy_id The phy_id for the phy instance
|
||||
* \param sfn_sf The SFN and SF in the format of FAPI
|
||||
* \return 0 means success, -1 means failure
|
||||
*
|
||||
* The client should call the subframe indication every 1ms. The PNF will
|
||||
* respond by invoking the pnf p7 subframe callbacks with the messages from the subframe buffer
|
||||
*
|
||||
* If messages are not in the subframe buffer, they dummy subframe messages will be sent
|
||||
*/
|
||||
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf);
|
||||
|
||||
/*! Send the HARQ.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the harq indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t* ind);
|
||||
|
||||
/*! Send the CRC.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the crc indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind);
|
||||
|
||||
/*! Send the RX.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the rx indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind);
|
||||
|
||||
/*! Send the RACH.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the rach indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t* ind);
|
||||
|
||||
/*! Send the SRS.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the srs indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_srs_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind);
|
||||
|
||||
/*! Send the SR.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the sr indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind);
|
||||
|
||||
/*! Send the CQI.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the cqi indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* ind);
|
||||
|
||||
/*! Send the LBT_DL.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the lbt dl indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind);
|
||||
|
||||
/*! Send the NB_HARQ.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the lbt dl indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind);
|
||||
|
||||
/*! Send the NRACH.indication
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param ind A pointer to the lbt dl indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind);
|
||||
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind);
|
||||
|
||||
|
||||
/*! Send a vendor exntesion message
|
||||
* \param config A pointer to a PNF P7 config
|
||||
* \param msg A pointer to the lbt dl indication message structure
|
||||
* \return 0 means success, -1 means failure
|
||||
*/
|
||||
int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg);
|
||||
|
||||
int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _NFAPI_PNF_INTERFACE_H_
|
||||
2344
l2-fapi-proxy/open-nFAPI/pnf/src/pnf.c
Normal file
2344
l2-fapi-proxy/open-nFAPI/pnf/src/pnf.c
Normal file
File diff suppressed because it is too large
Load Diff
585
l2-fapi-proxy/open-nFAPI/pnf/src/pnf_interface.c
Normal file
585
l2-fapi-proxy/open-nFAPI/pnf/src/pnf_interface.c
Normal file
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "pnf.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include "nfapi_nr_interface.h"
|
||||
#include "nfapi_nr_interface_scf.h"
|
||||
|
||||
nfapi_pnf_config_t* nfapi_pnf_config_create()
|
||||
{
|
||||
pnf_t* _this = (pnf_t*)malloc(sizeof(pnf_t));
|
||||
|
||||
if(_this == 0)
|
||||
return 0;
|
||||
|
||||
memset(_this, 0, sizeof(pnf_t));
|
||||
|
||||
_this->sctp = 1; // enable sctp
|
||||
|
||||
_this->_public.vnf_p5_port = NFAPI_P5_SCTP_PORT;
|
||||
|
||||
_this->_public.malloc = &malloc;
|
||||
_this->_public.free = &free;
|
||||
|
||||
_this->_public.codec_config.allocate = &malloc;
|
||||
_this->_public.codec_config.deallocate = &free;
|
||||
|
||||
return (nfapi_pnf_config_t* )_this;
|
||||
}
|
||||
|
||||
void nfapi_pnf_config_destory(nfapi_pnf_config_t* config)
|
||||
{
|
||||
free(config);
|
||||
}
|
||||
|
||||
int nfapi_pnf_start(nfapi_pnf_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
while (_this->terminate == 0)
|
||||
{
|
||||
int connect_result = pnf_connect(_this);
|
||||
|
||||
if(connect_result > 0)
|
||||
{
|
||||
pnf_message_pump(_this);
|
||||
}
|
||||
else if(connect_result < 0)
|
||||
{
|
||||
return connect_result;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfapi_nr_pnf_start(nfapi_pnf_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
while (_this->terminate == 0)
|
||||
{
|
||||
int connect_result = pnf_connect(_this);
|
||||
|
||||
if(connect_result > 0)
|
||||
{
|
||||
pnf_nr_message_pump(_this);
|
||||
}
|
||||
else if(connect_result < 0)
|
||||
{
|
||||
return connect_result;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() terminate=1 - EXITTING............\n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfapi_pnf_stop(nfapi_pnf_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
_this->terminate = 1;
|
||||
|
||||
// todo wait for the pnf to stop before returning
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int nfapi_nr_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_param_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_param_response_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_pnf_param_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_param_response_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_pnf_config_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
config->state = NFAPI_PNF_CONFIGURED;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_config_response_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_nr_pnf_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_config_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
config->state = NFAPI_PNF_CONFIGURED;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_config_response_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_pnf_start_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
config->state = NFAPI_PNF_RUNNING;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_start_response_t));
|
||||
}
|
||||
|
||||
int nfapi_nr_pnf_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_pnf_start_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
config->state = NFAPI_PNF_RUNNING;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_pnf_start_response_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_pnf_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_pnf_stop_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
config->state = NFAPI_PNF_CONFIGURED;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_pnf_stop_response_t));
|
||||
}
|
||||
int nfapi_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_param_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_param_response_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_nr_pnf_param_resp(nfapi_pnf_config_t* config, nfapi_nr_param_response_scf_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_param_response_scf_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_config_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
|
||||
|
||||
if(phy)
|
||||
{
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
phy->state = NFAPI_PNF_PHY_CONFIGURED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_config_response_t));
|
||||
}
|
||||
|
||||
int nfapi_nr_pnf_config_resp(nfapi_pnf_config_t* config, nfapi_nr_config_response_scf_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
|
||||
|
||||
if(phy)
|
||||
{
|
||||
if(resp->error_code == NFAPI_NR_CONFIG_MSG_OK)
|
||||
{
|
||||
phy->state = NFAPI_PNF_PHY_CONFIGURED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_config_response_scf_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_start_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
|
||||
if(phy)
|
||||
{
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
phy->state = NFAPI_PNF_PHY_RUNNING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_start_response_t));
|
||||
}
|
||||
|
||||
int nfapi_nr_pnf_start_resp(nfapi_pnf_config_t* config, nfapi_nr_start_response_scf_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
|
||||
if(phy)
|
||||
{
|
||||
if(resp->error_code == NFAPI_NR_START_MSG_OK)
|
||||
{
|
||||
phy->state = NFAPI_PNF_PHY_RUNNING;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknown phy id %d\n", __FUNCTION__, resp->header.phy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pnf_nr_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_nr_start_response_scf_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_pnf_stop_resp(nfapi_pnf_config_t* config, nfapi_stop_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
nfapi_pnf_phy_config_t* phy = nfapi_pnf_phy_config_find(config, resp->header.phy_id);
|
||||
if(phy)
|
||||
{
|
||||
if(resp->error_code == NFAPI_MSG_OK)
|
||||
{
|
||||
phy->state = NFAPI_PNF_PHY_CONFIGURED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: unknow phy id %d\n", __FUNCTION__, resp->header.phy_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_stop_response_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_measurement_resp(nfapi_pnf_config_t* config, nfapi_measurement_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, &(resp->header), sizeof(nfapi_measurement_response_t));
|
||||
}
|
||||
|
||||
|
||||
int nfapi_pnf_rssi_resp(nfapi_pnf_config_t* config, nfapi_rssi_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_rssi_response_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_rssi_ind(nfapi_pnf_config_t* config, nfapi_rssi_indication_t* ind)
|
||||
{
|
||||
if (config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_rssi_indication_t));
|
||||
}
|
||||
int nfapi_pnf_cell_search_resp(nfapi_pnf_config_t* config, nfapi_cell_search_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Send CELL_SEARCH.response\n");
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_cell_search_response_t));
|
||||
}
|
||||
int nfapi_pnf_cell_search_ind(nfapi_pnf_config_t* config, nfapi_cell_search_indication_t* ind)
|
||||
{
|
||||
if (config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_cell_search_indication_t));
|
||||
}
|
||||
int nfapi_pnf_broadcast_detect_resp(nfapi_pnf_config_t* config, nfapi_broadcast_detect_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_broadcast_detect_response_t));
|
||||
}
|
||||
int nfapi_pnf_broadcast_detect_ind(nfapi_pnf_config_t* config, nfapi_broadcast_detect_indication_t* ind)
|
||||
{
|
||||
if (config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_broadcast_detect_indication_t));
|
||||
}
|
||||
int nfapi_pnf_system_information_schedule_resp(nfapi_pnf_config_t* config, nfapi_system_information_schedule_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_system_information_schedule_response_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_system_information_schedule_ind(nfapi_pnf_config_t* config, nfapi_system_information_schedule_indication_t* ind)
|
||||
{
|
||||
if (config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_system_information_schedule_indication_t));
|
||||
}
|
||||
int nfapi_pnf_system_information_resp(nfapi_pnf_config_t* config, nfapi_system_information_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_system_information_response_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_system_information_ind(nfapi_pnf_config_t* config, nfapi_system_information_indication_t* ind)
|
||||
{
|
||||
if (config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(ind->header), sizeof(nfapi_system_information_indication_t));
|
||||
}
|
||||
int nfapi_pnf_nmm_stop_resp(nfapi_pnf_config_t* config, nfapi_nmm_stop_response_t* resp)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p4_message(_this, &(resp->header), sizeof(nfapi_nmm_stop_request_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_vendor_extension(nfapi_pnf_config_t* config, nfapi_p4_p5_message_header_t* msg, uint32_t msg_len)
|
||||
{
|
||||
// ensure it's valid
|
||||
if (config == NULL || msg == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_t* _this = (pnf_t*)(config);
|
||||
|
||||
return pnf_pack_and_send_p5_message(_this, msg, msg_len);
|
||||
}
|
||||
3216
l2-fapi-proxy/open-nFAPI/pnf/src/pnf_p7.c
Normal file
3216
l2-fapi-proxy/open-nFAPI/pnf/src/pnf_p7.c
Normal file
File diff suppressed because it is too large
Load Diff
333
l2-fapi-proxy/open-nFAPI/pnf/src/pnf_p7_interface.c
Normal file
333
l2-fapi-proxy/open-nFAPI/pnf/src/pnf_p7_interface.c
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "pnf_p7.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
nfapi_pnf_p7_config_t* nfapi_pnf_p7_config_create()
|
||||
{
|
||||
pnf_p7_t* _this = NULL;
|
||||
int rc = posix_memalign((void**)&_this, 32, sizeof(pnf_p7_t));
|
||||
|
||||
if (_this == NULL || rc != 0)
|
||||
return 0;
|
||||
|
||||
|
||||
// set the default parameters
|
||||
_this->_public.segment_size = 65000; // UDP max packet size is 65535
|
||||
_this->max_num_segments = 8;
|
||||
|
||||
_this->_public.subframe_buffer_size = 8;// TODO: Initialize the slot_buffer size
|
||||
_this->_public.timing_info_mode_periodic = 1;
|
||||
_this->_public.timing_info_period = 32;
|
||||
_this->_public.timing_info_mode_aperiodic = 1;
|
||||
|
||||
_this->_public.checksum_enabled = 1;
|
||||
|
||||
_this->_public.malloc = &malloc;
|
||||
_this->_public.free = &free;
|
||||
|
||||
_this->_public.codec_config.allocate = &malloc;
|
||||
_this->_public.codec_config.deallocate = &free;
|
||||
|
||||
// cppcheck-suppress memleak
|
||||
return &(_this->_public);
|
||||
}
|
||||
|
||||
void nfapi_pnf_p7_config_destory(nfapi_pnf_p7_config_t* config)
|
||||
{
|
||||
if(config == 0)
|
||||
return ;
|
||||
|
||||
free(config);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int nfapi_pnf_p7_start(nfapi_pnf_p7_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
|
||||
|
||||
pnf_p7_message_pump(_this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfapi_nr_pnf_p7_start(nfapi_pnf_p7_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s\n", __FUNCTION__);
|
||||
|
||||
_this->rx_message_buffer = realloc(_this->rx_message_buffer, NFAPI_MAX_PACKED_MESSAGE_SIZE);
|
||||
_this->rx_message_buffer_size = NFAPI_MAX_PACKED_MESSAGE_SIZE;
|
||||
|
||||
pnf_nr_p7_message_pump(_this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int nfapi_pnf_p7_stop(nfapi_pnf_p7_config_t* config)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
_this->terminate = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_slot_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn, uint16_t slot)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
return pnf_p7_slot_ind(_this, phy_id, sfn, slot);
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_subframe_ind(nfapi_pnf_p7_config_t* config, uint16_t phy_id, uint16_t sfn_sf)
|
||||
{
|
||||
// Verify that config is not null
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
return pnf_p7_subframe_ind(_this, phy_id, sfn_sf);
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_harq_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_harq_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_crc_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_crc_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_rx_ind(nfapi_pnf_p7_config_t* config, nfapi_rx_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_rx_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_rach_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_rach_indication_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_sr_ind(nfapi_pnf_p7_config_t* config, nfapi_sr_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_sr_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_cqi_ind(nfapi_pnf_p7_config_t* config, nfapi_cqi_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_cqi_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_lbt_dl_ind(nfapi_pnf_p7_config_t* config, nfapi_lbt_dl_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_lbt_dl_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_nb_harq_ind(nfapi_pnf_p7_config_t* config, nfapi_nb_harq_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nb_harq_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_nrach_ind(nfapi_pnf_p7_config_t* config, nfapi_nrach_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, (nfapi_p7_message_header_t*)ind, sizeof(nfapi_nrach_indication_t));
|
||||
}
|
||||
int nfapi_pnf_p7_vendor_extension(nfapi_pnf_p7_config_t* config, nfapi_p7_message_header_t* msg)
|
||||
{
|
||||
if(config == NULL || msg == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_p7_pack_and_send_p7_message(_this, msg, 0);
|
||||
}
|
||||
|
||||
int nfapi_pnf_ue_release_resp(nfapi_pnf_p7_config_t* config, nfapi_ue_release_response_t* resp)
|
||||
{
|
||||
if (config == NULL || resp == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: NULL parameters\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
return pnf_p7_pack_and_send_p7_message(_this, &(resp->header), sizeof(nfapi_ue_release_response_t));
|
||||
}
|
||||
|
||||
//NR UPLINK INDICATION
|
||||
|
||||
int nfapi_pnf_p7_nr_slot_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_slot_indication_scf_t* ind)
|
||||
{
|
||||
if (config == NULL || ind == NULL) {
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_slot_indication_scf_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_nr_rx_data_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rx_data_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
|
||||
int ret = pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rx_data_indication_t));
|
||||
if (ret == 0) {
|
||||
for (int i = 0; i < ind->number_of_pdus; ++i)
|
||||
_this->nr_stats.ul.bytes += ind->pdu_list[i].pdu_length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_nr_crc_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_crc_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_crc_indication_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_nr_srs_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_srs_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_srs_indication_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_nr_uci_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_uci_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_uci_indication_t));
|
||||
}
|
||||
|
||||
int nfapi_pnf_p7_nr_rach_ind(nfapi_pnf_p7_config_t* config, nfapi_nr_rach_indication_t* ind)
|
||||
{
|
||||
if(config == NULL || ind == NULL)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s: invalid input params\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pnf_p7_t* _this = (pnf_p7_t*)(config);
|
||||
return pnf_nr_p7_pack_and_send_p7_message(_this, (nfapi_nr_p7_message_header_t*)ind, sizeof(nfapi_nr_rach_indication_t));
|
||||
}
|
||||
28
l2-fapi-proxy/open-nFAPI/pnf/tests/Makefile.am
Normal file
28
l2-fapi-proxy/open-nFAPI/pnf/tests/Makefile.am
Normal file
@@ -0,0 +1,28 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#nfapi unit test
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/pnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
|
||||
|
||||
check_PROGRAMS= test_pnf
|
||||
|
||||
test_pnf_SOURCES = pnf_cunit_main.c ../../common/src/debug.c
|
||||
test_pnf_LDADD=$(top_builddir)/pnf/libnfapi_pnf.a $(top_builddir)/nfapi/libnfapi.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit
|
||||
|
||||
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
|
||||
TESTS=$(check_PROGRAMS)
|
||||
EXTRA_DIST = $(TESTS)
|
||||
2374
l2-fapi-proxy/open-nFAPI/pnf/tests/pnf_cunit_main.c
Normal file
2374
l2-fapi-proxy/open-nFAPI/pnf/tests/pnf_cunit_main.c
Normal file
File diff suppressed because it is too large
Load Diff
22
l2-fapi-proxy/open-nFAPI/pnf_sim/Makefile.am
Normal file
22
l2-fapi-proxy/open-nFAPI/pnf_sim/Makefile.am
Normal file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/pnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/nfapi/inc $(XML_CFLAGS) -g
|
||||
AM_CXXFLAGS = -I$(top_srcdir)/pnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/pnf/public_inc -I$(top_srcdir)/common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/nfapi/inc $(XML_CFLAGS) -std=c++11 $(BOOST_CPPFLAGS) -g
|
||||
bin_PROGRAMS = pnfsim
|
||||
pnfsim_SOURCES = src/main.cpp src/fapi_stub.cpp
|
||||
LDADD= $(top_builddir)/pnf/libnfapi_pnf.a $(top_builddir)/common/libnfapi_common.a $(top_builddir)/nfapi/libnfapi.a $(top_builddir)/sim_common/libnfapi_sim_common.a -L$(libdir) -lpthread -lrt -lsctp -lz
|
||||
1800
l2-fapi-proxy/open-nFAPI/pnf_sim/inc/fapi_interface.h
Normal file
1800
l2-fapi-proxy/open-nFAPI/pnf_sim/inc/fapi_interface.h
Normal file
File diff suppressed because it is too large
Load Diff
76
l2-fapi-proxy/open-nFAPI/pnf_sim/inc/fapi_stub.h
Normal file
76
l2-fapi-proxy/open-nFAPI/pnf_sim/inc/fapi_stub.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _FAPI_STUB_H_
|
||||
#define _FAPI_STUB_H_
|
||||
|
||||
#include "fapi_interface.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct fapi fapi_t;
|
||||
|
||||
typedef struct fapi {
|
||||
void* user_data;
|
||||
} fapi_t;
|
||||
|
||||
typedef struct {
|
||||
int (*fapi_param_response)(fapi_t* fapi, fapi_param_resp_t* resp);
|
||||
int (*fapi_config_response)(fapi_t* fapi, fapi_config_resp_t* resp);
|
||||
|
||||
int (*fapi_subframe_ind)(fapi_t* fapi, fapi_subframe_ind_t* ind);
|
||||
|
||||
int (*fapi_harq_ind)(fapi_t* fapi, fapi_harq_ind_t* ind);
|
||||
int (*fapi_crc_ind)(fapi_t* fapi, fapi_crc_ind_t* ind);
|
||||
int (*fapi_rx_ulsch_ind)(fapi_t* fapi, fapi_rx_ulsch_ind_t* ind);
|
||||
int (*fapi_rx_cqi_ind)(fapi_t* fapi, fapi_rx_cqi_ind_t* ind);
|
||||
int (*fapi_rx_sr_ind)(fapi_t* fapi, fapi_rx_sr_ind_t* ind);
|
||||
int (*fapi_rach_ind)(fapi_t* fapi, fapi_rach_ind_t* ind);
|
||||
int (*fapi_srs_ind)(fapi_t* fapi, fapi_srs_ind_t* ind);
|
||||
|
||||
int (*fapi_lbt_dl_ind)(fapi_t* fapi, fapi_lbt_dl_ind_t* ind);
|
||||
int (*fapi_nb_harq_ind)(fapi_t* fapi, fapi_nb_harq_ind_t* ind);
|
||||
int (*fapi_nrach_ind)(fapi_t* fapi, fapi_nrach_ind_t* ind);
|
||||
|
||||
} fapi_cb_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint16_t duplex_mode;
|
||||
uint16_t dl_channel_bw_support;
|
||||
uint16_t ul_channel_bw_support;
|
||||
} fapi_config_t;
|
||||
|
||||
fapi_t* fapi_create(fapi_cb_t* callbacks, fapi_config_t* config);
|
||||
|
||||
void fapi_start_data(fapi_t* fapi, unsigned rx_port, const char* tx_address, unsigned tx_port);
|
||||
|
||||
int fapi_param_request(fapi_t* fapi, fapi_param_req_t* req);
|
||||
int fapi_config_request(fapi_t* fapi, fapi_config_req_t* req);
|
||||
int fapi_start_request(fapi_t* fapi, fapi_start_req_t* req);
|
||||
|
||||
int fapi_dl_config_request(fapi_t* fapi, fapi_dl_config_req_t* req);
|
||||
int fapi_ul_config_request(fapi_t* fapi, fapi_ul_config_req_t* req);
|
||||
int fapi_hi_dci0_request(fapi_t* fapi, fapi_hi_dci0_req_t* req);
|
||||
int fapi_tx_request(fapi_t* fapi, fapi_tx_req_t* req);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
524
l2-fapi-proxy/open-nFAPI/pnf_sim/src/fapi_stub.cpp
Normal file
524
l2-fapi-proxy/open-nFAPI/pnf_sim/src/fapi_stub.cpp
Normal file
@@ -0,0 +1,524 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "fapi_stub.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <netdb.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
#include <list>
|
||||
|
||||
struct phy_pdu {
|
||||
phy_pdu() : buffer_len(1500), buffer(0), len(0) {
|
||||
buffer = (char *) malloc(buffer_len);
|
||||
}
|
||||
|
||||
virtual ~phy_pdu() {
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
unsigned buffer_len;
|
||||
char *buffer;
|
||||
unsigned len;
|
||||
};
|
||||
|
||||
class fapi_private {
|
||||
std::mutex mutex;
|
||||
std::queue<phy_pdu *> rx_buffer;
|
||||
|
||||
std::queue<phy_pdu *> free_store;
|
||||
public:
|
||||
|
||||
fapi_private()
|
||||
: byte_count(0), tick(0), first_dl_config(false) {
|
||||
}
|
||||
|
||||
phy_pdu *allocate_phy_pdu() {
|
||||
phy_pdu *pdu = 0;
|
||||
mutex.lock();
|
||||
|
||||
if(free_store.empty()) {
|
||||
pdu = new phy_pdu();
|
||||
} else {
|
||||
pdu = free_store.front();
|
||||
free_store.pop();
|
||||
}
|
||||
|
||||
mutex.unlock();
|
||||
return pdu;
|
||||
}
|
||||
|
||||
void release_phy_pdu(phy_pdu *pdu) {
|
||||
mutex.lock();
|
||||
free_store.push(pdu);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
bool rx_buffer_empty() {
|
||||
bool empty;
|
||||
mutex.lock();
|
||||
empty = rx_buffer.empty();
|
||||
mutex.unlock();
|
||||
return empty;
|
||||
}
|
||||
|
||||
|
||||
void push_rx_buffer(phy_pdu *buff) {
|
||||
mutex.lock();
|
||||
rx_buffer.push(buff);
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
phy_pdu *pop_rx_buffer() {
|
||||
phy_pdu *buff = 0;
|
||||
mutex.lock();
|
||||
|
||||
if(!rx_buffer.empty()) {
|
||||
buff = rx_buffer.front();
|
||||
rx_buffer.pop();
|
||||
}
|
||||
|
||||
mutex.unlock();
|
||||
return buff;
|
||||
}
|
||||
|
||||
uint32_t byte_count;
|
||||
uint32_t tick;
|
||||
bool first_dl_config;
|
||||
|
||||
};
|
||||
|
||||
extern "C"
|
||||
{
|
||||
typedef struct fapi_internal {
|
||||
fapi_t _public;
|
||||
|
||||
fapi_cb_t callbacks;
|
||||
|
||||
uint8_t state;
|
||||
fapi_config_t config;
|
||||
|
||||
int rx_sock;
|
||||
int tx_sock;
|
||||
struct sockaddr_in tx_addr;
|
||||
|
||||
uint32_t tx_byte_count;
|
||||
uint32_t tick;
|
||||
|
||||
fapi_private *fapi;
|
||||
|
||||
} fapi_internal_t;
|
||||
}
|
||||
|
||||
void send_uplink_indications(fapi_internal_t *instance, uint16_t sfn_sf) {
|
||||
fapi_harq_ind_t harq_ind;
|
||||
(instance->callbacks.fapi_harq_ind)(&(instance->_public), &harq_ind);
|
||||
fapi_crc_ind_t crc_ind;
|
||||
crc_ind.header.message_id = FAPI_CRC_INDICATION;
|
||||
crc_ind.header.length = 0; //??;
|
||||
crc_ind.sfn_sf = sfn_sf;
|
||||
crc_ind.body.number_of_crcs = 1;
|
||||
crc_ind.body.pdus[0].rx_ue_info.handle = 0; //??
|
||||
crc_ind.body.pdus[0].rx_ue_info.rnti = 0; //??
|
||||
crc_ind.body.pdus[0].rel8_pdu.crc_flag = 1;
|
||||
(instance->callbacks.fapi_crc_ind)(&(instance->_public), &crc_ind);
|
||||
|
||||
if(!instance->fapi->rx_buffer_empty()) {
|
||||
fapi_rx_ulsch_ind_t rx_ind;
|
||||
memset(&rx_ind, 0, sizeof(rx_ind));
|
||||
rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION;
|
||||
rx_ind.sfn_sf = sfn_sf;
|
||||
phy_pdu *buff = 0;
|
||||
int i = 0;
|
||||
std::list<phy_pdu *> free_list;
|
||||
|
||||
do {
|
||||
buff = instance->fapi->pop_rx_buffer();
|
||||
|
||||
if(buff != 0) {
|
||||
if(buff->len == 0) {
|
||||
printf("[FAPI] Buffer length = 0\n");
|
||||
}
|
||||
|
||||
rx_ind.body.pdus[i].rx_ue_info.handle = 0xDEADBEEF;
|
||||
rx_ind.body.pdus[i].rx_ue_info.rnti = 0x4242;
|
||||
rx_ind.body.pdus[i].rel8_pdu.length = buff->len;
|
||||
//rx_ind.pdus[i].rel8_pdu.data_offset;
|
||||
//rx_ind.pdus[i].rel8_pdu.ul_cqi;
|
||||
//rx_ind.pdus[i].rel8_pdu.timing_advance;
|
||||
rx_ind.body.data[i] = buff->buffer;
|
||||
rx_ind.body.number_of_pdus++;
|
||||
i++;
|
||||
instance->fapi->byte_count += buff->len;
|
||||
free_list.push_back(buff);
|
||||
}
|
||||
} while(buff != 0 && i < 8);
|
||||
|
||||
(instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind);
|
||||
|
||||
for(phy_pdu *pdu : free_list) {
|
||||
instance->fapi->release_phy_pdu(pdu);
|
||||
//free(tx_req.tx_request_body.tx_pdu_list[j].segments[0].segment_data);
|
||||
}
|
||||
} else {
|
||||
fapi_rx_ulsch_ind_t rx_ind;
|
||||
memset(&rx_ind, 0, sizeof(rx_ind));
|
||||
rx_ind.header.message_id = FAPI_RX_ULSCH_INDICATION;
|
||||
rx_ind.sfn_sf = sfn_sf;
|
||||
(instance->callbacks.fapi_rx_ulsch_ind)(&(instance->_public), &rx_ind);
|
||||
}
|
||||
|
||||
fapi_rx_cqi_ind_t cqi_ind;
|
||||
cqi_ind.sfn_sf = sfn_sf;
|
||||
(instance->callbacks.fapi_rx_cqi_ind)(&(instance->_public), &cqi_ind);
|
||||
fapi_rx_sr_ind_t sr_ind;
|
||||
sr_ind.sfn_sf = sfn_sf;
|
||||
(instance->callbacks.fapi_rx_sr_ind)(&(instance->_public), &sr_ind);
|
||||
fapi_rach_ind_t rach_ind;
|
||||
rach_ind.sfn_sf = sfn_sf;
|
||||
(instance->callbacks.fapi_rach_ind)(&(instance->_public), &rach_ind);
|
||||
fapi_srs_ind_t srs_ind;
|
||||
srs_ind.sfn_sf = sfn_sf;
|
||||
(instance->callbacks.fapi_srs_ind)(&(instance->_public), &srs_ind);
|
||||
/*
|
||||
nfapi_lbt_dl_indication_t lbt_ind;
|
||||
memset(&lbt_ind, 0, sizeof(lbt_ind));
|
||||
lbt_ind.header.message_id = NFAPI_LBT_DL_INDICATION;
|
||||
lbt_ind.header.phy_id = config->phy_id;
|
||||
lbt_ind.sfn_sf = sfn_sf;
|
||||
nfapi_pnf_p7_lbt_dl_ind(config, &lbt_ind);
|
||||
|
||||
vendor_ext_p7_ind ve_p7_ind;
|
||||
memset(&ve_p7_ind, 0, sizeof(ve_p7_ind));
|
||||
ve_p7_ind.header.message_id = P7_VENDOR_EXT_IND;
|
||||
ve_p7_ind.header.phy_id = config->phy_id;
|
||||
ve_p7_ind.error_code = NFAPI_MSG_OK;
|
||||
nfapi_pnf_p7_vendor_extension(config, &(ve_p7_ind.header));
|
||||
*/
|
||||
fapi_nb_harq_ind_t nb_harq_ind;
|
||||
nb_harq_ind.sfn_sf = sfn_sf;
|
||||
(instance->callbacks.fapi_nb_harq_ind)(&(instance->_public), &nb_harq_ind);
|
||||
fapi_nrach_ind_t nrach_ind;
|
||||
nrach_ind.sfn_sf = sfn_sf;
|
||||
(instance->callbacks.fapi_nrach_ind)(&(instance->_public), &nrach_ind);
|
||||
}
|
||||
|
||||
void *fapi_thread_start(void *ptr) {
|
||||
set_thread_priority(81);
|
||||
fapi_internal_t *instance = (fapi_internal_t *)ptr;
|
||||
uint16_t sfn_sf_dec = 0;
|
||||
uint32_t last_tv_usec = 0;
|
||||
uint32_t last_tv_sec = 0;
|
||||
uint32_t millisec;
|
||||
uint32_t last_millisec = -1;
|
||||
uint16_t catchup = 0;
|
||||
|
||||
while(1) {
|
||||
// get the time
|
||||
struct timeval sf_start;
|
||||
(void)gettimeofday(&sf_start, NULL);
|
||||
uint16_t sfn_sf = ((((sfn_sf_dec) / 10) << 4) | (((sfn_sf_dec) - (((sfn_sf_dec) / 10) * 10)) & 0xF));
|
||||
// increment the sfn/sf - for the next subframe
|
||||
sfn_sf_dec++;
|
||||
|
||||
if(sfn_sf_dec > 10239)
|
||||
sfn_sf_dec = 0;
|
||||
|
||||
fapi_subframe_ind_t ind;
|
||||
ind.sfn_sf = sfn_sf;
|
||||
|
||||
if(instance->fapi->first_dl_config)
|
||||
send_uplink_indications(instance, sfn_sf);
|
||||
|
||||
if(instance->tick == 1000) {
|
||||
if(instance->tx_byte_count > 0) {
|
||||
printf("[FAPI] Tx rate %u bytes/sec\n", instance->tx_byte_count);
|
||||
instance->tx_byte_count = 0;
|
||||
}
|
||||
|
||||
instance->tick = 0;
|
||||
}
|
||||
|
||||
instance->tick++;
|
||||
(instance->callbacks.fapi_subframe_ind)(&(instance->_public), &ind);
|
||||
{
|
||||
phy_pdu *pdu = instance->fapi->allocate_phy_pdu();
|
||||
int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, MSG_DONTWAIT, 0, 0);
|
||||
|
||||
if(len > 0) {
|
||||
pdu->len = len;
|
||||
instance->fapi->push_rx_buffer(pdu);
|
||||
} else {
|
||||
instance->fapi->release_phy_pdu(pdu);
|
||||
}
|
||||
}
|
||||
|
||||
if(catchup) {
|
||||
catchup--;
|
||||
} else {
|
||||
struct timespec now_ts;
|
||||
struct timespec sleep_ts;
|
||||
struct timespec sleep_rem_ts;
|
||||
// get the current time
|
||||
clock_gettime(CLOCK_MONOTONIC, &now_ts);
|
||||
// determine how long to sleep before the start of the next 1ms
|
||||
sleep_ts.tv_sec = 0;
|
||||
sleep_ts.tv_nsec = 1e6 - (now_ts.tv_nsec % 1000000);
|
||||
int nanosleep_result = nanosleep(&sleep_ts, &sleep_rem_ts);
|
||||
|
||||
if(nanosleep_result != 0)
|
||||
printf("*** nanosleep failed or was interrupted\n");
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now_ts);
|
||||
millisec = now_ts.tv_nsec / 1e6;
|
||||
|
||||
if(last_millisec != -1 && ((last_millisec + 1 ) % 1000) != millisec) {
|
||||
printf("*** missing millisec %u %u\n", last_millisec, millisec);
|
||||
catchup = millisec - last_millisec - 1;
|
||||
}
|
||||
|
||||
last_millisec = millisec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
fapi_t *fapi_create(fapi_cb_t *callbacks, fapi_config_t *config) {
|
||||
fapi_internal_t *instance = (fapi_internal *)calloc(1, sizeof(fapi_internal_t));
|
||||
instance->callbacks = *callbacks;
|
||||
instance->config = *config;
|
||||
instance->state = 0;
|
||||
instance->fapi = new fapi_private();
|
||||
return (fapi_t *)instance;
|
||||
}
|
||||
|
||||
void fapi_destroy(fapi_t *fapi) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
delete instance->fapi;
|
||||
free(instance);
|
||||
}
|
||||
|
||||
void *fapi_rx_thread_start(void *ptr) {
|
||||
set_thread_priority(60);
|
||||
fapi_internal_t *instance = (fapi_internal_t *)ptr;
|
||||
|
||||
while(1) {
|
||||
phy_pdu *pdu = instance->fapi->allocate_phy_pdu();
|
||||
int len = recvfrom(instance->rx_sock, pdu->buffer, pdu->buffer_len, 0, 0, 0);
|
||||
|
||||
if(len > 0) {
|
||||
pdu->len = len;
|
||||
instance->fapi->push_rx_buffer(pdu);
|
||||
} else {
|
||||
instance->fapi->release_phy_pdu(pdu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fapi_start_data(fapi_t *fapi, unsigned rx_port, const char *tx_address, unsigned tx_port) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
printf("[FAPI] Rx Data from %u\n", rx_port);
|
||||
printf("[FAPI] Tx Data to %s:%u\n", tx_address, tx_port);
|
||||
instance->rx_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
|
||||
if(instance->rx_sock < 0) {
|
||||
printf("[FAPI] Failed to create socket\n");
|
||||
return;
|
||||
}
|
||||
|
||||
struct sockaddr_in addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
|
||||
addr.sin_port = htons(rx_port);
|
||||
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
int bind_result = bind(instance->rx_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||
|
||||
if(bind_result == -1) {
|
||||
printf("[FAPI] Failed to bind to port %u\n", rx_port);
|
||||
close(instance->rx_sock);
|
||||
return ;
|
||||
}
|
||||
|
||||
instance->tx_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
instance->tx_addr.sin_family = AF_INET;
|
||||
instance->tx_addr.sin_port = htons(tx_port);
|
||||
instance->tx_addr.sin_addr.s_addr = inet_addr(tx_address);
|
||||
}
|
||||
|
||||
|
||||
void fill_tlv(fapi_tlv_t tlvs[], uint8_t count, uint8_t tag, uint8_t len, uint16_t value) {
|
||||
tlvs[count].tag = tag;
|
||||
tlvs[count].value = value;
|
||||
tlvs[count].length = len;
|
||||
}
|
||||
|
||||
int fapi_param_request(fapi_t *fapi, fapi_param_req_t *req) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
fapi_param_resp_t resp;
|
||||
resp.header.message_id = FAPI_PARAM_RESPONSE;
|
||||
resp.error_code = FAPI_MSG_OK;
|
||||
resp.number_of_tlvs = 0;
|
||||
fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_STATE_TAG, 2, instance->state);
|
||||
|
||||
if(instance->state == 0) {
|
||||
if(instance->config.duplex_mode == 0) {
|
||||
// -- TDD
|
||||
// Downlink Bandwidth Support
|
||||
// Uplink Bandwidth Support
|
||||
// Downlink Modulation Support
|
||||
// Uplink Modulation Support
|
||||
// PHY Antenna Capability
|
||||
// Release Capability
|
||||
// MBSFN Capability
|
||||
} else if(instance->config.duplex_mode == 1) {
|
||||
// -- FDD
|
||||
// Downlink Bandwidth Support
|
||||
fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_DL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.dl_channel_bw_support);
|
||||
// Uplink Bandwidth Support
|
||||
fill_tlv(resp.tlvs, resp.number_of_tlvs++, FAPI_PHY_CAPABILITIES_UL_BANDWIDTH_SUPPORT_TAG, 2, instance->config.ul_channel_bw_support);
|
||||
// Downlink Modulation Support
|
||||
// Uplink Modulation Support
|
||||
// PHY Antenna Capability
|
||||
// Release Capability
|
||||
// MBSFN Capability
|
||||
// LAA Capability
|
||||
}
|
||||
} else {
|
||||
if(instance->config.duplex_mode == 0) {
|
||||
// -- TDD
|
||||
// Downlink Bandwidth Support
|
||||
// Uplink Bandwidth Support
|
||||
// Downlink Modulation Support
|
||||
// Uplink Modulation Support
|
||||
// PHY Antenna Capability
|
||||
// Release Capability
|
||||
// MBSFN Capability
|
||||
// Duplexing Mode
|
||||
// PCFICH Power Offset
|
||||
// P-B
|
||||
// DL Cyclic Prefix Type
|
||||
// UL Cyclic Prefix Type
|
||||
// RF Config
|
||||
// PHICH Config
|
||||
// SCH Config
|
||||
// PRACH Config
|
||||
// PUSCH Config
|
||||
// PUCCH Config
|
||||
// SRS Config
|
||||
// Uplink Reference Signal Config
|
||||
// TDD Frame Structure Config
|
||||
// Data Report Mode
|
||||
} else if(instance->config.duplex_mode == 1) {
|
||||
// FDD
|
||||
// Downlink Bandwidth Support
|
||||
// Uplink Bandwidth Support
|
||||
// Downlink Modulation Support
|
||||
// Uplink Modulation Support
|
||||
// PHY Antenna Capability
|
||||
// Release Capability
|
||||
// MBSFN Capability
|
||||
// LAA Capability
|
||||
// Duplexing Mode
|
||||
// PCFICH Power Offset
|
||||
// P-B
|
||||
// DL Cyclic Prefix Type
|
||||
// UL Cyclic Prefix Type
|
||||
// RF Config
|
||||
// PHICH Config
|
||||
// SCH Config
|
||||
// PRACH Config
|
||||
// PUSCH Config
|
||||
// PUCCH Config
|
||||
// SRS Config
|
||||
// Uplink Reference Signal Config
|
||||
// Data Report Mode
|
||||
}
|
||||
}
|
||||
|
||||
//todo fill
|
||||
(instance->callbacks.fapi_param_response)(fapi, &resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fapi_config_request(fapi_t *fapi, fapi_config_req_t *req) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
fapi_config_resp_t resp;
|
||||
resp.header.message_id = FAPI_CONFIG_RESPONSE;
|
||||
resp.error_code = FAPI_MSG_OK;
|
||||
(instance->callbacks.fapi_config_response)(fapi, &resp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fapi_start_request(fapi_t *fapi, fapi_start_req_t *req) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
pthread_t fapi_thread;
|
||||
pthread_create(&fapi_thread, NULL, &fapi_thread_start, instance);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fapi_dl_config_request(fapi_t *fapi, fapi_dl_config_req_t *req) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
instance->fapi->first_dl_config = true;
|
||||
return 0;
|
||||
}
|
||||
int fapi_ul_config_request(fapi_t *fapi, fapi_ul_config_req_t *req) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
return 0;
|
||||
}
|
||||
int fapi_hi_dci0_request(fapi_t *fapi, fapi_hi_dci0_req_t *req) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
return 0;
|
||||
}
|
||||
int fapi_tx_request(fapi_t *fapi, fapi_tx_req_t *req) {
|
||||
fapi_internal_t *instance = (fapi_internal_t *)fapi;
|
||||
|
||||
for(int i = 0; i < req->body.number_of_pdus; ++i) {
|
||||
uint16_t len = req->body.pdus[i].pdu_length;
|
||||
uint32_t *data = req->body.pdus[i].tlvs[0].value;
|
||||
//printf("[FAPI] sfnsf:%d len:%d\n", req->sfn_sf,len);
|
||||
//
|
||||
instance->tx_byte_count += len;
|
||||
int sendto_result = sendto(instance->tx_sock, data, len, 0, (struct sockaddr *)&(instance->tx_addr), sizeof(instance->tx_addr));
|
||||
|
||||
if(sendto_result == -1) {
|
||||
// error
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
2282
l2-fapi-proxy/open-nFAPI/pnf_sim/src/main.cpp
Normal file
2282
l2-fapi-proxy/open-nFAPI/pnf_sim/src/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
31
l2-fapi-proxy/open-nFAPI/sim_common/Makefile.am
Normal file
31
l2-fapi-proxy/open-nFAPI/sim_common/Makefile.am
Normal file
@@ -0,0 +1,31 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
|
||||
AM_CFLAGS = -I$(top_srcdir)/sim_common/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/public_inc -g -Wall -Werror
|
||||
|
||||
AM_CXXFLAGS = -I$(top_srcdir)/sim_common/public_inc -I$(top_srcdir)/common/public_inc -std=c++11 -I$(top_srcdir)/nfapi/public_inc $(BOOST_CPPFLAGS) -g -Wall -Werror
|
||||
noinst_LIBRARIES =libnfapi_sim_common.a
|
||||
#libnfapi_sim_common_a_SOURCES = src/xml_property_tree.cpp src/pool.cpp
|
||||
libnfapi_sim_common_a_SOURCES = src/pool.cpp
|
||||
|
||||
libnfapi_sim_common_a_CFLAGS =$(AM_CFLAGS)
|
||||
libnfapi_sim_common_a_CXXFLAGS =$(AM_CXXFLAGS)
|
||||
|
||||
lib_LTLIBRARIES =libnfapi_sim_common.la
|
||||
#libnfapi_sim_common_la_SOURCES = src/xml_property_tree.cpp
|
||||
libnfapi_sim_common_la_SOURCES = src/pool.cpp
|
||||
186
l2-fapi-proxy/open-nFAPI/sim_common/inc/pool.h
Normal file
186
l2-fapi-proxy/open-nFAPI/sim_common/inc/pool.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _POOL_H_
|
||||
#define _POOL_H_
|
||||
|
||||
#include <mutex>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
class pool_config
|
||||
{
|
||||
public:
|
||||
|
||||
size_t size;
|
||||
uint16_t initial_count;
|
||||
};
|
||||
|
||||
class memory_pool
|
||||
{
|
||||
std::mutex mutex;
|
||||
std::map<size_t, std::queue<uint8_t*>> free_store;
|
||||
std::map<size_t, uint16_t> allocated_store;
|
||||
|
||||
void init(std::vector<pool_config> config)
|
||||
{
|
||||
printf("memory_pool::init\n");
|
||||
|
||||
for(pool_config c : config)
|
||||
{
|
||||
// todo : use the initial count to allocate initial pool memory
|
||||
free_store.insert(std::pair<size_t,
|
||||
std::queue<uint8_t*>>
|
||||
(c.size, std::queue<uint8_t*>()));
|
||||
allocated_store.insert(std::pair<size_t, uint16_t>(c.size, 0));
|
||||
}
|
||||
}
|
||||
|
||||
memory_pool()
|
||||
{
|
||||
std::vector<pool_config> config
|
||||
{
|
||||
{8, 0}, {32, 0}, {64, 0}, {128, 0}, {256, 0},
|
||||
{1024, 0}, {4096, 0}, {8912, 0}
|
||||
|
||||
};
|
||||
|
||||
init(config);
|
||||
}
|
||||
|
||||
|
||||
uint16_t determine_pool_size(size_t size)
|
||||
{
|
||||
for(auto pool : free_store)
|
||||
{
|
||||
if(pool.first >= size)
|
||||
return pool.first;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* alloc(size_t size)
|
||||
{
|
||||
if(size == 0)
|
||||
return 0;
|
||||
|
||||
uint8_t* ptr = 0;
|
||||
size_t psize = determine_pool_size(size + 4);
|
||||
|
||||
if(psize == 0)
|
||||
{
|
||||
ptr = (uint8_t*)malloc(size + 4);
|
||||
memset(ptr, 0, size + 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
mutex.lock();
|
||||
|
||||
auto it = free_store.find(psize);
|
||||
|
||||
if(it == free_store.end())
|
||||
{
|
||||
// Unknown pool size
|
||||
ptr = (uint8_t*)malloc(psize + 4);
|
||||
memcpy(ptr, &psize, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(it->second.size() > 0)
|
||||
{
|
||||
// Take from the pool
|
||||
ptr = (uint8_t*)(it->second.front());
|
||||
it->second.pop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// No memory left in pool
|
||||
ptr = (uint8_t*)malloc(psize + 4);
|
||||
memcpy(ptr, &psize, 4);
|
||||
}
|
||||
}
|
||||
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
return (ptr + 4);
|
||||
}
|
||||
|
||||
void dealloc(uint8_t* ptr)
|
||||
{
|
||||
if(ptr == 0)
|
||||
return;
|
||||
|
||||
uint8_t* _ptr = (uint8_t*)ptr;
|
||||
|
||||
size_t psize;
|
||||
memcpy(&psize, _ptr - 4, 4);
|
||||
|
||||
if(psize == 0)
|
||||
{
|
||||
free(_ptr - 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
mutex.lock();
|
||||
|
||||
auto it = free_store.find(psize);
|
||||
if(it == free_store.end())
|
||||
{
|
||||
free(_ptr - 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert((_ptr - 4) != 0);
|
||||
it->second.push(_ptr - 4);
|
||||
}
|
||||
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
memory_pool(memory_pool const&) = delete;
|
||||
void operator=(memory_pool const&) = delete;
|
||||
|
||||
/*! Get the memory_pool instance */
|
||||
static memory_pool& instance()
|
||||
{
|
||||
static memory_pool instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
/*! Allocate a buffer from the memory_pool is at least size */
|
||||
static uint8_t* allocate(size_t size)
|
||||
{
|
||||
return instance().alloc(size);
|
||||
}
|
||||
|
||||
/*! Return the buffer to the memory_pool */
|
||||
static void deallocate(uint8_t* ptr)
|
||||
{
|
||||
return instance().dealloc(ptr);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // _POOL_H_
|
||||
71
l2-fapi-proxy/open-nFAPI/sim_common/inc/vendor_ext.h
Normal file
71
l2-fapi-proxy/open-nFAPI/sim_common/inc/vendor_ext.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _VENDOR_EXT_H_
|
||||
#define _VENDOR_EXT_H_
|
||||
|
||||
#include "nfapi_interface.h"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
P5_VENDOR_EXT_REQ = NFAPI_VENDOR_EXT_MSG_MIN,
|
||||
P5_VENDOR_EXT_RSP,
|
||||
|
||||
P7_VENDOR_EXT_REQ,
|
||||
P7_VENDOR_EXT_IND
|
||||
|
||||
} vendor_ext_message_id_e;
|
||||
|
||||
typedef struct {
|
||||
nfapi_p4_p5_message_header_t header;
|
||||
uint16_t dummy1;
|
||||
uint16_t dummy2;
|
||||
} vendor_ext_p5_req;
|
||||
|
||||
typedef struct {
|
||||
nfapi_p4_p5_message_header_t header;
|
||||
uint16_t error_code;
|
||||
} vendor_ext_p5_rsp;
|
||||
|
||||
typedef struct {
|
||||
nfapi_p7_message_header_t header;
|
||||
uint16_t dummy1;
|
||||
uint16_t dummy2;
|
||||
} vendor_ext_p7_req;
|
||||
|
||||
typedef struct {
|
||||
nfapi_p7_message_header_t header;
|
||||
uint16_t error_code;
|
||||
} vendor_ext_p7_ind;
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
uint32_t dummy;
|
||||
} vendor_ext_tlv_1;
|
||||
|
||||
#define VENDOR_EXT_TLV_1_TAG 0xF001
|
||||
|
||||
typedef struct {
|
||||
nfapi_tl_t tl;
|
||||
uint32_t dummy;
|
||||
} vendor_ext_tlv_2;
|
||||
|
||||
#define VENDOR_EXT_TLV_2_TAG 0xF002
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _VENDOR_EXT_
|
||||
15
l2-fapi-proxy/open-nFAPI/sim_common/src/pool.cpp
Normal file
15
l2-fapi-proxy/open-nFAPI/sim_common/src/pool.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
294
l2-fapi-proxy/open-nFAPI/utils/nfapi_hex_parser.c
Normal file
294
l2-fapi-proxy/open-nFAPI/utils/nfapi_hex_parser.c
Normal file
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "nr_fapi.h"
|
||||
#include "nr_fapi_p5.h"
|
||||
#include "nr_fapi_p5_utils.h"
|
||||
#include "nr_fapi_p7.h"
|
||||
#include "nr_fapi_p7_utils.h"
|
||||
#define MAX_BUFFER_SIZE (1024 * 1024 * 2)
|
||||
|
||||
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||
{
|
||||
if (s != NULL) {
|
||||
printf("%s:%d %s() Exiting OAI (n)FAPI Hex Parser: %s\n", file, line, function, s);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
char *message_id_to_str(uint32_t message_id)
|
||||
{
|
||||
switch (message_id) {
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_START_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION";
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION:
|
||||
return "NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION";
|
||||
default:
|
||||
return "UNKNOWN PHY MSG TYPE";
|
||||
}
|
||||
}
|
||||
|
||||
void unpack_and_dump_message(void *buf, fapi_message_header_t hdr)
|
||||
{
|
||||
void *unpacked_req = calloc(1,MAX_BUFFER_SIZE);
|
||||
AssertFatal(unpacked_req != NULL, "malloc failed");
|
||||
if (hdr.message_id >= NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST && hdr.message_id <= NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION) {
|
||||
const int ret = fapi_nr_p5_message_unpack(buf, hdr.message_length + NFAPI_HEADER_LENGTH, unpacked_req, MAX_BUFFER_SIZE, 0);
|
||||
DevAssert(ret >= 0);
|
||||
} else if (hdr.message_id >= NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST && hdr.message_id <= NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION) {
|
||||
const int ret = fapi_nr_p7_message_unpack(buf, hdr.message_length + NFAPI_HEADER_LENGTH, unpacked_req, MAX_BUFFER_SIZE, 0);
|
||||
DevAssert(ret >= 0);
|
||||
}
|
||||
|
||||
switch (hdr.message_id) {
|
||||
/* P5 messages */
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_REQUEST: {
|
||||
dump_param_request(unpacked_req);
|
||||
free_param_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_PARAM_RESPONSE: {
|
||||
dump_param_response(unpacked_req);
|
||||
free_param_response(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_REQUEST: {
|
||||
dump_config_request(unpacked_req);
|
||||
free_config_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CONFIG_RESPONSE: {
|
||||
dump_config_response(unpacked_req);
|
||||
free_config_response(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_REQUEST: {
|
||||
dump_start_request(unpacked_req);
|
||||
free_start_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_START_RESPONSE: {
|
||||
dump_start_response(unpacked_req);
|
||||
free_start_response(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_REQUEST: {
|
||||
dump_stop_request(unpacked_req);
|
||||
free_stop_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_STOP_INDICATION: {
|
||||
dump_stop_indication(unpacked_req);
|
||||
free_stop_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_ERROR_INDICATION: {
|
||||
dump_error_indication(unpacked_req);
|
||||
free_error_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
/* P7 messages */
|
||||
case NFAPI_NR_PHY_MSG_TYPE_DL_TTI_REQUEST: {
|
||||
dump_dl_tti_request(unpacked_req);
|
||||
free_dl_tti_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_TTI_REQUEST: {
|
||||
dump_ul_tti_request(unpacked_req);
|
||||
free_ul_tti_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SLOT_INDICATION: {
|
||||
dump_slot_indication(unpacked_req);
|
||||
free_slot_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UL_DCI_REQUEST: {
|
||||
dump_ul_dci_request(unpacked_req);
|
||||
free_ul_dci_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_TX_DATA_REQUEST: {
|
||||
dump_tx_data_request(unpacked_req);
|
||||
free_tx_data_request(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RX_DATA_INDICATION: {
|
||||
dump_rx_data_indication(unpacked_req);
|
||||
free_rx_data_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_CRC_INDICATION: {
|
||||
dump_crc_indication(unpacked_req);
|
||||
free_crc_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_UCI_INDICATION: {
|
||||
dump_uci_indication(unpacked_req);
|
||||
free_crc_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_SRS_INDICATION: {
|
||||
dump_srs_indication(unpacked_req);
|
||||
free_srs_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
case NFAPI_NR_PHY_MSG_TYPE_RACH_INDICATION: {
|
||||
dump_rach_indication(unpacked_req);
|
||||
free_rach_indication(unpacked_req);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
printf("Unknown Msg ID 0x%02x\n", hdr.message_id);
|
||||
}
|
||||
free(unpacked_req);
|
||||
}
|
||||
|
||||
static uint8_t to_hex(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
printf("found invalid char %c\n", c);
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/* @brief decodes one byte in text representation (0xab or just ab) of s and places it in b
|
||||
* @return the number of bytes read, or -1 on error */
|
||||
static int parse_byte(const char *s, uint8_t *b)
|
||||
{
|
||||
if (!s)
|
||||
return -1;
|
||||
int c = 0;
|
||||
// skip any whitespaces
|
||||
while (s[0] && isspace(*s)) {
|
||||
c++;
|
||||
s++;
|
||||
}
|
||||
// end of string -> nothing to be read
|
||||
if (s[0] == 0)
|
||||
return -1;
|
||||
// jump over leading "0x"
|
||||
if (s[0] == '0' && s[1] == 'x') {
|
||||
c += 2;
|
||||
s += 2;
|
||||
}
|
||||
// only one digit, if s[1] has other garbage, it will be caught after
|
||||
if (s[1] == 0 || s[1] == ' ') {
|
||||
// only one digit
|
||||
*b = to_hex(s[0]);
|
||||
// check if valid
|
||||
return *b != 0xff ? c + 1 : -1;
|
||||
}
|
||||
// read both bytes, check if valid
|
||||
uint8_t hb = to_hex(s[0]);
|
||||
uint8_t lb = to_hex(s[1]);
|
||||
if (hb == 0xff || lb == 0xff)
|
||||
return -1;
|
||||
*b = ((hb & 0xf) << 4) | (lb & 0xf);
|
||||
return c + 2;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Check if there are enough arguments
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s [0xNN 0xNN ... | NN NN ... ]\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t hex_values[MAX_BUFFER_SIZE]; // Array to hold the parsed values, assuming max 1024 values
|
||||
int byte_count = 0;
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
const char *l = argv[i];
|
||||
int ret;
|
||||
do {
|
||||
ret = parse_byte(l, &hex_values[byte_count]);
|
||||
if (ret > 0)
|
||||
byte_count++;
|
||||
l += ret;
|
||||
} while (ret > 0 && byte_count < MAX_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
// Print the converted values
|
||||
printf("Parsed %d bytes:\n", byte_count);
|
||||
for (int i = 0; i < byte_count; i++) {
|
||||
if (i % 16 == 0 && i != 0) {
|
||||
printf("\n"); // Start a new line every 16 bytes
|
||||
} else if (i % 8 == 0 && i % 16 != 0) {
|
||||
printf(" "); // Add extra space between 8-byte sections
|
||||
}
|
||||
printf("%02x ", hex_values[i]);
|
||||
}
|
||||
printf("\n");
|
||||
AssertFatal(byte_count >= sizeof(fapi_message_header_t), "Read byte amount not enough to encode the header. Should have a minimum of %lu bytes, aborting...", sizeof(fapi_message_header_t));
|
||||
uint8_t *ptr = hex_values; // Points to the first element of the array
|
||||
uint8_t **msg_ptr = &ptr; // Pointer to the pointer
|
||||
|
||||
fapi_message_header_t hdr = {.num_msg = 0, .opaque_handle = 0, .message_id = 0, .message_length = 0};
|
||||
fapi_nr_message_header_unpack(msg_ptr, NFAPI_HEADER_LENGTH, &hdr, sizeof(fapi_message_header_t), 0);
|
||||
|
||||
printf("Decoded message %s message length 0x%02x\n", message_id_to_str(hdr.message_id), hdr.message_length);
|
||||
// Unpack the message
|
||||
unpack_and_dump_message((uint8_t *)hex_values, hdr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
43
l2-fapi-proxy/open-nFAPI/vnf/Makefile.am
Normal file
43
l2-fapi-proxy/open-nFAPI/vnf/Makefile.am
Normal file
@@ -0,0 +1,43 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/vnf/inc\
|
||||
-I$(top_srcdir)/vnf/public_inc\
|
||||
-I$(top_srcdir)/nfapi/public_inc\
|
||||
-I$(top_srcdir)/common/public_inc\
|
||||
-Wall -Werror -g
|
||||
|
||||
|
||||
noinst_LIBRARIES = libnfapi_vnf.a
|
||||
|
||||
libnfapi_vnf_a_SOURCES = src/vnf.c\
|
||||
src/vnf_p7.c\
|
||||
src/vnf_interface.c\
|
||||
src/vnf_p7_interface.c
|
||||
|
||||
LDADD = -lsctp ../common/bin/libnfapi_common.a
|
||||
|
||||
libnfapi_vnf_a_CFLAGS =$(AM_CFLAGS)
|
||||
|
||||
lib_LTLIBRARIES = libnfapi_vnf.la
|
||||
|
||||
libnfapi_vnf_la_SOURCES = src/vnf.c\
|
||||
src/vnf_p7.c\
|
||||
src/vnf_interface.c\
|
||||
src/vnf_p7_interface.c
|
||||
50
l2-fapi-proxy/open-nFAPI/vnf/inc/vnf.h
Normal file
50
l2-fapi-proxy/open-nFAPI/vnf/inc/vnf.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _VNF_H_
|
||||
#define _VNF_H_
|
||||
|
||||
#include "nfapi_vnf_interface.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
nfapi_vnf_config_t _public;
|
||||
|
||||
uint8_t terminate;
|
||||
uint8_t sctp;
|
||||
|
||||
uint8_t tx_message_buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
|
||||
uint16_t next_phy_id;
|
||||
|
||||
} vnf_t;
|
||||
|
||||
|
||||
int vnf_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
|
||||
int vnf_nr_pack_and_send_p5_message(vnf_t* vnf, uint16_t p5_idx, nfapi_nr_p4_p5_message_header_t* msg, uint16_t msg_len);
|
||||
|
||||
int vnf_pack_and_send_p4_message(vnf_t* vnf, uint16_t p5_idx, nfapi_p4_p5_message_header_t* msg, uint16_t msg_len);
|
||||
|
||||
int vnf_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
|
||||
int vnf_nr_read_dispatch_message(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* pnf);
|
||||
|
||||
|
||||
void nfapi_vnf_phy_info_list_add(nfapi_vnf_config_t* config, nfapi_vnf_phy_info_t* info);
|
||||
nfapi_vnf_phy_info_t* nfapi_vnf_phy_info_list_find(nfapi_vnf_config_t* config, uint16_t phy_id);
|
||||
void nfapi_vnf_pnf_list_add(nfapi_vnf_config_t* config, nfapi_vnf_pnf_info_t* node);
|
||||
nfapi_vnf_pnf_info_t* nfapi_vnf_pnf_list_find(nfapi_vnf_config_t* config, int p5_idx);
|
||||
#endif // _VNF_H_
|
||||
148
l2-fapi-proxy/open-nFAPI/vnf/inc/vnf_p7.h
Normal file
148
l2-fapi-proxy/open-nFAPI/vnf/inc/vnf_p7.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _VNF_P7_H_
|
||||
#define _VNF_P7_H_
|
||||
|
||||
#include "nfapi_vnf_interface.h"
|
||||
|
||||
#define TIMEHR_SEC(_time_hr) ((uint32_t)(_time_hr) >> 20)
|
||||
#define TIMEHR_USEC(_time_hr) ((uint32_t)(_time_hr) & 0xFFFFF)
|
||||
#define TIME2TIMEHR(_time) (((uint32_t)(_time.tv_sec) & 0xFFF) << 20 | ((uint32_t)(_time.tv_usec) & 0xFFFFF))
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t* buffer;
|
||||
uint32_t length;
|
||||
} vnf_p7_rx_message_segment_t;
|
||||
|
||||
typedef struct vnf_p7_rx_message vnf_p7_rx_message_t;
|
||||
|
||||
typedef struct vnf_p7_rx_message {
|
||||
uint8_t sequence_number;
|
||||
uint8_t num_segments_received;
|
||||
uint8_t num_segments_expected;
|
||||
|
||||
// the spec allows of upto 128 segments, this does seem excessive
|
||||
vnf_p7_rx_message_segment_t segments[128];
|
||||
|
||||
uint32_t rx_hr_time;
|
||||
|
||||
vnf_p7_rx_message_t* next;
|
||||
} vnf_p7_rx_message_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
vnf_p7_rx_message_t* msg_queue;
|
||||
|
||||
} vnf_p7_rx_reassembly_queue_t;
|
||||
|
||||
typedef struct nfapi_vnf_p7_connection_info {
|
||||
|
||||
/*! The PHY id */
|
||||
int phy_id;
|
||||
|
||||
|
||||
// this does not belong here...
|
||||
uint8_t stream_id;
|
||||
|
||||
/*! Flag indicating the sync state of the P7 conenction */
|
||||
uint8_t in_sync;
|
||||
|
||||
int dl_out_sync_offset;
|
||||
int dl_out_sync_period; // ms (as a pow2)
|
||||
|
||||
int dl_in_sync_offset;
|
||||
int dl_in_sync_period; // ms (as a pow2)
|
||||
|
||||
uint8_t filtered_adjust;
|
||||
uint16_t min_sync_cycle_count;
|
||||
uint32_t latency[8];
|
||||
uint32_t average_latency;
|
||||
int32_t sf_offset_filtered;
|
||||
int32_t sf_offset_trend;
|
||||
int32_t sf_offset;
|
||||
int32_t slot_offset;
|
||||
int32_t slot_offset_trend;
|
||||
int32_t slot_offset_filtered;
|
||||
uint16_t zero_count;
|
||||
int32_t adjustment;
|
||||
int32_t insync_minor_adjustment;
|
||||
int32_t insync_minor_adjustment_duration;
|
||||
|
||||
uint32_t previous_t1;
|
||||
uint32_t previous_t2;
|
||||
int32_t previous_sf_offset_filtered;
|
||||
int32_t previous_slot_offset_filtered;
|
||||
int sfn_sf;
|
||||
int sfn;
|
||||
int slot;
|
||||
int mu; // some 5G slot calculations need the numerology to know the number
|
||||
// of slots
|
||||
|
||||
int socket;
|
||||
struct sockaddr_in local_addr;
|
||||
struct sockaddr_in remote_addr;
|
||||
|
||||
vnf_p7_rx_reassembly_queue_t reassembly_queue;
|
||||
uint8_t* reassembly_buffer;
|
||||
uint32_t reassembly_buffer_size;
|
||||
|
||||
uint32_t sequence_number;
|
||||
|
||||
struct nfapi_vnf_p7_connection_info* next;
|
||||
|
||||
} nfapi_vnf_p7_connection_info_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
nfapi_vnf_p7_config_t _public;
|
||||
|
||||
// private data
|
||||
uint8_t terminate;
|
||||
nfapi_vnf_p7_connection_info_t* p7_connections;
|
||||
int socket;
|
||||
uint32_t sf_start_time_hr;
|
||||
uint32_t slot_start_time_hr;
|
||||
uint8_t* rx_message_buffer; // would this be better put in the p7 conenction info?
|
||||
uint16_t rx_message_buffer_size;
|
||||
|
||||
} vnf_p7_t;
|
||||
|
||||
uint32_t vnf_get_current_time_hr(void);
|
||||
|
||||
uint16_t increment_sfn_sf(uint16_t sfn_sf);
|
||||
int vnf_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
|
||||
int vnf_nr_sync(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* p7_info);
|
||||
|
||||
int send_mac_subframe_indications(vnf_p7_t* config);
|
||||
int send_mac_slot_indications(vnf_p7_t* config);
|
||||
int vnf_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
|
||||
int vnf_nr_p7_read_dispatch_message(vnf_p7_t* vnf_p7 );
|
||||
|
||||
void vnf_p7_connection_info_list_add(vnf_p7_t* vnf_p7, nfapi_vnf_p7_connection_info_t* node);
|
||||
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_find(vnf_p7_t* vnf_p7, uint16_t phy_id);
|
||||
nfapi_vnf_p7_connection_info_t* vnf_p7_connection_info_list_delete(vnf_p7_t* vnf_p7, uint16_t phy_id);
|
||||
|
||||
int vnf_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
|
||||
int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_t* header);
|
||||
|
||||
void vnf_p7_release_msg(vnf_p7_t* vnf_p7, nfapi_p7_message_header_t* header);
|
||||
void vnf_p7_release_pdu(vnf_p7_t* vnf_p7, void* pdu);
|
||||
|
||||
|
||||
#endif // _VNF_P7_H_
|
||||
1027
l2-fapi-proxy/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
Normal file
1027
l2-fapi-proxy/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h
Normal file
File diff suppressed because it is too large
Load Diff
1628
l2-fapi-proxy/open-nFAPI/vnf/src/vnf.c
Normal file
1628
l2-fapi-proxy/open-nFAPI/vnf/src/vnf.c
Normal file
File diff suppressed because it is too large
Load Diff
1164
l2-fapi-proxy/open-nFAPI/vnf/src/vnf_interface.c
Normal file
1164
l2-fapi-proxy/open-nFAPI/vnf/src/vnf_interface.c
Normal file
File diff suppressed because it is too large
Load Diff
2741
l2-fapi-proxy/open-nFAPI/vnf/src/vnf_p7.c
Normal file
2741
l2-fapi-proxy/open-nFAPI/vnf/src/vnf_p7.c
Normal file
File diff suppressed because it is too large
Load Diff
709
l2-fapi-proxy/open-nFAPI/vnf/src/vnf_p7_interface.c
Normal file
709
l2-fapi-proxy/open-nFAPI/vnf/src/vnf_p7_interface.c
Normal file
@@ -0,0 +1,709 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "vnf_p7.h"
|
||||
#include "nfapi_vnf.h"
|
||||
|
||||
#include "common/ran_context.h"
|
||||
|
||||
#include "openair1/PHY/defs_gNB.h"
|
||||
#define FAPI2_IP_DSCP 0
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
nfapi_vnf_p7_config_t* nfapi_vnf_p7_config_create()
|
||||
{
|
||||
vnf_p7_t* _this = (vnf_p7_t*)calloc(1, sizeof(vnf_p7_t));
|
||||
|
||||
if(_this == 0)
|
||||
return 0;
|
||||
|
||||
// todo : initialize
|
||||
_this->_public.segment_size = 65000; // UDP max packet size is 65535
|
||||
_this->_public.max_num_segments = 8;
|
||||
_this->_public.checksum_enabled = 1;
|
||||
|
||||
_this->_public.malloc = &malloc;
|
||||
_this->_public.free = &free;
|
||||
|
||||
_this->_public.codec_config.allocate = &malloc;
|
||||
_this->_public.codec_config.deallocate = &free;
|
||||
|
||||
|
||||
return (nfapi_vnf_p7_config_t*)_this;
|
||||
}
|
||||
|
||||
void nfapi_vnf_p7_config_destory(nfapi_vnf_p7_config_t* config)
|
||||
{
|
||||
free(config);
|
||||
}
|
||||
|
||||
|
||||
struct timespec timespec_add(struct timespec lhs, struct timespec rhs)
|
||||
{
|
||||
struct timespec result;
|
||||
|
||||
result.tv_sec = lhs.tv_sec + rhs.tv_sec;
|
||||
result.tv_nsec = lhs.tv_nsec + rhs.tv_nsec;
|
||||
|
||||
if(result.tv_nsec > 1e9)
|
||||
{
|
||||
result.tv_sec++;
|
||||
result.tv_nsec-= 1e9;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct timespec timespec_sub(struct timespec lhs, struct timespec rhs)
|
||||
{
|
||||
struct timespec result;
|
||||
if ((lhs.tv_nsec-rhs.tv_nsec)<0)
|
||||
{
|
||||
result.tv_sec = lhs.tv_sec-rhs.tv_sec-1;
|
||||
result.tv_nsec = 1000000000+lhs.tv_nsec-rhs.tv_nsec;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.tv_sec = lhs.tv_sec-rhs.tv_sec;
|
||||
result.tv_nsec = lhs.tv_nsec-rhs.tv_nsec;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// monitor the p7 endpoints and the timing loop and
|
||||
// send indications to mac
|
||||
int nfapi_nr_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
{
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
|
||||
// Create p7 receive udp port
|
||||
// todo : this needs updating for Ipv6
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
|
||||
|
||||
// open the UDP socket
|
||||
if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n");
|
||||
|
||||
// configure the UDP socket options
|
||||
int iptos_value = FAPI2_IP_DSCP << 2;
|
||||
if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n");
|
||||
|
||||
// Create the address structure
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(config->port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
// bind to the configured port
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
|
||||
if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
|
||||
//if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n");
|
||||
|
||||
|
||||
//struct timespec original_pselect_timeout;
|
||||
struct timespec pselect_timeout;
|
||||
pselect_timeout.tv_sec = 100;
|
||||
pselect_timeout.tv_nsec = 0;
|
||||
|
||||
struct timespec ref_time;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ref_time);
|
||||
while(vnf_p7->terminate == 0)
|
||||
{
|
||||
fd_set rfds;
|
||||
int maxSock = 0;
|
||||
FD_ZERO(&rfds);
|
||||
int selectRetval = 0;
|
||||
|
||||
// Add the p7 socket
|
||||
FD_SET(vnf_p7->socket, &rfds);
|
||||
maxSock = vnf_p7->socket;
|
||||
|
||||
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
|
||||
|
||||
if(selectRetval == 0)
|
||||
{
|
||||
// pselect timed out, continue
|
||||
}
|
||||
else if(selectRetval > 0)
|
||||
{
|
||||
// have a p7 message
|
||||
if(FD_ISSET(vnf_p7->socket, &rfds))
|
||||
{
|
||||
vnf_nr_p7_read_dispatch_message(vnf_p7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pselect error
|
||||
if(selectRetval == -1 && errno == EINTR)
|
||||
{
|
||||
// a sigal was received.
|
||||
}
|
||||
else
|
||||
{
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%d.%d orginal:%d.%d last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond);
|
||||
// should we exit now?
|
||||
if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
|
||||
close(vnf_p7->socket);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int nfapi_vnf_p7_start(nfapi_vnf_p7_config_t* config)
|
||||
{
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s()\n", __FUNCTION__);
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
|
||||
// Create p7 receive udp port
|
||||
// todo : this needs updating for Ipv6
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Initialising VNF P7 port:%u\n", config->port);
|
||||
|
||||
// open the UDP socket
|
||||
if ((vnf_p7->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After P7 socket errno: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 socket created...\n");
|
||||
|
||||
// configure the UDP socket options
|
||||
int iptos_value = FAPI2_IP_DSCP << 2;
|
||||
if (setsockopt(vnf_p7->socket, IPPROTO_IP, IP_TOS, &iptos_value, sizeof(iptos_value)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After setsockopt (IP_TOS) errno: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 setsockopt succeeded...\n");
|
||||
|
||||
// Create the address structure
|
||||
struct sockaddr_in addr;
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(config->port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
// bind to the configured port
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 binding too %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
|
||||
if (bind(vnf_p7->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
|
||||
//if (sctp_bindx(config->socket, (struct sockaddr *)&addr, sizeof(struct sockaddr_in), 0) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "After bind errno: %d\n", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "VNF P7 bind succeeded...\n");
|
||||
|
||||
|
||||
//struct timespec original_pselect_timeout;
|
||||
struct timespec pselect_timeout;
|
||||
pselect_timeout.tv_sec = 0;
|
||||
pselect_timeout.tv_nsec = 1000000; // ns in a 1 us
|
||||
|
||||
|
||||
struct timespec pselect_start;
|
||||
struct timespec pselect_stop;
|
||||
|
||||
//struct timespec sf_end;
|
||||
|
||||
long last_millisecond = -1;
|
||||
|
||||
|
||||
struct timespec sf_duration;
|
||||
sf_duration.tv_sec = 0;
|
||||
sf_duration.tv_nsec = 1e6; // We want 1ms pause
|
||||
|
||||
struct timespec sf_start;
|
||||
clock_gettime(CLOCK_MONOTONIC, &sf_start);
|
||||
long millisecond = sf_start.tv_nsec / 1e6;
|
||||
sf_start = timespec_add(sf_start, sf_duration);
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %ld.%ld\n", sf_start.tv_sec, sf_start.tv_nsec);
|
||||
|
||||
while(vnf_p7->terminate == 0)
|
||||
{
|
||||
fd_set rfds;
|
||||
int maxSock = 0;
|
||||
FD_ZERO(&rfds);
|
||||
int selectRetval = 0;
|
||||
|
||||
// Add the p7 socket
|
||||
FD_SET(vnf_p7->socket, &rfds);
|
||||
maxSock = vnf_p7->socket;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &pselect_start);
|
||||
//long millisecond = pselect_start.tv_nsec / 1e6;
|
||||
|
||||
if((last_millisecond == -1) || (millisecond == last_millisecond) || (millisecond == (last_millisecond + 1) % 1000) )
|
||||
{
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "pselect_start:%d.%d sf_start:%d.%d\n", pselect_start.tv_sec, pselect_start.tv_nsec, sf_start.tv_sec, sf_start.tv_nsec);
|
||||
|
||||
|
||||
if((pselect_start.tv_sec > sf_start.tv_sec) ||
|
||||
((pselect_start.tv_sec == sf_start.tv_sec) && (pselect_start.tv_nsec > sf_start.tv_nsec)))
|
||||
{
|
||||
// overran the end of the subframe we do not want to wait
|
||||
pselect_timeout.tv_sec = 0;
|
||||
pselect_timeout.tv_nsec = 0;
|
||||
|
||||
//struct timespec overrun = timespec_sub(pselect_start, sf_start);
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "Subframe overrun detected of %d.%d running to catchup\n", overrun.tv_sec, overrun.tv_nsec);
|
||||
}
|
||||
else
|
||||
{
|
||||
// still time before the end of the subframe wait
|
||||
pselect_timeout = timespec_sub(sf_start, pselect_start);
|
||||
|
||||
}
|
||||
|
||||
//original_pselect_timeout = pselect_timeout;
|
||||
|
||||
// detemine how long to sleep in ns before the start of the next 1ms
|
||||
//pselect_timeout.tv_nsec = 1e6 - (pselect_start.tv_nsec % 1000000);
|
||||
|
||||
//uint8_t underrun_possible =0;
|
||||
|
||||
// if we are not sleeping until the next milisecond due to the
|
||||
// insycn minor adjment flag it so we don't consider it an error
|
||||
//uint8_t underrun_possible =0;
|
||||
/*
|
||||
{
|
||||
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
|
||||
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0 && pselect_start.tv_nsec != 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] Subframe minor adjustment %d (%d->%d)\n", phy->insync_minor_adjustment,
|
||||
pselect_timeout.tv_nsec, pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000))
|
||||
if(phy->insync_minor_adjustment > 0)
|
||||
{
|
||||
// todo check we don't go below 0
|
||||
if((phy->insync_minor_adjustment * 1000) > pselect_timeout.tv_nsec)
|
||||
pselect_timeout.tv_nsec = 0;
|
||||
else
|
||||
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
|
||||
|
||||
|
||||
//underrun_possible = 1;
|
||||
}
|
||||
else if(phy->insync_minor_adjustment < 0)
|
||||
{
|
||||
// todo check we don't go below 0
|
||||
pselect_timeout.tv_nsec = pselect_timeout.tv_nsec - (phy->insync_minor_adjustment * 1000);
|
||||
}
|
||||
|
||||
//phy->insync_minor_adjustment = 0;
|
||||
phy->insync_minor_adjustment_duration--;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
//long wraps = pselect_timeout.tv_nsec % 1e9;
|
||||
|
||||
|
||||
selectRetval = pselect(maxSock+1, &rfds, NULL, NULL, &pselect_timeout, NULL);
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &pselect_stop);
|
||||
|
||||
nfapi_vnf_p7_connection_info_t* phy = vnf_p7->p7_connections;
|
||||
|
||||
if (selectRetval==-1 && errno == 22)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "INVAL: pselect_timeout:%ld.%ld adj[dur:%d adj:%d], sf_dur:%ld.%ld\n",
|
||||
pselect_timeout.tv_sec, pselect_timeout.tv_nsec,
|
||||
phy->insync_minor_adjustment_duration, phy->insync_minor_adjustment,
|
||||
sf_duration.tv_sec, sf_duration.tv_nsec);
|
||||
}
|
||||
if(selectRetval == 0)
|
||||
{
|
||||
// calculate the start of the next subframe
|
||||
sf_start = timespec_add(sf_start, sf_duration);
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "next subframe will start at %d.%d\n", sf_start.tv_sec, sf_start.tv_nsec);
|
||||
|
||||
if(phy && phy->in_sync && phy->insync_minor_adjustment != 0 && phy->insync_minor_adjustment_duration > 0)
|
||||
{
|
||||
long insync_minor_adjustment_ns = (phy->insync_minor_adjustment * 1000);
|
||||
|
||||
sf_start.tv_nsec -= insync_minor_adjustment_ns;
|
||||
|
||||
#if 1
|
||||
if (sf_start.tv_nsec > 1e9)
|
||||
{
|
||||
sf_start.tv_sec++;
|
||||
sf_start.tv_nsec-=1e9;
|
||||
}
|
||||
else if (sf_start.tv_nsec < 0)
|
||||
{
|
||||
sf_start.tv_sec--;
|
||||
sf_start.tv_nsec+=1e9;
|
||||
}
|
||||
#else
|
||||
//NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] BEFORE adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%d\n", phy->insync_minor_adjustment, sf_start.tv_nsec);
|
||||
if(phy->insync_minor_adjustment > 0)
|
||||
{
|
||||
// decrease the subframe duration a little
|
||||
if (sf_start.tv_nsec > insync_minor_adjustment_ns)
|
||||
sf_start.tv_nsec -= insync_minor_adjustment_ns;
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] Adjustment would make it negative sf:%d.%ld adjust:%ld\n\n\n", sf_start.tv_sec, sf_start.tv_nsec, insync_minor_adjustment_ns);
|
||||
sf_start.tv_sec--;
|
||||
sf_start.tv_nsec += 1e9 - insync_minor_adjustment_ns;
|
||||
}
|
||||
}
|
||||
else if(phy->insync_minor_adjustment < 0)
|
||||
{
|
||||
// todo check we don't go below 0
|
||||
// increase the subframe duration a little
|
||||
sf_start.tv_nsec += insync_minor_adjustment_ns;
|
||||
|
||||
if (sf_start.tv_nsec < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "[VNF] OVERFLOW %d.%ld\n\n\n\n", sf_start.tv_sec, sf_start.tv_nsec);
|
||||
sf_start.tv_sec++;
|
||||
sf_start.tv_nsec += 1e9;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//phy->insync_minor_adjustment = 0;
|
||||
phy->insync_minor_adjustment_duration--;
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_NOTE, "[VNF] AFTER adjustment - Subframe minor adjustment %dus sf_start.tv_nsec:%ld duration:%u\n",
|
||||
phy->insync_minor_adjustment, sf_start.tv_nsec, phy->insync_minor_adjustment_duration);
|
||||
|
||||
if (phy->insync_minor_adjustment_duration==0)
|
||||
{
|
||||
phy->insync_minor_adjustment = 0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
long pselect_stop_millisecond = pselect_stop.tv_nsec / 1e6;
|
||||
if(millisecond == pselect_stop_millisecond)
|
||||
{
|
||||
// we have woke up in the same subframe
|
||||
if(underrun_possible == 0)
|
||||
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect underrun %ld (%d.%d)\n", millisecond, pselect_stop.tv_sec, pselect_stop.tv_nsec);
|
||||
}
|
||||
else if(((millisecond + 1) % 1000) != pselect_stop_millisecond)
|
||||
{
|
||||
// we have overrun the subframe
|
||||
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe pselect overrun %ld %ld\n", millisecond, pselect_stop_millisecond);
|
||||
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe underrun %ld\n", millisecond);
|
||||
}
|
||||
last_millisecond = millisecond;
|
||||
*/
|
||||
|
||||
millisecond ++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// we have overrun the subframe advance to go and collect $200
|
||||
if((millisecond - last_millisecond) > 3)
|
||||
NFAPI_TRACE(NFAPI_TRACE_WARN, "subframe overrun %ld %ld (%ld)\n", millisecond, last_millisecond, millisecond - last_millisecond + 1);
|
||||
|
||||
last_millisecond = ( last_millisecond + 1 ) % 1000;
|
||||
selectRetval = 0;
|
||||
}
|
||||
|
||||
if(selectRetval == 0)
|
||||
{
|
||||
vnf_p7->sf_start_time_hr = vnf_get_current_time_hr();
|
||||
|
||||
// pselect timed out
|
||||
nfapi_vnf_p7_connection_info_t* curr = vnf_p7->p7_connections;
|
||||
|
||||
while(curr != 0)
|
||||
{
|
||||
curr->sfn_sf = increment_sfn_sf(curr->sfn_sf);
|
||||
vnf_sync(vnf_p7, curr);
|
||||
curr = curr->next;
|
||||
}
|
||||
|
||||
send_mac_subframe_indications(vnf_p7);
|
||||
|
||||
}
|
||||
else if(selectRetval > 0)
|
||||
{
|
||||
// have a p7 message
|
||||
if(FD_ISSET(vnf_p7->socket, &rfds))
|
||||
{
|
||||
vnf_p7_read_dispatch_message(vnf_p7);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// pselect error
|
||||
if(selectRetval == -1 && errno == EINTR)
|
||||
{
|
||||
// a sigal was received.
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "P7 select failed result %d errno %d timeout:%ld.%ld orginal:%ld.%ld last_ms:%ld ms:%ld\n", selectRetval, errno, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, pselect_timeout.tv_sec, pselect_timeout.tv_nsec, last_millisecond, millisecond);
|
||||
// should we exit now?
|
||||
if (selectRetval == -1 && errno == 22) // invalid argument??? not sure about timeout duration
|
||||
{
|
||||
usleep(100000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "Closing p7 socket\n");
|
||||
close(vnf_p7->socket);
|
||||
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s() returning\n", __FUNCTION__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int nfapi_vnf_p7_stop(nfapi_vnf_p7_config_t* config)
|
||||
{
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
vnf_p7->terminate =1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_add_pnf(nfapi_vnf_p7_config_t* config, const char* pnf_p7_addr, int pnf_p7_port, int phy_id, int mu)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p phy_id:%d pnf_addr:%s pnf_p7_port:%d)\n", __FUNCTION__, config, phy_id, pnf_p7_addr, pnf_p7_port);
|
||||
|
||||
if(config == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
|
||||
nfapi_vnf_p7_connection_info_t* node = (nfapi_vnf_p7_connection_info_t*)malloc(sizeof(nfapi_vnf_p7_connection_info_t));
|
||||
|
||||
memset(node, 0, sizeof(nfapi_vnf_p7_connection_info_t));
|
||||
node->phy_id = phy_id;
|
||||
node->in_sync = 0;
|
||||
node->dl_out_sync_offset = 30;//TODO: Values need to be changed for NR,How to set the values
|
||||
node->dl_out_sync_period = 10;
|
||||
node->dl_in_sync_offset = 30;
|
||||
node->dl_in_sync_period = 512;
|
||||
//node->sfn_sf = 0;
|
||||
node->sfn = 0;
|
||||
node->slot = 0;
|
||||
node->min_sync_cycle_count = 8;
|
||||
node->mu = mu;
|
||||
|
||||
// save the remote endpoint information
|
||||
node->remote_addr.sin_family = AF_INET;
|
||||
node->remote_addr.sin_port = pnf_p7_port;//htons(pnf_p7_port);
|
||||
node->remote_addr.sin_addr.s_addr = inet_addr(pnf_p7_addr);
|
||||
|
||||
vnf_p7_connection_info_list_add(vnf_p7, node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_del_pnf(nfapi_vnf_p7_config_t* config, int phy_id)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(phy_id:%d)\n", __FUNCTION__, phy_id);
|
||||
|
||||
if(config == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
|
||||
nfapi_vnf_p7_connection_info_t* to_delete = vnf_p7_connection_info_list_delete(vnf_p7, phy_id);
|
||||
|
||||
if(to_delete)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(phy_id:%d) deleting connection info\n", __FUNCTION__, phy_id);
|
||||
free(to_delete);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int nfapi_vnf_p7_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_dl_config_request_t* req)
|
||||
{
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req);
|
||||
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_nr_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_nr_dl_tti_request_t* req)
|
||||
{
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO, "%s(config:%p req:%p)\n", __FUNCTION__, config, req);
|
||||
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_ul_tti_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_tti_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_ul_config_req(nfapi_vnf_p7_config_t* config, nfapi_ul_config_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
int nfapi_vnf_p7_ul_dci_req(nfapi_vnf_p7_config_t* config, nfapi_nr_ul_dci_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
int nfapi_vnf_p7_hi_dci0_req(nfapi_vnf_p7_config_t* config, nfapi_hi_dci0_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
int nfapi_vnf_p7_tx_data_req(nfapi_vnf_p7_config_t* config, nfapi_nr_tx_data_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_nr_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
int nfapi_vnf_p7_tx_req(nfapi_vnf_p7_config_t* config, nfapi_tx_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
int nfapi_vnf_p7_lbt_dl_config_req(nfapi_vnf_p7_config_t* config, nfapi_lbt_dl_config_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
int nfapi_vnf_p7_vendor_extension(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* header)
|
||||
{
|
||||
if(config == 0 || header == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_p7_pack_and_send_p7_msg(vnf_p7, header);
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_ue_release_req(nfapi_vnf_p7_config_t* config, nfapi_ue_release_request_t* req)
|
||||
{
|
||||
if(config == 0 || req == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
return vnf_p7_pack_and_send_p7_msg(vnf_p7, &req->header);
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_release_msg(nfapi_vnf_p7_config_t* config, nfapi_p7_message_header_t* header)
|
||||
{
|
||||
if(config == 0 || header == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
vnf_p7_release_msg(vnf_p7, header);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int nfapi_vnf_p7_release_pdu(nfapi_vnf_p7_config_t* config, void* pdu)
|
||||
{
|
||||
if(config == 0 || pdu == 0)
|
||||
return -1;
|
||||
|
||||
vnf_p7_t* vnf_p7 = (vnf_p7_t*)config;
|
||||
vnf_p7_release_pdu(vnf_p7, pdu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
30
l2-fapi-proxy/open-nFAPI/vnf/tests/Makefile.am
Normal file
30
l2-fapi-proxy/open-nFAPI/vnf/tests/Makefile.am
Normal file
@@ -0,0 +1,30 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
#vnf unit test
|
||||
#AUTOMAKE_OPTIONS=subdir-objects
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/vnf/public_inc $(CFLAGS_CUNIT) -Wall -Werror
|
||||
|
||||
check_PROGRAMS= test_vnf
|
||||
|
||||
test_vnf_SOURCES = vnf_cunit_main.c ../..//common/src/debug.c
|
||||
test_vnf_LDADD=$(top_builddir)/vnf/libnfapi_vnf.a $(top_builddir)/nfapi/libnfapi.a -L$(libdir) -lpthread -lrt -lsctp -lz -lcunit
|
||||
|
||||
LOG_DRIVER = $(top_srcdir)/tap-driver.sh
|
||||
TESTS=test_vnf
|
||||
EXTRA_DIST = $(TESTS)
|
||||
|
||||
1497
l2-fapi-proxy/open-nFAPI/vnf/tests/vnf_cunit_main.c
Normal file
1497
l2-fapi-proxy/open-nFAPI/vnf/tests/vnf_cunit_main.c
Normal file
File diff suppressed because it is too large
Load Diff
22
l2-fapi-proxy/open-nFAPI/vnf_sim/Makefile.am
Normal file
22
l2-fapi-proxy/open-nFAPI/vnf_sim/Makefile.am
Normal file
@@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright 2017 Cisco Systems, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
AUTOMAKE_OPTIONS=subdir-objects
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/vnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/vnf/inc -I$(top_srcdir)/vnf/public_inc $(XML_CFLAGS) -Wall -Werror -g
|
||||
AM_CXXFLAGS = -I$(top_srcidr)/vnf_sim/inc -I$(top_srcdir)/sim_common/inc -I$(top_srcdir)/common/public_inc -I$(top_srcdir)/nfapi/inc -I$(top_srcdir)/nfapi/public_inc -I$(top_srcdir)/vnf/inc -I$(top_srcdir)/vnf/public_inc $(XML_CFLAGS) -std=c++11 $(BOOST_CPPFLAGS) -g
|
||||
bin_PROGRAMS = vnfsim
|
||||
vnfsim_SOURCES = src/main.cpp src/mac.cpp
|
||||
LDADD= $(top_builddir)/vnf/libnfapi_vnf.a $(top_builddir)/common/libnfapi_common.a $(top_builddir)/nfapi/libnfapi.a $(top_builddir)/sim_common/libnfapi_sim_common.a -L$(libdir) -lpthread -lrt -lsctp -lz
|
||||
60
l2-fapi-proxy/open-nFAPI/vnf_sim/inc/mac.h
Normal file
60
l2-fapi-proxy/open-nFAPI/vnf_sim/inc/mac.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2017 Cisco Systems, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _MAC_H_
|
||||
#define _MAC_H_
|
||||
|
||||
#include "nfapi_interface.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct mac mac_t;
|
||||
|
||||
typedef struct mac
|
||||
{
|
||||
void* user_data;
|
||||
|
||||
void (*dl_config_req)(mac_t* mac, nfapi_dl_config_request_t* req);
|
||||
void (*ul_config_req)(mac_t* mac, nfapi_ul_config_request_t* req);
|
||||
void (*hi_dci0_req)(mac_t* mac, nfapi_hi_dci0_request_t* req);
|
||||
void (*tx_req)(mac_t* mac, nfapi_tx_request_t* req);
|
||||
} mac_t;
|
||||
|
||||
mac_t* mac_create(uint8_t wireshark_test_mode);
|
||||
void mac_destroy(mac_t* mac);
|
||||
|
||||
void mac_start_data(mac_t* mac, unsigned rx_port, const char* tx_addres, unsigned tx_port);
|
||||
|
||||
void mac_subframe_ind(mac_t* mac, uint16_t phy_id, uint16_t sfn_sf);
|
||||
void mac_harq_ind(mac_t* mac, nfapi_harq_indication_t* ind);
|
||||
void mac_crc_ind(mac_t* mac, nfapi_crc_indication_t* ind);
|
||||
void mac_rx_ind(mac_t* mac, nfapi_rx_indication_t* ind);
|
||||
void mac_rach_ind(mac_t* mac, nfapi_rach_indication_t* ind);
|
||||
void mac_srs_ind(mac_t* mac, nfapi_srs_indication_t* ind);
|
||||
void mac_sr_ind(mac_t* mac, nfapi_sr_indication_t* ind);
|
||||
void mac_cqi_ind(mac_t* mac, nfapi_cqi_indication_t* ind);
|
||||
void mac_lbt_dl_ind(mac_t* mac, nfapi_lbt_dl_indication_t* ind);
|
||||
void mac_nb_harq_ind(mac_t* mac, nfapi_nb_harq_indication_t* ind);
|
||||
void mac_nrach_ind(mac_t* mac, nfapi_nrach_indication_t* ind);
|
||||
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
1160
l2-fapi-proxy/open-nFAPI/vnf_sim/src/mac.cpp
Normal file
1160
l2-fapi-proxy/open-nFAPI/vnf_sim/src/mac.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1712
l2-fapi-proxy/open-nFAPI/vnf_sim/src/main.cpp
Normal file
1712
l2-fapi-proxy/open-nFAPI/vnf_sim/src/main.cpp
Normal file
File diff suppressed because it is too large
Load Diff
88
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_1_A.xml
Normal file
88
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_1_A.xml
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pnf>
|
||||
<sync_mode>0</sync_mode>
|
||||
<location_mode>0</location_mode>
|
||||
<location_coordinates></location_coordinates>
|
||||
|
||||
<dl_config_timing>500</dl_config_timing>
|
||||
<ul_config_timing>500</ul_config_timing>
|
||||
<tx_timing>500</tx_timing>
|
||||
<hi_dci0_timing>500</hi_dci0_timing>
|
||||
|
||||
<max_phys>1</max_phys>
|
||||
<max_total_bandwidth>30</max_total_bandwidth>
|
||||
<max_total_num_dl_layers>1</max_total_num_dl_layers>
|
||||
<max_total_num_ul_layers>1</max_total_num_ul_layers>
|
||||
|
||||
<shared_bands>0</shared_bands>
|
||||
<shared_pas>0</shared_pas>
|
||||
|
||||
<maximum_total_power>0</maximum_total_power>
|
||||
|
||||
<oui>ALPHA</oui>
|
||||
|
||||
|
||||
<phys>
|
||||
<phy>
|
||||
<index>88</index>
|
||||
<port>2500</port>
|
||||
<address>192.168.1.74</address>
|
||||
|
||||
<duplex_mode>1</duplex_mode>
|
||||
|
||||
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
|
||||
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
|
||||
|
||||
<number_of_dl_layers>1</number_of_dl_layers>
|
||||
<number_of_ul_layers>1</number_of_ul_layers>
|
||||
|
||||
<3gpp_release_supported>31</3gpp_release_supported>
|
||||
|
||||
<nmm_modes_supported>0</nmm_modes_supported>
|
||||
|
||||
<dl_ues_per_subframe>8</dl_ues_per_subframe>
|
||||
<ul_ues_per_subframe>8</ul_ues_per_subframe>
|
||||
|
||||
<!-- todo adn the other release parameters -->
|
||||
|
||||
<rfs>
|
||||
<index>0</index>
|
||||
</rfs>
|
||||
<excluded_rfs>
|
||||
<index>1</index>
|
||||
</excluded_rfs>
|
||||
|
||||
<data>
|
||||
<udp>
|
||||
<rx_port>5201</rx_port>
|
||||
<tx_addr>192.168.1.28</tx_addr>
|
||||
<tx_port>5200</tx_port>
|
||||
</udp>
|
||||
</data>
|
||||
</phy>
|
||||
</phys>
|
||||
<rfs>
|
||||
<rf>
|
||||
<index>0</index>
|
||||
<band>2</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
<rf>
|
||||
<index>1</index>
|
||||
<band>3</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
</rfs>
|
||||
</pnf>
|
||||
90
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_1_A_ws.xml
Normal file
90
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_1_A_ws.xml
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pnf>
|
||||
<wireshark_test_mode>1</wireshark_test_mode>
|
||||
|
||||
<sync_mode>0</sync_mode>
|
||||
<location_mode>0</location_mode>
|
||||
<location_coordinates></location_coordinates>
|
||||
|
||||
<dl_config_timing>500</dl_config_timing>
|
||||
<ul_config_timing>500</ul_config_timing>
|
||||
<tx_timing>500</tx_timing>
|
||||
<hi_dci0_timing>500</hi_dci0_timing>
|
||||
|
||||
<max_phys>1</max_phys>
|
||||
<max_total_bandwidth>30</max_total_bandwidth>
|
||||
<max_total_num_dl_layers>1</max_total_num_dl_layers>
|
||||
<max_total_num_ul_layers>1</max_total_num_ul_layers>
|
||||
|
||||
<shared_bands>0</shared_bands>
|
||||
<shared_pas>0</shared_pas>
|
||||
|
||||
<maximum_total_power>0</maximum_total_power>
|
||||
|
||||
<oui>ALPHA</oui>
|
||||
|
||||
|
||||
<phys>
|
||||
<phy>
|
||||
<index>88</index>
|
||||
<port>2500</port>
|
||||
<address>127.0.0.1</address>
|
||||
|
||||
<duplex_mode>1</duplex_mode>
|
||||
|
||||
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
|
||||
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
|
||||
|
||||
<number_of_dl_layers>1</number_of_dl_layers>
|
||||
<number_of_ul_layers>1</number_of_ul_layers>
|
||||
|
||||
<3gpp_release_supported>31</3gpp_release_supported>
|
||||
|
||||
<nmm_modes_supported>0</nmm_modes_supported>
|
||||
|
||||
<dl_ues_per_subframe>8</dl_ues_per_subframe>
|
||||
<ul_ues_per_subframe>8</ul_ues_per_subframe>
|
||||
|
||||
<!-- todo adn the other release parameters -->
|
||||
|
||||
<rfs>
|
||||
<index>0</index>
|
||||
</rfs>
|
||||
<excluded_rfs>
|
||||
<index>1</index>
|
||||
</excluded_rfs>
|
||||
|
||||
<data>
|
||||
<udp>
|
||||
<rx_port>7722</rx_port>
|
||||
<tx_addr>127.0.0.1</tx_addr>
|
||||
<tx_port>7733</tx_port>
|
||||
</udp>
|
||||
</data>
|
||||
</phy>
|
||||
</phys>
|
||||
<rfs>
|
||||
<rf>
|
||||
<index>0</index>
|
||||
<band>2</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
<rf>
|
||||
<index>1</index>
|
||||
<band>3</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
</rfs>
|
||||
</pnf>
|
||||
88
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_1_B.xml
Normal file
88
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_1_B.xml
Normal file
@@ -0,0 +1,88 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pnf>
|
||||
<sync_mode>0</sync_mode>
|
||||
<location_mode>0</location_mode>
|
||||
<location_coordinates></location_coordinates>
|
||||
|
||||
<dl_config_timing>500</dl_config_timing>
|
||||
<ul_config_timing>500</ul_config_timing>
|
||||
<tx_timing>500</tx_timing>
|
||||
<hi_dci0_timing>500</hi_dci0_timing>
|
||||
|
||||
<max_phys>1</max_phys>
|
||||
<max_total_bandwidth>30</max_total_bandwidth>
|
||||
<max_total_num_dl_layers>1</max_total_num_dl_layers>
|
||||
<max_total_num_ul_layers>1</max_total_num_ul_layers>
|
||||
|
||||
<shared_bands>0</shared_bands>
|
||||
<shared_pas>0</shared_pas>
|
||||
|
||||
<maximum_total_power>0</maximum_total_power>
|
||||
|
||||
<oui>ALPHA</oui>
|
||||
|
||||
|
||||
<phys>
|
||||
<phy>
|
||||
<index>89</index>
|
||||
<port>2510</port>
|
||||
<address>127.0.0.1</address>
|
||||
|
||||
<duplex_mode>1</duplex_mode>
|
||||
|
||||
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
|
||||
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
|
||||
|
||||
<number_of_dl_layers>1</number_of_dl_layers>
|
||||
<number_of_ul_layers>1</number_of_ul_layers>
|
||||
|
||||
<3gpp_release_supported>31</3gpp_release_supported>
|
||||
|
||||
<nmm_modes_supported>0</nmm_modes_supported>
|
||||
|
||||
<dl_ues_per_subframe>8</dl_ues_per_subframe>
|
||||
<ul_ues_per_subframe>8</ul_ues_per_subframe>
|
||||
|
||||
<!-- todo adn the other release parameters -->
|
||||
|
||||
<rfs>
|
||||
<index>0</index>
|
||||
</rfs>
|
||||
<excluded_rfs>
|
||||
<index>1</index>
|
||||
</excluded_rfs>
|
||||
|
||||
<data>
|
||||
<udp>
|
||||
<rx_port>7744</rx_port>
|
||||
<tx_addr>127.0.0.1</tx_addr>
|
||||
<tx_port>7755</tx_port>
|
||||
</udp>
|
||||
</data>
|
||||
</phy>
|
||||
</phys>
|
||||
<rfs>
|
||||
<rf>
|
||||
<index>0</index>
|
||||
<band>2</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
<rf>
|
||||
<index>1</index>
|
||||
<band>3</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
</rfs>
|
||||
</pnf>
|
||||
90
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_2_A.xml
Normal file
90
l2-fapi-proxy/open-nFAPI/xml/pnf_phy_2_A.xml
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<pnf>
|
||||
<sync_mode>0</sync_mode>
|
||||
<location_mode>0</location_mode>
|
||||
<location_coordinates></location_coordinates>
|
||||
|
||||
<dl_config_timing>500</dl_config_timing>
|
||||
<ul_config_timing>500</ul_config_timing>
|
||||
<tx_timing>500</tx_timing>
|
||||
<hi_dci0_timing>500</hi_dci0_timing>
|
||||
|
||||
<max_phys>1</max_phys>
|
||||
<max_total_bandwidth>30</max_total_bandwidth>
|
||||
<max_total_num_dl_layers>1</max_total_num_dl_layers>
|
||||
<max_total_num_ul_layers>1</max_total_num_ul_layers>
|
||||
|
||||
<shared_bands>0</shared_bands>
|
||||
<shared_pas>0</shared_pas>
|
||||
|
||||
<maximum_total_power>0</maximum_total_power>
|
||||
|
||||
<oui>ALPHA</oui>
|
||||
|
||||
<phys>
|
||||
<phy>
|
||||
<index>88</index>
|
||||
<port>2500</port>
|
||||
<address>127.0.0.1</address>
|
||||
|
||||
<duplex_mode>1</duplex_mode>
|
||||
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
|
||||
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
|
||||
<number_of_dl_layers>1</number_of_dl_layers>
|
||||
<number_of_ul_layers>1</number_of_ul_layers>
|
||||
<3gpp_release_supported>31</3gpp_release_supported>
|
||||
<nmm_modes_supported>0</nmm_modes_supported>
|
||||
<dl_ues_per_subframe>8</dl_ues_per_subframe>
|
||||
<ul_ues_per_subframe>8</ul_ues_per_subframe>
|
||||
|
||||
<rfs>
|
||||
<index>0</index>
|
||||
</rfs>
|
||||
<excluded_rfs/>
|
||||
</phy>
|
||||
<phy>
|
||||
<index>44</index>
|
||||
<port>2600</port>
|
||||
<address>127.0.0.1</address>
|
||||
|
||||
<duplex_mode>1</duplex_mode>
|
||||
<downlink_channel_bandwidth_support>22</downlink_channel_bandwidth_support>
|
||||
<uplink_channel_bandwidth_support>22</uplink_channel_bandwidth_support>
|
||||
<number_of_dl_layers>1</number_of_dl_layers>
|
||||
<number_of_ul_layers>1</number_of_ul_layers>
|
||||
<3gpp_release_supported>31</3gpp_release_supported>
|
||||
<nmm_modes_supported>0</nmm_modes_supported>
|
||||
<dl_ues_per_subframe>8</dl_ues_per_subframe>
|
||||
<ul_ues_per_subframe>8</ul_ues_per_subframe>
|
||||
|
||||
<rfs>
|
||||
<index>1</index>
|
||||
</rfs>
|
||||
<excluded_rfs/>
|
||||
</phy>
|
||||
</phys>
|
||||
<rfs>
|
||||
<rf>
|
||||
<index>0</index>
|
||||
<band>2</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
<rf>
|
||||
<index>1</index>
|
||||
<band>4</band>
|
||||
<max_transmit_power>-30</max_transmit_power>
|
||||
<min_transmit_power>-230</min_transmit_power>
|
||||
<num_antennas_supported>2</num_antennas_supported>
|
||||
<min_downlink_frequency>1890</min_downlink_frequency>
|
||||
<max_downlink_frequency>1890</max_downlink_frequency>
|
||||
<max_uplink_frequency>1890</max_uplink_frequency>
|
||||
<min_uplink_frequency>1890</min_uplink_frequency>
|
||||
</rf>
|
||||
</rfs>
|
||||
</pnf>
|
||||
21
l2-fapi-proxy/open-nFAPI/xml/vnf_A.xml
Normal file
21
l2-fapi-proxy/open-nFAPI/xml/vnf_A.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vnf>
|
||||
<vnf_p7_list>
|
||||
<vnf_p7>
|
||||
<port>5201</port>
|
||||
<address>192.168.1.28</address>
|
||||
<timing_window>10</timing_window>
|
||||
<periodic_timing_enabled>0</periodic_timing_enabled>
|
||||
<periodic_timing_window>0</periodic_timing_window>
|
||||
<aperiodic_timing_enabled>0</aperiodic_timing_enabled>
|
||||
|
||||
<data>
|
||||
<udp>
|
||||
<rx_port>8891</rx_port>
|
||||
<tx_addr>192.168.1.28</tx_addr>
|
||||
<tx_port>8892</tx_port>
|
||||
</udp>
|
||||
</data>
|
||||
</vnf_p7>
|
||||
</vnf_p7_list>
|
||||
</vnf>
|
||||
23
l2-fapi-proxy/open-nFAPI/xml/vnf_A_ws.xml
Normal file
23
l2-fapi-proxy/open-nFAPI/xml/vnf_A_ws.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<vnf>
|
||||
|
||||
<vnf_p7_list>
|
||||
<vnf_p7>
|
||||
<wireshark_test_mode>1</wireshark_test_mode>
|
||||
<port>5200</port>
|
||||
<address>127.0.0.1</address>
|
||||
<timing_window>10</timing_window>
|
||||
<periodic_timing_enabled>0</periodic_timing_enabled>
|
||||
<periodic_timing_window>0</periodic_timing_window>
|
||||
<aperiodic_timing_enabled>0</aperiodic_timing_enabled>
|
||||
|
||||
<data>
|
||||
<udp>
|
||||
<rx_port>8891</rx_port>
|
||||
<tx_addr>127.0.0.1</tx_addr>
|
||||
<tx_port>8892</tx_port>
|
||||
</udp>
|
||||
</data>
|
||||
</vnf_p7>
|
||||
</vnf_p7_list>
|
||||
</vnf>
|
||||
296
l2-fapi-proxy/src/lte_proxy.cc
Normal file
296
l2-fapi-proxy/src/lte_proxy.cc
Normal file
@@ -0,0 +1,296 @@
|
||||
#/*
|
||||
# * Licensed to the EPYSYS SCIENCE (EpiSci) under one or more
|
||||
# * contributor license agreements.
|
||||
# * The EPYSYS SCIENCE (EpiSci) licenses this file to You under
|
||||
# * the Episys Science (EpiSci) 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
|
||||
# *
|
||||
# * https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy/blob/master/LICENSE
|
||||
# *
|
||||
# * 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 EPYSYS SCIENCE (EpiSci):
|
||||
# * bo.ryu@episci.com
|
||||
# */
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sstream>
|
||||
#include "lte_proxy.h"
|
||||
#include "nfapi_pnf.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
Multi_UE_Proxy *instance;
|
||||
}
|
||||
|
||||
Multi_UE_Proxy::Multi_UE_Proxy(int num_of_ues, std::string enb_ip, std::string proxy_ip, std::vector<std::string> ue_ip)
|
||||
{
|
||||
assert(instance == NULL);
|
||||
instance = this;
|
||||
num_ues = num_of_ues ;
|
||||
|
||||
configure(enb_ip, proxy_ip, ue_ip);
|
||||
|
||||
oai_subframe_init();
|
||||
}
|
||||
|
||||
void Multi_UE_Proxy::start(softmodem_mode_t softmodem_mode)
|
||||
{
|
||||
pthread_t thread;
|
||||
|
||||
configure_nfapi_pnf(vnf_ipaddr.c_str(), vnf_p5port, pnf_ipaddr.c_str(), pnf_p7port, vnf_p7port);
|
||||
|
||||
if (pthread_create(&thread, NULL, &oai_subframe_task, (void *)softmodem_mode) != 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "pthread_create failed for calling oai_subframe_task");
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_ues; i++)
|
||||
{
|
||||
threads.push_back(std::thread(&Multi_UE_Proxy::receive_message_from_ue, this, i));
|
||||
}
|
||||
for (auto &th : threads)
|
||||
{
|
||||
if(th.joinable())
|
||||
{
|
||||
th.join();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Multi_UE_Proxy::configure(std::string enb_ip, std::string proxy_ip, std::vector<std::string> ue_ip)
|
||||
{
|
||||
oai_ue_ipaddr = ue_ip;
|
||||
vnf_ipaddr = enb_ip;
|
||||
pnf_ipaddr = proxy_ip;
|
||||
vnf_p5port = 50001;
|
||||
vnf_p7port = 50011;
|
||||
pnf_p7port = 50010;
|
||||
|
||||
std::cout<<"VNF is on IP Address "<<vnf_ipaddr<<std::endl;
|
||||
std::cout<<"PNF is on IP Address "<<pnf_ipaddr<<std::endl;
|
||||
|
||||
for (int ue_idx = 0; ue_idx < num_ues; ue_idx++)
|
||||
{
|
||||
std::cout<<"OAI-UE "<<ue_idx<<" is on IP Address "<<oai_ue_ipaddr[ue_idx]<<std::endl;
|
||||
int oai_rx_ue_port = 3211 + ue_idx * port_delta;
|
||||
int oai_tx_ue_port = 3212 + ue_idx * port_delta;
|
||||
init_oai_socket(oai_ue_ipaddr[ue_idx].c_str(), oai_tx_ue_port, oai_rx_ue_port, ue_idx);
|
||||
}
|
||||
}
|
||||
|
||||
int Multi_UE_Proxy::init_oai_socket(const char *addr, int tx_port, int rx_port, int ue_idx)
|
||||
{
|
||||
{ //Setup Rx Socket
|
||||
memset(&address_rx_, 0, sizeof(address_rx_));
|
||||
address_rx_.sin_family = AF_INET;
|
||||
address_rx_.sin_addr.s_addr = INADDR_ANY;
|
||||
address_rx_.sin_port = htons(rx_port);
|
||||
|
||||
ue_rx_socket_ = socket(address_rx_.sin_family, SOCK_DGRAM, 0);
|
||||
ue_rx_socket[ue_idx] = ue_rx_socket_;
|
||||
if (ue_rx_socket_ < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "socket: %s", ERR);
|
||||
return -1;
|
||||
}
|
||||
if (bind(ue_rx_socket_, (struct sockaddr *)&address_rx_, sizeof(address_rx_)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "bind failed in init_oai_socket: %s\n", strerror(errno));
|
||||
close(ue_rx_socket_);
|
||||
ue_rx_socket_ = -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
{ //Setup Tx Socket
|
||||
memset(&address_tx_, 0, sizeof(address_tx_));
|
||||
address_tx_.sin_family = AF_INET;
|
||||
address_tx_.sin_port = htons(tx_port);
|
||||
|
||||
if (inet_aton(addr, &address_tx_.sin_addr) == 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "addr no good %s", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ue_tx_socket_ = socket(address_tx_.sin_family, SOCK_DGRAM, 0);
|
||||
ue_tx_socket[ue_idx] = ue_tx_socket_;
|
||||
if (ue_tx_socket_ < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "socket: %s", ERR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (connect(ue_tx_socket_, (struct sockaddr *)&address_tx_, sizeof(address_tx_)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "tx connection failed in init_oai_socket: %s\n", strerror(errno));
|
||||
close(ue_tx_socket_);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Multi_UE_Proxy::receive_message_from_ue(int ue_idx)
|
||||
{
|
||||
char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
|
||||
socklen_t addr_len = sizeof(address_rx_);
|
||||
|
||||
while(true)
|
||||
{
|
||||
int buflen = recvfrom(ue_rx_socket[ue_idx], buffer, sizeof(buffer), 0, (sockaddr *)&address_rx_, &addr_len);
|
||||
if (buflen == -1)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Recvfrom failed %s", strerror(errno));
|
||||
return ;
|
||||
}
|
||||
if (buflen == 4)
|
||||
{
|
||||
//NFAPI_TRACE(NFAPI_TRACE_INFO , "Dummy frame");
|
||||
continue;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
nfapi_p7_message_header_t header;
|
||||
if (nfapi_p7_message_header_unpack(buffer, buflen, &header, sizeof(header), NULL) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Header unpack failed for standalone pnf");
|
||||
return ;
|
||||
}
|
||||
uint16_t sfn_sf = nfapi_get_sfnsf(buffer, buflen);
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO , "(Proxy) Proxy has received %d uplink message from OAI UE at socket. Frame: %d, Subframe: %d",
|
||||
header.message_id, NFAPI_SFNSF2SFN(sfn_sf), NFAPI_SFNSF2SF(sfn_sf));
|
||||
}
|
||||
oai_subframe_handle_msg_from_ue(buffer, buflen, ue_idx + 2);
|
||||
}
|
||||
}
|
||||
|
||||
void Multi_UE_Proxy::oai_enb_downlink_nfapi_task(void *msg_org)
|
||||
{
|
||||
lock_guard_t lock(mutex);
|
||||
|
||||
char buffer[NFAPI_MAX_PACKED_MESSAGE_SIZE];
|
||||
int encoded_size = nfapi_p7_message_pack(msg_org, buffer, sizeof(buffer), nullptr);
|
||||
if (encoded_size <= 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Message pack failed");
|
||||
return;
|
||||
}
|
||||
|
||||
union
|
||||
{
|
||||
nfapi_p7_message_header_t header;
|
||||
nfapi_dl_config_request_t dl_config_req;
|
||||
nfapi_tx_request_t tx_req;
|
||||
nfapi_hi_dci0_request_t hi_dci0_req;
|
||||
nfapi_ul_config_request_t ul_config_req;
|
||||
} msg;
|
||||
|
||||
if (nfapi_p7_message_unpack((void *)buffer, encoded_size, &msg, sizeof(msg), NULL) != 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "nfapi_p7_message_unpack failed NEM ID: %d", 1);
|
||||
return;
|
||||
}
|
||||
|
||||
for(int ue_idx = 0; ue_idx < num_ues; ue_idx++)
|
||||
{
|
||||
inet_aton(oai_ue_ipaddr[ue_idx].c_str(), &address_tx_.sin_addr);
|
||||
address_tx_.sin_port = htons(3212 + ue_idx * port_delta);
|
||||
uint16_t id_=1;
|
||||
switch (msg.header.message_id)
|
||||
{
|
||||
|
||||
case NFAPI_DL_CONFIG_REQUEST:
|
||||
{
|
||||
int dl_sfn = NFAPI_SFNSF2SFN(msg.dl_config_req.sfn_sf);
|
||||
int dl_sf = NFAPI_SFNSF2SF(msg.dl_config_req.sfn_sf);
|
||||
uint16_t dl_numPDU = msg.dl_config_req.dl_config_request_body.number_pdu;
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO , "(UE) Prior to sending dl_config_req to OAI UE. Frame: %d,"
|
||||
" Subframe: %d, Number of PDUs: %u",
|
||||
dl_sfn, dl_sf, dl_numPDU);
|
||||
assert(ue_tx_socket[ue_idx] > 2);
|
||||
if (sendto(ue_tx_socket[ue_idx], buffer, encoded_size, 0, (const struct sockaddr *) &address_tx_, sizeof(address_tx_)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Send NFAPI_DL_CONFIG_REQUEST to OAI UE failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO , "DL_CONFIG_REQ forwarded to UE from UE NEM: %u", id_);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NFAPI_TX_REQUEST:
|
||||
assert(ue_tx_socket[ue_idx] > 2);
|
||||
if (sendto(ue_tx_socket[ue_idx], buffer, encoded_size, 0, (const struct sockaddr *) &address_tx_, sizeof(address_tx_)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Send NFAPI_TX_CONFIG_REQUEST to OAI UE failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO , "TX_REQ forwarded to UE from UE NEM: %u", id_);
|
||||
}
|
||||
break;
|
||||
|
||||
case NFAPI_UL_CONFIG_REQUEST:
|
||||
assert(ue_tx_socket[ue_idx] > 2);
|
||||
if (sendto(ue_tx_socket[ue_idx], buffer, encoded_size, 0, (const struct sockaddr *) &address_tx_, sizeof(address_tx_)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Send NFAPI_UL_CONFIG_REQUEST to OAI UE failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO , "UL_CONFIG_REQ forwarded to UE from UE NEM: %u", id_);
|
||||
}
|
||||
break;
|
||||
|
||||
case NFAPI_HI_DCI0_REQUEST:
|
||||
assert(ue_tx_socket[ue_idx] > 2);
|
||||
if (sendto(ue_tx_socket[ue_idx], buffer, encoded_size, 0, (const struct sockaddr *) &address_tx_, sizeof(address_tx_)) < 0)
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Send NFAPI_HI_DCI0_REQUEST to OAI UE failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO , "NFAPI_HI_DCI0_REQ forwarded to UE from UE NEM: %u", id_);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
NFAPI_TRACE(NFAPI_TRACE_INFO , "Unhandled message at UE NEM: %d message_id: %u", id_, msg.header.message_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Multi_UE_Proxy::pack_and_send_downlink_sfn_sf_msg(uint16_t sfn_sf)
|
||||
{
|
||||
lock_guard_t lock(mutex);
|
||||
|
||||
for(int ue_idx = 0; ue_idx < num_ues; ue_idx++)
|
||||
{
|
||||
inet_aton(oai_ue_ipaddr[ue_idx].c_str(), &address_tx_.sin_addr);
|
||||
address_tx_.sin_port = htons(3212 + ue_idx * port_delta);
|
||||
assert(ue_tx_socket[ue_idx] > 2);
|
||||
if (sendto(ue_tx_socket[ue_idx], &sfn_sf, sizeof(sfn_sf), 0, (const struct sockaddr *) &address_tx_, sizeof(address_tx_)) < 0)
|
||||
{
|
||||
int sfn = NFAPI_SFNSF2SFN(sfn_sf);
|
||||
int sf = NFAPI_SFNSF2SF(sfn_sf);
|
||||
NFAPI_TRACE(NFAPI_TRACE_ERROR, "Send sfn_sf_tx to OAI UE FAIL Frame: %d,Subframe: %d", sfn, sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void transfer_downstream_nfapi_msg_to_proxy(void *msg)
|
||||
{
|
||||
instance->oai_enb_downlink_nfapi_task(msg);
|
||||
}
|
||||
void transfer_downstream_sfn_sf_to_proxy(uint16_t sfn_sf)
|
||||
{
|
||||
instance->pack_and_send_downlink_sfn_sf_msg(sfn_sf);
|
||||
}
|
||||
82
l2-fapi-proxy/src/lte_proxy.h
Normal file
82
l2-fapi-proxy/src/lte_proxy.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#/*
|
||||
# * Licensed to the EPYSYS SCIENCE (EpiSci) under one or more
|
||||
# * contributor license agreements.
|
||||
# * The EPYSYS SCIENCE (EpiSci) licenses this file to You under
|
||||
# * the Episys Science (EpiSci) 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
|
||||
# *
|
||||
# * https://github.com/EpiSci/oai-lte-5g-multi-ue-proxy/blob/master/LICENSE
|
||||
# *
|
||||
# * 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 EPYSYS SCIENCE (EpiSci):
|
||||
# * bo.ryu@episci.com
|
||||
# */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/sctp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include "proxy.h"
|
||||
|
||||
class Multi_UE_Proxy
|
||||
{
|
||||
public:
|
||||
Multi_UE_Proxy(int num_of_ues, std::string enb_ip, std::string proxy_ip, std::vector<std::string> ue_ip);
|
||||
~Multi_UE_Proxy() = default;
|
||||
void configure(std::string enb_ip, std::string proxy_ip, std::vector<std::string> ue_ip);
|
||||
int init_oai_socket(const char *addr, int tx_port, int rx_port, int ue_idx);
|
||||
void oai_enb_downlink_nfapi_task(void *msg);
|
||||
void testcode_tx_packet_to_UE( int ue_tx_socket_);
|
||||
void pack_and_send_downlink_sfn_sf_msg(uint16_t sfn_sf);
|
||||
void receive_message_from_ue(int ue_id);
|
||||
void send_ue_to_enb_msg(void *buffer, size_t buflen);
|
||||
void send_received_msg_to_proxy_queue(void *buffer, size_t buflen);
|
||||
void send_uplink_oai_msg_to_proxy_queue(void *buffer, size_t buflen);
|
||||
void start(softmodem_mode_t softmodem_mode);
|
||||
private:
|
||||
std::vector<std::string> oai_ue_ipaddr;
|
||||
std::string vnf_ipaddr;
|
||||
std::string pnf_ipaddr;
|
||||
int vnf_p5port = -1;
|
||||
int vnf_p7port = -1;
|
||||
int pnf_p7port = -1;
|
||||
|
||||
std::uint16_t u16SequenceNumber_ = 0;
|
||||
struct sockaddr_in address_tx_;
|
||||
struct sockaddr_in address_rx_;
|
||||
int ue_tx_socket_ = -1;
|
||||
int ue_rx_socket_ = -1;
|
||||
int ue_rx_socket[100];
|
||||
int ue_tx_socket[100];
|
||||
std::uint16_t id ;
|
||||
std::recursive_mutex mutex;
|
||||
using lock_guard_t = std::lock_guard<std::recursive_mutex>;
|
||||
std::vector<std::thread> threads;
|
||||
bool stop_thread = false;
|
||||
int port_delta = 2;
|
||||
};
|
||||
57
l2-fapi-proxy/src/nfapi.c
Normal file
57
l2-fapi-proxy/src/nfapi.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 <pthread.h>
|
||||
// #include "nfapi/oai_integration/vendor_ext.h"
|
||||
#include "vendor_ext.h"
|
||||
#include "log.h"
|
||||
static const char *const nfapi_str_mode[] = {
|
||||
"MONOLITHIC",
|
||||
"PNF",
|
||||
"VNF",
|
||||
"AERIAL",
|
||||
"UE_STUB_PNF",
|
||||
"UE_STUB_OFFNET",
|
||||
"STANDALONE_PNF",
|
||||
"<UNKNOWN NFAPI MODE>"
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
nfapi_mode_t nfapi_mode;
|
||||
} nfapi_params_t;
|
||||
|
||||
static nfapi_params_t nfapi_params = {0};
|
||||
|
||||
const char *nfapi_get_strmode(void) {
|
||||
if (nfapi_params.nfapi_mode > NFAPI_MODE_UNKNOWN)
|
||||
return nfapi_str_mode[NFAPI_MODE_UNKNOWN];
|
||||
|
||||
return nfapi_str_mode[nfapi_params.nfapi_mode];
|
||||
}
|
||||
|
||||
nfapi_mode_t nfapi_getmode(void) {
|
||||
return nfapi_params.nfapi_mode;
|
||||
}
|
||||
|
||||
void nfapi_setmode(nfapi_mode_t nfapi_mode) {
|
||||
nfapi_params.nfapi_mode = nfapi_mode;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user