From 6b794037673eb0efbb6f9e9ed703b1b339838069 Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 21 Apr 2020 15:20:22 +0200 Subject: [PATCH 001/171] NR pdcp: Rebase initial implementation Initially targeting ENDC setup with commercial UE - Missing nr_rrc_pdcp and nr_rrc_rlc configuration wrt the established DRB - Remaining to test with user plane data traffic (Downlink and Uplink) --- cmake_targets/CMakeLists.txt | 35 +- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c | 74 ++ openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h | 63 ++ .../LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c | 70 ++ .../LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h | 38 + openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 837 ++++++++++++++++++ openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c | 198 +++++ openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h | 65 ++ 8 files changed, 1366 insertions(+), 14 deletions(-) create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c create mode 100644 openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index ebd6f88fc2..bac4e22568 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1668,6 +1668,16 @@ set(LTE_RLC_SRC ${RLC_DIR}/rlc_mpls.c ) +set(LTE_PDCP_SRC + ${PDCP_DIR}/pdcp.c + ${PDCP_DIR}/pdcp_fifo.c + ${PDCP_DIR}/pdcp_sequence_manager.c + ${PDCP_DIR}/pdcp_primitives.c + ${PDCP_DIR}/pdcp_util.c + ${PDCP_DIR}/pdcp_security.c + ${PDCP_DIR}/pdcp_netlink.c + ) + set(NR_RLC_SRC ${OPENAIR2_DIR}/LAYER2/nr_rlc/asn1_utils.c ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_entity.c @@ -1679,16 +1689,16 @@ set(NR_RLC_SRC ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_sdu.c ${OPENAIR2_DIR}/LAYER2/nr_rlc/nr_rlc_ue_manager.c ) + +set(NR_PDCP_SRC + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_oai_api.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity.c + ${OPENAIR2_DIR}/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c + ) set(L2_SRC ${OPENAIR2_DIR}/LAYER2/openair2_proc.c - ${PDCP_DIR}/pdcp.c - ${PDCP_DIR}/pdcp_fifo.c - ${PDCP_DIR}/pdcp_sequence_manager.c - ${PDCP_DIR}/pdcp_primitives.c - ${PDCP_DIR}/pdcp_util.c - ${PDCP_DIR}/pdcp_security.c - ${PDCP_DIR}/pdcp_netlink.c # ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_eNB.c ${RRC_DIR}/rrc_eNB_endc.c @@ -1703,10 +1713,12 @@ set(L2_SRC set(L2_LTE_SRC ${LTE_RLC_SRC} + ${LTE_PDCP_SRC} ) set(L2_NR_SRC ${NR_RLC_SRC} + ${NR_PDCP_SRC} ${NR_RRC_DIR}/rrc_gNB.c ${NR_RRC_DIR}/nr_rrc_common.c ${NR_RRC_DIR}/L2_nr_interface.c @@ -1718,13 +1730,6 @@ set(L2_NR_SRC ) set(L2_SRC_UE - ${PDCP_DIR}/pdcp.c - ${PDCP_DIR}/pdcp_fifo.c - ${PDCP_DIR}/pdcp_sequence_manager.c - ${PDCP_DIR}/pdcp_primitives.c - ${PDCP_DIR}/pdcp_util.c - ${PDCP_DIR}/pdcp_security.c - ${PDCP_DIR}/pdcp_netlink.c ${RRC_DIR}/rrc_UE.c ${RRC_DIR}/rrc_common.c ${RRC_DIR}/L2_interface_common.c @@ -1740,10 +1745,12 @@ set(LTE_NR_L2_SRC_UE ${PDCP_DIR}/pdcp_security.c ${PDCP_DIR}/pdcp_netlink.c ${LTE_RLC_SRC} + ${LTE_PDCP_SRC} ) set(NR_L2_SRC_UE ${NR_RLC_SRC} + ${NR_PDCP_SRC} ${NR_UE_RRC_DIR}/L2_interface_ue.c ${NR_UE_RRC_DIR}/main_ue.c ${NR_UE_RRC_DIR}/rrc_UE.c diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c new file mode 100644 index 0000000000..e25201c22c --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -0,0 +1,74 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_entity.h" + +#include "nr_pdcp_entity_drb_am.h" + +#include "LOG/log.h" + +nr_pdcp_entity_t *new_nr_pdcp_entity_srb( + int rb_id, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size, int sdu_id), + void *deliver_pdu_data) +{ + abort(); +} + +nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( + int rb_id, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size, int sdu_id), + void *deliver_pdu_data) +{ + nr_pdcp_entity_drb_am_t *ret; + + ret = calloc(1, sizeof(nr_pdcp_entity_drb_am_t)); + if (ret == NULL) { + LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ret->common.recv_pdu = nr_pdcp_entity_drb_am_recv_pdu; + ret->common.recv_sdu = nr_pdcp_entity_drb_am_recv_sdu; + ret->common.set_integrity_key = nr_pdcp_entity_drb_am_set_integrity_key; + + ret->common.delete = nr_pdcp_entity_drb_am_delete; + + ret->common.deliver_sdu = deliver_sdu; + ret->common.deliver_sdu_data = deliver_sdu_data; + + ret->common.deliver_pdu = deliver_pdu; + ret->common.deliver_pdu_data = deliver_pdu_data; + + ret->rb_id = rb_id; + + ret->common.maximum_nr_pdcp_sn = 4095; + + return (nr_pdcp_entity_t *)ret; +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h new file mode 100644 index 0000000000..74f09352d6 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -0,0 +1,63 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_ENTITY_H_ +#define _NR_PDCP_ENTITY_H_ + +typedef struct nr_pdcp_entity_t { + /* functions provided by the PDCP module */ + void (*recv_pdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size); + void (*recv_sdu)(struct nr_pdcp_entity_t *entity, char *buffer, int size, + int sdu_id); + void (*delete)(struct nr_pdcp_entity_t *entity); + void (*set_integrity_key)(struct nr_pdcp_entity_t *entity, char *key); + + /* callbacks provided to the PDCP module */ + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size); + void *deliver_sdu_data; + void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size, int sdu_id); + void *deliver_pdu_data; + int tx_hfn; + int next_nr_pdcp_tx_sn; + int maximum_nr_pdcp_sn; +} nr_pdcp_entity_t; + +nr_pdcp_entity_t *new_nr_pdcp_entity_srb( + int rb_id, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size, int sdu_id), + void *deliver_pdu_data); + +nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( + int rb_id, + void (*deliver_sdu)(void *deliver_sdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size), + void *deliver_sdu_data, + void (*deliver_pdu)(void *deliver_pdu_data, struct nr_pdcp_entity_t *entity, + char *buf, int size, int sdu_id), + void *deliver_pdu_data); + +#endif /* _NR_PDCP_ENTITY_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c new file mode 100644 index 0000000000..c25f28aae8 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c @@ -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 + */ + +#include "nr_pdcp_entity_drb_am.h" + +#include +#include +#include + +void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int size) +{ + nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; + + if (size < 3) abort(); + if (!(buffer[0] & 0x80)) { printf("%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } + entity->common.deliver_sdu(entity->common.deliver_sdu_data, + (nr_pdcp_entity_t *)entity, buffer+2, size-2); +} + +void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size, + int sdu_id) +{ + nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; + int sn; + char buf[size+2]; + + sn = entity->common.next_nr_pdcp_tx_sn; + + entity->common.next_nr_pdcp_tx_sn++; + if (entity->common.next_nr_pdcp_tx_sn > entity->common.maximum_nr_pdcp_sn) { + entity->common.next_nr_pdcp_tx_sn = 0; + entity->common.tx_hfn++; + } + + buf[0] = 0x80 | ((sn >> 8) & 0x0f); + buf[1] = sn & 0xff; + memcpy(buf+2, buffer, size); + + entity->common.deliver_pdu(entity->common.deliver_pdu_data, + (nr_pdcp_entity_t *)entity, buf, size+2, sdu_id); +} + +void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key) +{ + /* nothing to do */ +} + +void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *_entity) +{ + nr_pdcp_entity_drb_am_t *entity = (nr_pdcp_entity_drb_am_t *)_entity; + free(entity); +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h new file mode 100644 index 0000000000..faa8226e93 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.h @@ -0,0 +1,38 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_ENTITY_DRB_AM_H_ +#define _NR_PDCP_ENTITY_DRB_AM_H_ + +#include "nr_pdcp_entity.h" + +typedef struct { + nr_pdcp_entity_t common; + int rb_id; +} nr_pdcp_entity_drb_am_t; + +void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *entity, char *buffer, int size); +void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *entity, char *buffer, int size, + int sdu_id); +void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *entity, char *key); +void nr_pdcp_entity_drb_am_delete(nr_pdcp_entity_t *entity); + +#endif /* _NR_PDCP_ENTITY_DRB_AM_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c new file mode 100644 index 0000000000..62f71475be --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -0,0 +1,837 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_ue_manager.h" + +/* from OAI */ +#include "pdcp.h" + +#define TODO do { \ + printf("%s:%d:%s: todo\n", __FILE__, __LINE__, __FUNCTION__); \ + exit(1); \ + } while (0) + +static nr_pdcp_ue_manager_t *nr_pdcp_ue_manager; + +/* necessary globals for OAI, not used internally */ +hash_table_t *pdcp_coll_p; +static uint64_t pdcp_optmask; + +/****************************************************************************/ +/* rlc_data_req queue - begin */ +/****************************************************************************/ + +#include + +/* NR PDCP and RLC both use "big locks". In some cases a thread may do + * lock(rlc) followed by lock(pdcp) (typically when running 'rx_sdu'). + * Another thread may first do lock(pdcp) and then lock(rlc) (typically + * the GTP module calls 'pdcp_data_req' that, in a previous implementation + * was indirectly calling 'rlc_data_req' which does lock(rlc)). + * To avoid the resulting deadlock it is enough to ensure that a call + * to lock(pdcp) will never be followed by a call to lock(rlc). So, + * here we chose to have a separate thread that deals with rlc_data_req, + * out of the PDCP lock. Other solutions may be possible. + * So instead of calling 'rlc_data_req' directly we have a queue and a + * separate thread emptying it. + */ + +typedef struct { + protocol_ctxt_t ctxt_pP; + srb_flag_t srb_flagP; + MBMS_flag_t MBMS_flagP; + rb_id_t rb_idP; + mui_t muiP; + confirm_t confirmP; + sdu_size_t sdu_sizeP; + mem_block_t *sdu_pP; +} rlc_data_req_queue_item; + +#define RLC_DATA_REQ_QUEUE_SIZE 10000 + +typedef struct { + rlc_data_req_queue_item q[RLC_DATA_REQ_QUEUE_SIZE]; + volatile int start; + volatile int length; + pthread_mutex_t m; + pthread_cond_t c; +} rlc_data_req_queue; + +static rlc_data_req_queue q; + +static void *rlc_data_req_thread(void *_) +{ + int i; + + while (1) { + if (pthread_mutex_lock(&q.m) != 0) abort(); + while (q.length == 0) + if (pthread_cond_wait(&q.c, &q.m) != 0) abort(); + i = q.start; + if (pthread_mutex_unlock(&q.m) != 0) abort(); + + rlc_data_req(&q.q[i].ctxt_pP, + q.q[i].srb_flagP, + q.q[i].MBMS_flagP, + q.q[i].rb_idP, + q.q[i].muiP, + q.q[i].confirmP, + q.q[i].sdu_sizeP, + q.q[i].sdu_pP, + NULL, + NULL); + + if (pthread_mutex_lock(&q.m) != 0) abort(); + + q.length--; + q.start = (q.start + 1) % RLC_DATA_REQ_QUEUE_SIZE; + + if (pthread_cond_signal(&q.c) != 0) abort(); + if (pthread_mutex_unlock(&q.m) != 0) abort(); + } +} + +static void init_nr_rlc_data_req_queue(void) +{ + pthread_t t; + + pthread_mutex_init(&q.m, NULL); + pthread_cond_init(&q.c, NULL); + + if (pthread_create(&t, NULL, rlc_data_req_thread, NULL) != 0) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +static void enqueue_rlc_data_req(const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_idP, + const mui_t muiP, + confirm_t confirmP, + sdu_size_t sdu_sizeP, + mem_block_t *sdu_pP, + void *_unused1, void *_unused2) +{ + int i; + int logged = 0; + + if (pthread_mutex_lock(&q.m) != 0) abort(); + while (q.length == RLC_DATA_REQ_QUEUE_SIZE) { + if (!logged) { + logged = 1; + LOG_W(PDCP, "%s: rlc_data_req queue is full\n", __FUNCTION__); + } + if (pthread_cond_wait(&q.c, &q.m) != 0) abort(); + } + + i = (q.start + q.length) % RLC_DATA_REQ_QUEUE_SIZE; + q.length++; + + q.q[i].ctxt_pP = *ctxt_pP; + q.q[i].srb_flagP = srb_flagP; + q.q[i].MBMS_flagP = MBMS_flagP; + q.q[i].rb_idP = rb_idP; + q.q[i].muiP = muiP; + q.q[i].confirmP = confirmP; + q.q[i].sdu_sizeP = sdu_sizeP; + q.q[i].sdu_pP = sdu_pP; + + if (pthread_cond_signal(&q.c) != 0) abort(); + if (pthread_mutex_unlock(&q.m) != 0) abort(); +} + +/****************************************************************************/ +/* rlc_data_req queue - end */ +/****************************************************************************/ + +/****************************************************************************/ +/* hacks to be cleaned up at some point - begin */ +/****************************************************************************/ + +#include "LAYER2/MAC/mac_extern.h" + +void nr_ip_over_LTE_DRB_preconfiguration(void) +{ + // Addition for the use-case of 4G stack on top of 5G-NR. + // We need to configure pdcp and rlc instances without having an actual + // UE RRC Connection. In order to be able to test the NR PHY with some injected traffic + // on top of the LTE stack. + protocol_ctxt_t ctxt; + LTE_DRB_ToAddModList_t* DRB_configList=NULL; + DRB_configList = CALLOC(1, sizeof(LTE_DRB_ToAddModList_t)); + struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; + struct LTE_RLC_Config *DRB_rlc_config = NULL; + struct LTE_PDCP_Config *DRB_pdcp_config = NULL; + struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; + + struct LTE_DRB_ToAddMod *DRB_config = NULL; + struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; + long *logicalchannelgroup_drb; + + + //Static preconfiguration of DRB + DRB_config = CALLOC(1, sizeof(*DRB_config)); + + DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); + // allowed value 5..15, value : x+4 + *(DRB_config->eps_BearerIdentity) = 1; //ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation + // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; + // 1 + drb_identiy_index; + DRB_config->drb_Identity = 1; + DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); + *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 + + DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); + DRB_config->rlc_Config = DRB_rlc_config; + + DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); + DRB_config->pdcp_Config = DRB_pdcp_config; + DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); + *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; + DRB_pdcp_config->rlc_AM = NULL; + DRB_pdcp_config->rlc_UM = NULL; + + DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; + DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; + DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; + // PDCP + PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); + DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; + PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; + + DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; + + DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); + DRB_config->logicalChannelConfig = DRB_lchan_config; + DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); + DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; + + DRB_ul_SpecificParameters->priority= 4; + + DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; + //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + DRB_ul_SpecificParameters->bucketSizeDuration = + LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + + logicalchannelgroup_drb = CALLOC(1, sizeof(long)); + *logicalchannelgroup_drb = 1;//(i+1) % 3; + DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; + + ASN_SEQUENCE_ADD(&DRB_configList->list,DRB_config); + + if (ENB_NAS_USE_TUN){ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0); + } + else{ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + } + + rrc_pdcp_config_asn1_req(&ctxt, + (LTE_SRB_ToAddModList_t *) NULL, + DRB_configList, + (LTE_DRB_ToReleaseList_t *) NULL, + 0xff, NULL, NULL, NULL + , (LTE_PMCH_InfoList_r9_t *) NULL, + &DRB_config->drb_Identity); + + rrc_rlc_config_asn1_req(&ctxt, + (LTE_SRB_ToAddModList_t*)NULL, + DRB_configList, + (LTE_DRB_ToReleaseList_t*)NULL + //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) + ,(LTE_PMCH_InfoList_r9_t *)NULL + , 0, 0 + //#endif + ); +} + +static void reblock_tun_socket(void) +{ + extern int nas_sock_fd[]; + int f; + + f = fcntl(nas_sock_fd[0], F_GETFL, 0); + f &= ~(O_NONBLOCK); + if (fcntl(nas_sock_fd[0], F_SETFL, f) == -1) { + LOG_E(PDCP, "reblock_tun_socket failed\n"); + exit(1); + } +} + +static void *enb_tun_read_thread(void *_) +{ + extern int nas_sock_fd[]; + char rx_buf[NL_MAX_PAYLOAD]; + int len; + int rnti; + protocol_ctxt_t ctxt; + + int rb_id = 1; + + while (1) { + len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD); + if (len == -1) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + +printf("\n\n\n########## nas_sock_fd read returns len %d\n", len); + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + + if (rnti == -1) continue; + + ctxt.module_id = 0; + ctxt.enb_flag = 1; + ctxt.instance = 0; + ctxt.frame = 0; + ctxt.subframe = 0; + ctxt.eNB_index = 0; + ctxt.configured = 1; + ctxt.brOption = 0; + + ctxt.rnti = rnti; + + pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf, + PDCP_TRANSMISSION_MODE_DATA, NULL, NULL); + } + + return NULL; +} + +static void *ue_tun_read_thread(void *_) +{ + extern int nas_sock_fd[]; + char rx_buf[NL_MAX_PAYLOAD]; + int len; + int rnti; + protocol_ctxt_t ctxt; + + int rb_id = 1; + + while (1) { + len = read(nas_sock_fd[0], &rx_buf, NL_MAX_PAYLOAD); + if (len == -1) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + +printf("\n\n\n########## nas_sock_fd read returns len %d\n", len); + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + rnti = nr_pdcp_get_first_rnti(nr_pdcp_ue_manager); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + + if (rnti == -1) continue; + + ctxt.module_id = 0; + ctxt.enb_flag = 0; + ctxt.instance = 0; + ctxt.frame = 0; + ctxt.subframe = 0; + ctxt.eNB_index = 0; + ctxt.configured = 1; + ctxt.brOption = 0; + + ctxt.rnti = rnti; + + pdcp_data_req(&ctxt, SRB_FLAG_NO, rb_id, RLC_MUI_UNDEFINED, + RLC_SDU_CONFIRM_NO, len, (unsigned char *)rx_buf, + PDCP_TRANSMISSION_MODE_DATA, NULL, NULL); + } + + return NULL; +} + +static void start_pdcp_tun_enb(void) +{ + pthread_t t; + + reblock_tun_socket(); + + if (pthread_create(&t, NULL, enb_tun_read_thread, NULL) != 0) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +static void start_pdcp_tun_ue(void) +{ + pthread_t t; + + reblock_tun_socket(); + + if (pthread_create(&t, NULL, ue_tun_read_thread, NULL) != 0) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +/****************************************************************************/ +/* hacks to be cleaned up at some point - end */ +/****************************************************************************/ + +int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) +{ + return 0; +} + +void pdcp_layer_init(void) +{ + /* hack: be sure to initialize only once */ + static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; + static int initialized = 0; + if (pthread_mutex_lock(&m) != 0) abort(); + if (initialized) { + if (pthread_mutex_unlock(&m) != 0) abort(); + return; + } + initialized = 1; + if (pthread_mutex_unlock(&m) != 0) abort(); + + nr_pdcp_ue_manager = new_nr_pdcp_ue_manager(1); + init_nr_rlc_data_req_queue(); +} + +#include "nfapi/oai_integration/vendor_ext.h" +#include "targets/RT/USER/lte-softmodem.h" +#include "openair2/RRC/NAS/nas_config.h" + +uint64_t pdcp_module_init(uint64_t _pdcp_optmask) +{ + /* hack: be sure to initialize only once */ + static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; + static int initialized = 0; + if (pthread_mutex_lock(&m) != 0) abort(); + if (initialized) { + abort(); + } + initialized = 1; + if (pthread_mutex_unlock(&m) != 0) abort(); + +#if 0 + pdcp_optmask = _pdcp_optmask; + return pdcp_optmask; +#endif + /* temporary enforce netlink when UE_NAS_USE_TUN is set, + this is while switching from noS1 as build option + to noS1 as config option */ + if ( _pdcp_optmask & UE_NAS_USE_TUN_BIT) { + pdcp_optmask = pdcp_optmask | PDCP_USE_NETLINK_BIT ; + } + + pdcp_optmask = pdcp_optmask | _pdcp_optmask ; + LOG_I(PDCP, "pdcp init,%s %s\n", + ((LINK_ENB_PDCP_TO_GTPV1U)?"usegtp":""), + ((PDCP_USE_NETLINK)?"usenetlink":"")); + + if (PDCP_USE_NETLINK) { + nas_getparams(); + + if(UE_NAS_USE_TUN) { + int num_if = (NFAPI_MODE == NFAPI_UE_STUB_PNF || IS_SOFTMODEM_SIML1 )?MAX_NUMBER_NETIF:1; + netlink_init_tun("ue",num_if); + //Add --nr-ip-over-lte option check for next line + if (IS_SOFTMODEM_NOS1) + nas_config(1, 1, 2, "ue"); + LOG_I(PDCP, "UE pdcp will use tun interface\n"); + start_pdcp_tun_ue(); + } else if(ENB_NAS_USE_TUN) { + netlink_init_tun("enb",1); + nas_config(1, 1, 1, "enb"); + LOG_I(PDCP, "ENB pdcp will use tun interface\n"); + start_pdcp_tun_enb(); + } else { + LOG_I(PDCP, "pdcp will use kernel modules\n"); + abort(); + netlink_init(); + } + } + return pdcp_optmask ; +} + +static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, + char *buf, int size) +{ + extern int nas_sock_fd[]; + int len; + + len = write(nas_sock_fd[0], buf, size); + if (len != size) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +static void deliver_pdu_drb(void *_ue, nr_pdcp_entity_t *entity, + char *buf, int size, int sdu_id) +{ + nr_pdcp_ue_t *ue = _ue; + int rb_id; + protocol_ctxt_t ctxt; + int i; + mem_block_t *memblock; + + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(PDCP, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + +rb_found: + ctxt.module_id = 0; + ctxt.enb_flag = 1; + ctxt.instance = 0; + ctxt.frame = 0; + ctxt.subframe = 0; + ctxt.eNB_index = 0; + ctxt.configured = 1; + ctxt.brOption = 0; + + ctxt.rnti = ue->rnti; + + memblock = get_free_mem_block(size, __FUNCTION__); + memcpy(memblock->data, buf, size); + +printf("!!!!!!! deliver_pdu_drb (srb %d) calling rlc_data_req size %d: ", rb_id, size); +//for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)memblock->data[i]); +printf("\n"); + enqueue_rlc_data_req(&ctxt, 0, MBMS_FLAG_NO, rb_id, sdu_id, 0, size, memblock, NULL, NULL); +} + +boolean_t pdcp_data_ind( + const protocol_ctxt_t *const ctxt_pP, + const srb_flag_t srb_flagP, + const MBMS_flag_t MBMS_flagP, + const rb_id_t rb_id, + const sdu_size_t sdu_buffer_size, + mem_block_t *const sdu_buffer) +{ + nr_pdcp_ue_t *ue; + nr_pdcp_entity_t *rb; + int rnti = ctxt_pP->rnti; + + if (ctxt_pP->module_id != 0 || + //ctxt_pP->enb_flag != 1 || + ctxt_pP->instance != 0 || + ctxt_pP->eNB_index != 0 || + ctxt_pP->configured != 1 || + ctxt_pP->brOption != 0) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (ctxt_pP->enb_flag) + T(T_ENB_PDCP_UL, T_INT(ctxt_pP->module_id), T_INT(rnti), + T_INT(rb_id), T_INT(sdu_buffer_size)); + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti); + + if (srb_flagP == 1) { + if (rb_id < 1 || rb_id > 2) + rb = NULL; + else + rb = ue->srb[rb_id - 1]; + } else { + if (rb_id < 1 || rb_id > 5) + rb = NULL; + else + rb = ue->drb[rb_id - 1]; + } + + if (rb != NULL) { + rb->recv_pdu(rb, (char *)sdu_buffer->data, sdu_buffer_size); + } else { + LOG_E(PDCP, "%s:%d:%s: fatal: no RB found (rb_id %ld, srb_flag %d)\n", + __FILE__, __LINE__, __FUNCTION__, rb_id, srb_flagP); + exit(1); + } + + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + + free_mem_block(sdu_buffer, __FUNCTION__); + + return 1; +} + +void pdcp_run(const protocol_ctxt_t *const ctxt_pP) +{ + MessageDef *msg_p; + int result; + protocol_ctxt_t ctxt; + + while (1) { + itti_poll_msg(ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, &msg_p); + if (msg_p == NULL) + break; + switch (ITTI_MSG_ID(msg_p)) { + case RRC_DCCH_DATA_REQ: + PROTOCOL_CTXT_SET_BY_MODULE_ID( + &ctxt, + RRC_DCCH_DATA_REQ(msg_p).module_id, + RRC_DCCH_DATA_REQ(msg_p).enb_flag, + RRC_DCCH_DATA_REQ(msg_p).rnti, + RRC_DCCH_DATA_REQ(msg_p).frame, + 0, + RRC_DCCH_DATA_REQ(msg_p).eNB_index); + result = pdcp_data_req(&ctxt, + SRB_FLAG_YES, + RRC_DCCH_DATA_REQ(msg_p).rb_id, + RRC_DCCH_DATA_REQ(msg_p).muip, + RRC_DCCH_DATA_REQ(msg_p).confirmp, + RRC_DCCH_DATA_REQ(msg_p).sdu_size, + RRC_DCCH_DATA_REQ(msg_p).sdu_p, + RRC_DCCH_DATA_REQ(msg_p).mode, + NULL, NULL); + + if (result != TRUE) + LOG_E(PDCP, "PDCP data request failed!\n"); + result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), RRC_DCCH_DATA_REQ(msg_p).sdu_p); + AssertFatal(result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result); + break; + default: + LOG_E(PDCP, "Received unexpected message %s\n", ITTI_MSG_NAME(msg_p)); + break; + } + } +} + +static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) +{ + TODO; +} + +static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s) +{ + nr_pdcp_entity_t *pdcp_drb; + nr_pdcp_ue_t *ue; + + int drb_id = s->drb_Identity; + +printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id); + + if (drb_id != 1) { + LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id); + exit(1); + } + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti); + if (ue->drb[drb_id-1] != NULL) { + LOG_D(PDCP, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } else { + pdcp_drb = new_nr_pdcp_entity_drb_am(drb_id, deliver_sdu_drb, ue, deliver_pdu_drb, ue); + nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); + + LOG_D(PDCP, "%s:%d:%s: added drb %d to ue %d\n", + __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); + } + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + +static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) +{ + switch (s->rlc_Config->present) { + case LTE_RLC_Config_PR_am: + add_drb_am(rnti, s); + break; + case LTE_RLC_Config_PR_um_Bi_Directional: + //add_drb_um(rnti, s); + /* hack */ + add_drb_am(rnti, s); + break; + default: + LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +boolean_t rrc_pdcp_config_asn1_req( + const protocol_ctxt_t *const ctxt_pP, + LTE_SRB_ToAddModList_t *const srb2add_list, + LTE_DRB_ToAddModList_t *const drb2add_list, + LTE_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 +#endif + ,rb_id_t *const defaultDRB) +{ + int rnti = ctxt_pP->rnti; + int i; + + if (//ctxt_pP->enb_flag != 1 || + ctxt_pP->module_id != 0 || + ctxt_pP->instance != 0 || + ctxt_pP->eNB_index != 0 || + //ctxt_pP->configured != 2 || + //srb2add_list == NULL || + //drb2add_list != NULL || + drb2release_list != NULL || + security_modeP != 255 || + //kRRCenc != NULL || + //kRRCint != NULL || + //kUPenc != NULL || + pmch_InfoList_r9 != NULL /*|| + defaultDRB != NULL */) { + TODO; + } + + if (srb2add_list != NULL) { + for (i = 0; i < srb2add_list->list.count; i++) { + add_srb(rnti, srb2add_list->list.array[i]); + } + } + + if (drb2add_list != NULL) { + for (i = 0; i < drb2add_list->list.count; i++) { + add_drb(rnti, drb2add_list->list.array[i]); + } + } + + /* update security */ + if (kRRCint != NULL) { + /* todo */ + } + + free(kRRCenc); + free(kRRCint); + free(kUPenc); + + return 0; +} + +uint64_t get_pdcp_optmask(void) +{ + return pdcp_optmask; +} + +boolean_t pdcp_remove_UE( + const protocol_ctxt_t *const ctxt_pP) +{ + TODO; + return 1; +} + +void pdcp_config_set_security(const protocol_ctxt_t* const ctxt_pP, pdcp_t *pdcp_pP, rb_id_t rb_id, + uint16_t lc_idP, uint8_t security_modeP, uint8_t *kRRCenc_pP, uint8_t *kRRCint_pP, uint8_t *kUPenc_pP) +{ + TODO; +} + +static boolean_t pdcp_data_req_drb( + protocol_ctxt_t *ctxt_pP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer) +{ +printf("pdcp_data_req called size %d\n", sdu_buffer_size); + nr_pdcp_ue_t *ue; + nr_pdcp_entity_t *rb; + int rnti = ctxt_pP->rnti; + + if (ctxt_pP->module_id != 0 || + //ctxt_pP->enb_flag != 1 || + ctxt_pP->instance != 0 || + ctxt_pP->eNB_index != 0 /*|| + ctxt_pP->configured != 1 || + ctxt_pP->brOption != 0*/) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + + ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, rnti); + + if (rb_id < 1 || rb_id > 5) + rb = NULL; + else + rb = ue->drb[rb_id - 1]; + + if (rb == NULL) { + LOG_E(PDCP, "%s:%d:%s: fatal: no DRB found (rnti %d, rb_id %ld)\n", + __FILE__, __LINE__, __FUNCTION__, rnti, rb_id); + exit(1); + } + + rb->recv_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP); + + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + + return 1; +} + +boolean_t pdcp_data_req( + protocol_ctxt_t *ctxt_pP, + const srb_flag_t srb_flagP, + const rb_id_t rb_id, + const mui_t muiP, + const confirm_t confirmP, + const sdu_size_t sdu_buffer_size, + unsigned char *const sdu_buffer, + const pdcp_transmission_mode_t mode +#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0)) + ,const uint32_t *const sourceL2Id + ,const uint32_t *const destinationL2Id +#endif + ) +{ + if (srb_flagP) { TODO; } + return pdcp_data_req_drb(ctxt_pP, rb_id, muiP, confirmP, sdu_buffer_size, + sdu_buffer); +} + +void pdcp_set_pdcp_data_ind_func(pdcp_data_ind_func_t pdcp_data_ind) +{ + /* nothing to do */ +} + +void pdcp_set_rlc_data_req_func(send_rlc_data_req_func_t send_rlc_data_req) +{ + /* nothing to do */ +} + +//Dummy function needed due to LTE dependencies +void +pdcp_mbms_run ( const protocol_ctxt_t *const ctxt_pP){ + /* nothing to do */ +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c new file mode 100644 index 0000000000..ca51da3d5f --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.c @@ -0,0 +1,198 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#include "nr_pdcp_ue_manager.h" + +#include +#include +#include + +#include "LOG/log.h" + +typedef struct { + pthread_mutex_t lock; + nr_pdcp_ue_t **ue_list; + int ue_count; + int enb_flag; +} nr_pdcp_ue_manager_internal_t; + +nr_pdcp_ue_manager_t *new_nr_pdcp_ue_manager(int enb_flag) +{ + nr_pdcp_ue_manager_internal_t *ret; + + ret = calloc(1, sizeof(nr_pdcp_ue_manager_internal_t)); + if (ret == NULL) { + LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (pthread_mutex_init(&ret->lock, NULL)) abort(); + ret->enb_flag = enb_flag; + + return ret; +} + +int nr_pdcp_manager_get_enb_flag(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + return m->enb_flag; +} + +void nr_pdcp_manager_lock(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + if (pthread_mutex_lock(&m->lock)) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + if (pthread_mutex_unlock(&m->lock)) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +/* must be called with lock acquired */ +nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *_m, int rnti) +{ + /* TODO: optimze */ + nr_pdcp_ue_manager_internal_t *m = _m; + int i; + + for (i = 0; i < m->ue_count; i++) + if (m->ue_list[i]->rnti == rnti) + return m->ue_list[i]; + + LOG_D(PDCP, "%s:%d:%s: new UE %d\n", __FILE__, __LINE__, __FUNCTION__, rnti); + + m->ue_count++; + m->ue_list = realloc(m->ue_list, sizeof(nr_pdcp_ue_t *) * m->ue_count); + if (m->ue_list == NULL) { + LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + m->ue_list[m->ue_count-1] = calloc(1, sizeof(nr_pdcp_ue_t)); + if (m->ue_list[m->ue_count-1] == NULL) { + LOG_E(PDCP, "%s:%d:%s: out of memory\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + m->ue_list[m->ue_count-1]->rnti = rnti; + + return m->ue_list[m->ue_count-1]; +} + +/* must be called with lock acquired */ +void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *_m, int rnti) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + nr_pdcp_ue_t *ue; + int i; + int j; + + for (i = 0; i < m->ue_count; i++) + if (m->ue_list[i]->rnti == rnti) + break; + + if (i == m->ue_count) { + LOG_D(PDCP, "%s:%d:%s: warning: ue %d not found\n", + __FILE__, __LINE__, __FUNCTION__, + rnti); + return; + } + + ue = m->ue_list[i]; + + for (j = 0; j < 2; j++) + if (ue->srb[j] != NULL) + ue->srb[j]->delete(ue->srb[j]); + + for (j = 0; j < 5; j++) + if (ue->drb[j] != NULL) + ue->drb[j]->delete(ue->drb[j]); + + free(ue); + + m->ue_count--; + if (m->ue_count == 0) { + free(m->ue_list); + m->ue_list = NULL; + return; + } + + memmove(&m->ue_list[i], &m->ue_list[i+1], + (m->ue_count - i) * sizeof(nr_pdcp_ue_t *)); + m->ue_list = realloc(m->ue_list, m->ue_count * sizeof(nr_pdcp_ue_t *)); + if (m->ue_list == NULL) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } +} + +/* must be called with lock acquired */ +void nr_pdcp_ue_add_srb_pdcp_entity(nr_pdcp_ue_t *ue, int srb_id, nr_pdcp_entity_t *entity) +{ + if (srb_id < 1 || srb_id > 2) { + LOG_E(PDCP, "%s:%d:%s: fatal, bad srb id\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + srb_id--; + + if (ue->srb[srb_id] != NULL) { + LOG_E(PDCP, "%s:%d:%s: fatal, srb already present\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ue->srb[srb_id] = entity; +} + +/* must be called with lock acquired */ +void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, nr_pdcp_entity_t *entity) +{ + if (drb_id < 1 || drb_id > 5) { + LOG_E(PDCP, "%s:%d:%s: fatal, bad drb id\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + drb_id--; + + if (ue->drb[drb_id] != NULL) { + LOG_E(PDCP, "%s:%d:%s: fatal, drb already present\n", + __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + ue->drb[drb_id] = entity; +} + +int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *_m) +{ + nr_pdcp_ue_manager_internal_t *m = _m; + if (m->ue_count == 0) + return -1; + return m->ue_list[0]->rnti; +} diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h new file mode 100644 index 0000000000..0de2f024b3 --- /dev/null +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_ue_manager.h @@ -0,0 +1,65 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +#ifndef _NR_PDCP_UE_MANAGER_H_ +#define _NR_PDCP_UE_MANAGER_H_ + +#include "nr_pdcp_entity.h" + +typedef void nr_pdcp_ue_manager_t; + +typedef struct nr_pdcp_ue_t { + int rnti; + nr_pdcp_entity_t *srb[2]; + nr_pdcp_entity_t *drb[5]; +} nr_pdcp_ue_t; + +/***********************************************************************/ +/* manager functions */ +/***********************************************************************/ + +nr_pdcp_ue_manager_t *new_nr_pdcp_ue_manager(int enb_flag); + +int nr_pdcp_manager_get_enb_flag(nr_pdcp_ue_manager_t *m); + +void nr_pdcp_manager_lock(nr_pdcp_ue_manager_t *m); +void nr_pdcp_manager_unlock(nr_pdcp_ue_manager_t *m); + +nr_pdcp_ue_t *nr_pdcp_manager_get_ue(nr_pdcp_ue_manager_t *m, int rnti); +void nr_pdcp_manager_remove_ue(nr_pdcp_ue_manager_t *m, int rnti); + +/***********************************************************************/ +/* ue functions */ +/***********************************************************************/ + +void nr_pdcp_ue_add_srb_pdcp_entity(nr_pdcp_ue_t *ue, int srb_id, + nr_pdcp_entity_t *entity); +void nr_pdcp_ue_add_drb_pdcp_entity(nr_pdcp_ue_t *ue, int drb_id, + nr_pdcp_entity_t *entity); + +/***********************************************************************/ +/* hacks */ +/***********************************************************************/ + +/* returns -1 if no UE */ +int nr_pdcp_get_first_rnti(nr_pdcp_ue_manager_t *m); + +#endif /* _NR_PDCP_UE_MANAGER_H_ */ From eb51e39f39b6cbce444874ea03e9b6c3cf5b7f7f Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 4 May 2020 17:48:18 +0200 Subject: [PATCH 002/171] Introduce NR RRC->PDCP configuration -Create nr_rrc_pdcp_config_asn1_req function -Update PDCP DRB addition functions with NR structures instead of LTE --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 73 +++++++++++++++++++++-- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 62f71475be..44b493b807 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -631,7 +631,7 @@ static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) TODO; } -static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s) +static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -661,13 +661,13 @@ printf("\n\n################# rnti %d add drb %d\n\n\n", rnti, drb_id); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) +static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config) { - switch (s->rlc_Config->present) { - case LTE_RLC_Config_PR_am: + switch (rlc_Config->present) { + case NR_RLC_Config_PR_am: add_drb_am(rnti, s); break; - case LTE_RLC_Config_PR_um_Bi_Directional: + case NR_RLC_Config_PR_um_Bi_Directional: //add_drb_um(rnti, s); /* hack */ add_drb_am(rnti, s); @@ -679,6 +679,67 @@ static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) } } +boolean_t nr_rrc_pdcp_config_asn1_req( + const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc +#if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 +#endif + ,rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) + //struct NR_RLC_Config *rlc_Config) +{ + int rnti = ctxt_pP->rnti; + int i; + + if (//ctxt_pP->enb_flag != 1 || + ctxt_pP->module_id != 0 || + ctxt_pP->instance != 0 || + ctxt_pP->eNB_index != 0 || + //ctxt_pP->configured != 2 || + //srb2add_list == NULL || + //drb2add_list != NULL || + drb2release_list != NULL || + security_modeP != 255 || + //kRRCenc != NULL || + //kRRCint != NULL || + //kUPenc != NULL || + pmch_InfoList_r9 != NULL /*|| + defaultDRB != NULL */) { + TODO; + } + + if (srb2add_list != NULL) { + for (i = 0; i < srb2add_list->list.count; i++) { + add_srb(rnti, srb2add_list->list.array[i]); + } + } + + if (drb2add_list != NULL) { + for (i = 0; i < drb2add_list->list.count; i++) { + LOG_I(PDCP, "Before calling add_drb \n"); + add_drb(rnti, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config); + } + } + + /* update security */ + if (kRRCint != NULL) { + /* todo */ + } + + free(kRRCenc); + free(kRRCint); + free(kUPenc); + + return 0; +} + boolean_t rrc_pdcp_config_asn1_req( const protocol_ctxt_t *const ctxt_pP, LTE_SRB_ToAddModList_t *const srb2add_list, @@ -721,7 +782,7 @@ boolean_t rrc_pdcp_config_asn1_req( if (drb2add_list != NULL) { for (i = 0; i < drb2add_list->list.count; i++) { - add_drb(rnti, drb2add_list->list.array[i]); + add_drb(rnti, drb2add_list->list.array[i], NULL); } } From 017a6ef1412e94b691b7fa65e5e258013bbf1a37 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 4 May 2020 17:58:36 +0200 Subject: [PATCH 003/171] Introduce NR RRC->RLC configuration -Create nr_rrc_rlc_config_asn1_req function -Update RLC DRB addition functions with NR structures instead of LTE --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 95 +++++++++++++++++++------ 1 file changed, 73 insertions(+), 22 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 88bde65107..15b1b2133a 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -27,6 +27,13 @@ #include "asn1_utils.h" #include "nr_rlc_ue_manager.h" #include "nr_rlc_entity.h" +#include "NR_RLC-BearerConfig.h" +#include "NR_DRB-ToAddMod.h" +#include "NR_DRB-ToAddModList.h" +#include "NR_SRB-ToAddModList.h" +#include "NR_DRB-ToReleaseList.h" +#include "NR_CellGroupConfig.h" +#include "NR_RLC-Config.h" #include @@ -636,15 +643,15 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod * nr_rlc_manager_unlock(nr_rlc_ue_manager); } -static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s) +static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_t *rlc_BearerConfig) { nr_rlc_entity_t *nr_rlc_am; nr_rlc_ue_t *ue; - struct LTE_RLC_Config *r = s->rlc_Config; - struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig; + struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config; + struct NR_LogicalChannelConfig *l = rlc_BearerConfig->mac_LogicalChannelConfig; int drb_id = s->drb_Identity; - int channel_id = *s->logicalChannelIdentity; + int channel_id = rlc_BearerConfig->logicalChannelIdentity; int logical_channel_group; //int t_reordering; @@ -677,9 +684,9 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s) } switch (r->present) { - case LTE_RLC_Config_PR_am: { - struct LTE_RLC_Config__am *am; - am = &r->choice.am; + case NR_RLC_Config_PR_am: { + struct NR_RLC_Config__am *am; + am = r->choice.am; //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering); t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); @@ -724,15 +731,15 @@ static void add_drb_am(int rnti, struct LTE_DRB_ToAddMod *s) nr_rlc_manager_unlock(nr_rlc_ue_manager); } -static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s) +static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_t *rlc_BearerConfig) { nr_rlc_entity_t *nr_rlc_um; nr_rlc_ue_t *ue; - struct LTE_RLC_Config *r = s->rlc_Config; - struct LTE_LogicalChannelConfig *l = s->logicalChannelConfig; + struct NR_RLC_Config *r = rlc_BearerConfig->rlc_Config; + struct NR_LogicalChannelConfig *l = rlc_BearerConfig->mac_LogicalChannelConfig; int drb_id = s->drb_Identity; - int channel_id = *s->logicalChannelIdentity; + int channel_id = rlc_BearerConfig->logicalChannelIdentity; int logical_channel_group; //int t_reordering; @@ -760,15 +767,15 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s) } switch (r->present) { - case LTE_RLC_Config_PR_um_Bi_Directional: { - struct LTE_RLC_Config__um_Bi_Directional *um; - um = &r->choice.um_Bi_Directional; + case NR_RLC_Config_PR_um_Bi_Directional: { + struct NR_RLC_Config__um_Bi_Directional *um; + um = r->choice.um_Bi_Directional; //t_reordering = decode_t_reordering(um->dl_UM_RLC.t_Reordering); if (um->dl_UM_RLC.sn_FieldLength != um->ul_UM_RLC.sn_FieldLength) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - sn_field_length = decode_sn_field_length(um->dl_UM_RLC.sn_FieldLength); + sn_field_length = decode_sn_field_length(*um->dl_UM_RLC.sn_FieldLength); break; } default: @@ -798,14 +805,14 @@ static void add_drb_um(int rnti, struct LTE_DRB_ToAddMod *s) nr_rlc_manager_unlock(nr_rlc_ue_manager); } -__attribute__ ((unused)) static void add_drb(int rnti, struct LTE_DRB_ToAddMod *s) +__attribute__ ((unused)) static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, struct NR_RLC_BearerConfig *rlc_BearerConfig) { - switch (s->rlc_Config->present) { - case LTE_RLC_Config_PR_am: - add_drb_am(rnti, s); + switch (rlc_BearerConfig->rlc_Config->present) { + case NR_RLC_Config_PR_am: + add_drb_am(rnti, s, rlc_BearerConfig); break; - case LTE_RLC_Config_PR_um_Bi_Directional: - add_drb_um(rnti, s); + case NR_RLC_Config_PR_um_Bi_Directional: + add_drb_um(rnti, s, rlc_BearerConfig); break; default: LOG_E(RLC, "%s:%d:%s: fatal: unhandled DRB type\n", @@ -853,7 +860,7 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP if (drb2add_listP != NULL) { for (i = 0; i < drb2add_listP->list.count; i++) { - add_drb(rnti, drb2add_listP->list.array[i]); + add_drb(rnti, drb2add_listP->list.array[i], NULL); } } @@ -861,6 +868,50 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP } //#endif +rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, + const NR_SRB_ToAddModList_t * const srb2add_listP, + const NR_DRB_ToAddModList_t * const drb2add_listP, + const NR_DRB_ToReleaseList_t * const drb2release_listP, + const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, + NR_CellGroupConfig_t *SCell_GroupConfig) +{ + int rnti = ctxt_pP->rnti; + int i; + + if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*|| + ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 || + ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) { + LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %d %d %d %d)\n", __FUNCTION__, + ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance, + ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption); + exit(1); + } + + if (pmch_InfoList_r9_pP != NULL) { + LOG_E(RLC, "%s: pmch_InfoList_r9_pP not handled\n", __FUNCTION__); + exit(1); + } + + if (drb2release_listP != NULL) { + LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + if (srb2add_listP != NULL) { + for (i = 0; i < srb2add_listP->list.count; i++) { + add_srb(rnti, srb2add_listP->list.array[i]); + } + } + + if (drb2add_listP != NULL) { + for (i = 0; i < drb2add_listP->list.count; i++) { + add_drb(rnti, drb2add_listP->list.array[i], SCell_GroupConfig->rlc_BearerToAddModList->list.array[i]); + } + } + + return RLC_OP_STATUS_OK; +} + //#if 0 rlc_op_status_t rrc_rlc_config_req ( const protocol_ctxt_t* const ctxt_pP, From 632ef048c82b0cc3d75f3757e0e275635911f7b3 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 4 May 2020 18:12:20 +0200 Subject: [PATCH 004/171] Introduce triggering of PDCP and RLC configuration for the list of added DRBs -Upon reception of SgNB Addition Request from the eNB, the gNB configures pdcp and rlc entities for the list of DRBs provided from the eNB --- openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c | 5 ++- openair2/RRC/NR/nr_rrc_proto.h | 2 +- openair2/RRC/NR/rrc_gNB_nsa.c | 51 ++++++++++++++++++++++- openair2/RRC/NR/rrc_gNB_reconfig.c | 8 ++-- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c index 8f3d49d8c2..0c8526c2f0 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_entity_am.c @@ -109,7 +109,8 @@ static void consider_retransmission(nr_rlc_entity_am_t *entity, * upper layers should deal with this condition, internally it's better * for the RLC code to keep going with this segment (we only remove * a segment that was ACKed) - */ + */ + LOG_D(RLC, "RLC segment to be added at the ReTx list \n"); nr_rlc_sdu_segment_list_append(&entity->retransmit_list, &entity->retransmit_end, cur); @@ -1588,6 +1589,8 @@ void nr_rlc_entity_am_recv_sdu(nr_rlc_entity_t *_entity, sdu = nr_rlc_new_sdu(buffer, size, sdu_id); + LOG_I(RLC, "Created new RLC SDU and append it to the RLC list \n"); + nr_rlc_sdu_segment_list_append(&entity->tx_list, &entity->tx_end, sdu); } diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index fd766f7e12..cb23b6d5e6 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -82,7 +82,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon int n_physical_antenna_ports, int initial_csi_index); -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig); +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, long eps_BearerIdentity, long drb_Identity); int generate_CG_Config(gNB_RRC_INST *rrc, NR_CG_Config_t *cg_Config, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index afd5404d29..5740a9cc7b 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -36,9 +36,32 @@ //#include "NR_UE-CapabilityRAT-ContainerList.h" #include "LTE_UE-CapabilityRAT-ContainerList.h" #include "NR_CG-Config.h" +//#include "NR_SRB-ToAddModList.h" #include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h" #include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h" +extern boolean_t nr_rrc_pdcp_config_asn1_req( + const protocol_ctxt_t *const ctxt_pP, + NR_SRB_ToAddModList_t *const srb2add_list, + NR_DRB_ToAddModList_t *const drb2add_list, + NR_DRB_ToReleaseList_t *const drb2release_list, + const uint8_t security_modeP, + uint8_t *const kRRCenc, + uint8_t *const kRRCint, + uint8_t *const kUPenc + #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0)) + ,LTE_PMCH_InfoList_r9_t *pmch_InfoList_r9 + #endif + ,rb_id_t *const defaultDRB, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + +extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, + const NR_SRB_ToAddModList_t * const srb2add_listP, + const NR_DRB_ToAddModList_t * const drb2add_listP, + const NR_DRB_ToReleaseList_t * const drb2release_listP, + const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + void rrc_parse_ue_capabilities(gNB_RRC_INST *rrc, LTE_UE_CapabilityRAT_ContainerList_t *UE_CapabilityRAT_ContainerList, x2ap_ENDC_sgnb_addition_req_t *m) { struct rrc_gNB_ue_context_s *ue_context_p = NULL; @@ -132,8 +155,13 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ carrier->initial_csi_index[rrc->Nb_ue]); ue_context_p->ue_context.rb_config = calloc(1,sizeof(NR_RRCReconfiguration_t)); + //NR_CellGroupConfig_t *secondaryCellGroup = ue_context_p->ue_context.secondaryCellGroup; + //secondaryCellGroup->rlc_BearerToAddModList->list.array[0]->rlc_Config - fill_default_rbconfig(ue_context_p->ue_context.rb_config); + if(m!=NULL) + fill_default_rbconfig(ue_context_p->ue_context.rb_config, m->e_rabs_tobeadded[0].e_rab_id, m->e_rabs_tobeadded[0].drb_ID); + else + fill_default_rbconfig(ue_context_p->ue_context.rb_config, 5, 1); ue_context_p->ue_id_rnti = ue_context_p->ue_context.secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void*)CG_Config,0,sizeof(*CG_Config)); @@ -232,6 +260,27 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ 1, // add_ue flag ue_context_p->ue_id_rnti, ue_context_p->ue_context.secondaryCellGroup); + + nr_rrc_pdcp_config_asn1_req( + &ctxt, + (NR_SRB_ToAddModList_t *) NULL, + ue_context_p->ue_context.rb_config->drb_ToAddModList , + ue_context_p->ue_context.rb_config->drb_ToReleaseList, + 0xff, + NULL, + NULL, + NULL, + NULL, + NULL, + ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); + + nr_rrc_rlc_config_asn1_req (&ctxt, + (NR_SRB_ToAddModList_t *) NULL, + ue_context_p->ue_context.rb_config->drb_ToAddModList, + ue_context_p->ue_context.rb_config->drb_ToReleaseList, + (LTE_PMCH_InfoList_r9_t *) NULL, + ue_context_p->ue_context.secondaryCellGroup); + } diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index f732529ed7..1423505daf 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -62,7 +62,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); - RLC_BearerConfig->logicalChannelIdentity = 4; + RLC_BearerConfig->logicalChannelIdentity = 3; RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer)); RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; @@ -2046,7 +2046,7 @@ void fill_default_reconfig(NR_ServingCellConfigCommon_t *servingcellconfigcommon reconfig->nonCriticalExtension = NULL; } -void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { +void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig, long eps_BearerIdentity, long drb_Identity) { rbconfig->srb_ToAddModList = NULL; rbconfig->srb3_ToRelease = NULL; @@ -2054,8 +2054,8 @@ void fill_default_rbconfig(NR_RadioBearerConfig_t *rbconfig) { NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity=5; - drb_ToAddMod->drb_Identity = 1; + drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= eps_BearerIdentity; //5; + drb_ToAddMod->drb_Identity = drb_Identity; drb_ToAddMod->reestablishPDCP = NULL; drb_ToAddMod->recoverPDCP = NULL; drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); From bd1c4dd00be61b464e4acce124a2376cad71d393 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 5 May 2020 20:30:19 +0200 Subject: [PATCH 005/171] Add default NR RLC UM bearer configuration --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 2 +- openair2/RRC/NR/rrc_gNB_reconfig.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 15b1b2133a..1201bf5a78 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -771,7 +771,7 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ struct NR_RLC_Config__um_Bi_Directional *um; um = r->choice.um_Bi_Directional; //t_reordering = decode_t_reordering(um->dl_UM_RLC.t_Reordering); - if (um->dl_UM_RLC.sn_FieldLength != um->ul_UM_RLC.sn_FieldLength) { + if (*um->dl_UM_RLC.sn_FieldLength != *um->ul_UM_RLC.sn_FieldLength) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 1423505daf..722281ef31 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -70,6 +70,18 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC)); *RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true; RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config)); + + // RLC UM Bi-directional Bearer configuration + /*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional; + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional)); + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); + *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; + + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength)); + *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15;*/ + + // RLC AM Bearer configuration RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am; RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am)); RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); From 06d4ef6177bb80d109ae2407fadb9d72562454dd Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Tue, 12 May 2020 14:58:44 +0200 Subject: [PATCH 006/171] Modification of an input parameter type for nr_rrc_rlc_config_asn1_req --- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 4 ++-- openair2/RRC/NR/rrc_gNB_nsa.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 1201bf5a78..6564fc897b 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -873,7 +873,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt const NR_DRB_ToAddModList_t * const drb2add_listP, const NR_DRB_ToReleaseList_t * const drb2release_listP, const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, - NR_CellGroupConfig_t *SCell_GroupConfig) + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) { int rnti = ctxt_pP->rnti; int i; @@ -905,7 +905,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt if (drb2add_listP != NULL) { for (i = 0; i < drb2add_listP->list.count; i++) { - add_drb(rnti, drb2add_listP->list.array[i], SCell_GroupConfig->rlc_BearerToAddModList->list.array[i]); + add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[i]); } } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 5740a9cc7b..b267ddc6ec 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -279,7 +279,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ue_context_p->ue_context.rb_config->drb_ToAddModList, ue_context_p->ue_context.rb_config->drb_ToReleaseList, (LTE_PMCH_InfoList_r9_t *) NULL, - ue_context_p->ue_context.secondaryCellGroup); + ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); } From 9e8e9c8ff0535f6b50c821d284d66fa4d27d395d Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 19 May 2020 14:57:38 +0200 Subject: [PATCH 007/171] noS1: Introduce NR DRB preconfiguration and PDCP RLC configuration triggering --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 228 +++++++++++++--------- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 5 +- openair2/RRC/NR/rrc_gNB_nsa.c | 2 +- 3 files changed, 136 insertions(+), 99 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 44b493b807..613ef1026f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -20,6 +20,10 @@ */ #include "nr_pdcp_ue_manager.h" +#include "NR_RadioBearerConfig.h" +#include "NR_RLC-BearerConfig.h" +#include "NR_CellGroupConfig.h" +#include "openair2/RRC/NR/nr_rrc_proto.h" /* from OAI */ #include "pdcp.h" @@ -77,6 +81,13 @@ typedef struct { static rlc_data_req_queue q; +extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, + const NR_SRB_ToAddModList_t * const srb2add_listP, + const NR_DRB_ToAddModList_t * const drb2add_listP, + const NR_DRB_ToReleaseList_t * const drb2release_listP, + const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list); + static void *rlc_data_req_thread(void *_) { int i; @@ -170,102 +181,6 @@ static void enqueue_rlc_data_req(const protocol_ctxt_t *const ctxt_pP, #include "LAYER2/MAC/mac_extern.h" -void nr_ip_over_LTE_DRB_preconfiguration(void) -{ - // Addition for the use-case of 4G stack on top of 5G-NR. - // We need to configure pdcp and rlc instances without having an actual - // UE RRC Connection. In order to be able to test the NR PHY with some injected traffic - // on top of the LTE stack. - protocol_ctxt_t ctxt; - LTE_DRB_ToAddModList_t* DRB_configList=NULL; - DRB_configList = CALLOC(1, sizeof(LTE_DRB_ToAddModList_t)); - struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; - struct LTE_RLC_Config *DRB_rlc_config = NULL; - struct LTE_PDCP_Config *DRB_pdcp_config = NULL; - struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; - - struct LTE_DRB_ToAddMod *DRB_config = NULL; - struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; - long *logicalchannelgroup_drb; - - - //Static preconfiguration of DRB - DRB_config = CALLOC(1, sizeof(*DRB_config)); - - DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); - // allowed value 5..15, value : x+4 - *(DRB_config->eps_BearerIdentity) = 1; //ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation - // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; - // 1 + drb_identiy_index; - DRB_config->drb_Identity = 1; - DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); - *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - - DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); - DRB_config->rlc_Config = DRB_rlc_config; - - DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); - DRB_config->pdcp_Config = DRB_pdcp_config; - DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; - DRB_pdcp_config->rlc_AM = NULL; - DRB_pdcp_config->rlc_UM = NULL; - - DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; - DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; - // PDCP - PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); - DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; - PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; - - DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; - - DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); - DRB_config->logicalChannelConfig = DRB_lchan_config; - DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); - DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; - - DRB_ul_SpecificParameters->priority= 4; - - DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; - //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - DRB_ul_SpecificParameters->bucketSizeDuration = - LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - - logicalchannelgroup_drb = CALLOC(1, sizeof(long)); - *logicalchannelgroup_drb = 1;//(i+1) % 3; - DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - - ASN_SEQUENCE_ADD(&DRB_configList->list,DRB_config); - - if (ENB_NAS_USE_TUN){ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0); - } - else{ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); - } - - rrc_pdcp_config_asn1_req(&ctxt, - (LTE_SRB_ToAddModList_t *) NULL, - DRB_configList, - (LTE_DRB_ToReleaseList_t *) NULL, - 0xff, NULL, NULL, NULL - , (LTE_PMCH_InfoList_r9_t *) NULL, - &DRB_config->drb_Identity); - - rrc_rlc_config_asn1_req(&ctxt, - (LTE_SRB_ToAddModList_t*)NULL, - DRB_configList, - (LTE_DRB_ToReleaseList_t*)NULL - //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - ,(LTE_PMCH_InfoList_r9_t *)NULL - , 0, 0 - //#endif - ); -} - static void reblock_tun_socket(void) { extern int nas_sock_fd[]; @@ -798,6 +713,127 @@ boolean_t rrc_pdcp_config_asn1_req( return 0; } +void nr_ip_over_LTE_DRB_preconfiguration(void) +{ + + NR_RadioBearerConfig_t *rbconfig = NULL; + struct NR_CellGroupConfig__rlc_BearerToAddModList *Rlc_Bearer_ToAdd_list = NULL; + protocol_ctxt_t ctxt; + //fill_default_rbconfig(rb_config, 5, 1); + rbconfig = calloc(1, sizeof(*rbconfig)); + + rbconfig->srb_ToAddModList = NULL; + rbconfig->srb3_ToRelease = NULL; + rbconfig->drb_ToAddModList = calloc(1,sizeof(*rbconfig->drb_ToAddModList)); + NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); + drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); + drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; + drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5; + drb_ToAddMod->drb_Identity = 1; + drb_ToAddMod->reestablishPDCP = NULL; + drb_ToAddMod->recoverPDCP = NULL; + drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); + drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb)); + drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer)); + *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30; + drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL)); + *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; + drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL)); + *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; + drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0; + + drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL; + drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL; + drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL; + drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL; + + drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering)); + *drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0; + drb_ToAddMod->pdcp_Config->ext1 = NULL; + + ASN_SEQUENCE_ADD(&rbconfig->drb_ToAddModList->list,drb_ToAddMod); + + rbconfig->drb_ToReleaseList = NULL; + + rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); + rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); + rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; + rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); + *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; + + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); + + + NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); + + RLC_BearerConfig->logicalChannelIdentity = 3; + RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer)); + RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; + + RLC_BearerConfig->servedRadioBearer->choice.drb_Identity=1; + RLC_BearerConfig->reestablishRLC=calloc(1,sizeof(*RLC_BearerConfig->reestablishRLC)); + *RLC_BearerConfig->reestablishRLC=NR_RLC_BearerConfig__reestablishRLC_true; + RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config)); + + // RLC UM Bi-directional Bearer configuration + RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional; + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional)); + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); + *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; + + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength)); + *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15; + + RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig)); + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters)); + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->prioritisedBitRate = NR_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bucketSizeDuration = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedServingCells = NULL; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->allowedSCS_List = NULL; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->maxPUSCH_Duration = NULL; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->configuredGrantType1Allowed = NULL; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup)); + *RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelGroup = 1; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->schedulingRequestID = NULL; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_Mask = false; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->logicalChannelSR_DelayTimerApplied = false; + RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->bitRateQueryProhibitTimer = NULL; + + Rlc_Bearer_ToAdd_list = calloc(1,sizeof(*Rlc_Bearer_ToAdd_list)); + ASN_SEQUENCE_ADD(&Rlc_Bearer_ToAdd_list->list, RLC_BearerConfig); + + if (ENB_NAS_USE_TUN){ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0); + } + else{ + PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); + } + + nr_rrc_pdcp_config_asn1_req( + &ctxt, + (NR_SRB_ToAddModList_t *) NULL, + rbconfig->drb_ToAddModList , + rbconfig->drb_ToReleaseList, + 0xff, + NULL, + NULL, + NULL, + NULL, + NULL, + Rlc_Bearer_ToAdd_list); + + nr_rrc_rlc_config_asn1_req (&ctxt, + (NR_SRB_ToAddModList_t *) NULL, + rbconfig->drb_ToAddModList, + rbconfig->drb_ToReleaseList, + (LTE_PMCH_InfoList_r9_t *) NULL, + Rlc_Bearer_ToAdd_list); +} + uint64_t get_pdcp_optmask(void) { return pdcp_optmask; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 1201bf5a78..5a21611f5b 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -873,7 +873,8 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt const NR_DRB_ToAddModList_t * const drb2add_listP, const NR_DRB_ToReleaseList_t * const drb2release_listP, const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, - NR_CellGroupConfig_t *SCell_GroupConfig) + struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list) + //NR_CellGroupConfig_t *SCell_GroupConfig) { int rnti = ctxt_pP->rnti; int i; @@ -905,7 +906,7 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt if (drb2add_listP != NULL) { for (i = 0; i < drb2add_listP->list.count; i++) { - add_drb(rnti, drb2add_listP->list.array[i], SCell_GroupConfig->rlc_BearerToAddModList->list.array[i]); + add_drb(rnti, drb2add_listP->list.array[i], rlc_bearer2add_list->list.array[i]); } } diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index 5740a9cc7b..b267ddc6ec 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -279,7 +279,7 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_ ue_context_p->ue_context.rb_config->drb_ToAddModList, ue_context_p->ue_context.rb_config->drb_ToReleaseList, (LTE_PMCH_InfoList_r9_t *) NULL, - ue_context_p->ue_context.secondaryCellGroup); + ue_context_p->ue_context.secondaryCellGroup->rlc_BearerToAddModList); } From c2e65b06392922537d42be49be16b747ea476bdc Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 19 May 2020 15:08:02 +0200 Subject: [PATCH 008/171] Correct pseudo-subheader byte of random ULSCH PDU (phytest) to an appropriate value --- openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c | 6 +++--- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c index c74bc16754..f7e5737a9f 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_ulsch_decoding.c @@ -714,11 +714,11 @@ uint32_t nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB, } #ifdef DEBUG_ULSCH_DECODING - LOG_I(PHY, "Decoder output (payload): \n"); - for (i = 0; i < harq_process->TBS / 8; i++) { + LOG_I(PHY, "Decoder output (payload, TBS: %d): \n", harq_process->TBS); + for (i = 0; i < harq_process->TBS; i++) { //harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf("a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - printf("0x%02x",harq_process->b[i]); + printf("%02x",harq_process->b[i]); } #endif diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 769cea37a1..fc02cb989e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -193,15 +193,14 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, if (!IS_SOFTMODEM_NOS1 || !data_existing) { //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid //and block this traffic from being forwarded to the upper layers at the gNB - uint16_t payload_offset = 5; LOG_D(PHY, "Random data to be tranmsitted: \n"); - //Give the header bytes a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to block the random packet at the MAC layer of the receiver - for (i = 0; ia[i] = 64; + //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) + //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should + //have a valid LCID (nr_process_mac_pdu function) + harq_process_ul_ue->a[0] = 0x31; - for (i = payload_offset; i < harq_process_ul_ue->TBS / 8; i++) { + for (i = 1; i < harq_process_ul_ue->TBS / 8; i++) { harq_process_ul_ue->a[i] = (unsigned char) rand(); //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); } From 0c287d9f516b8be8beb339bc16dfede25774cf5f Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 19 May 2020 15:23:12 +0200 Subject: [PATCH 009/171] Adaptation at DLSCH scheduling function to support EPC mode --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 4 ++-- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 10 ++++------ 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index 9903544612..e1c8e6fac0 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -262,8 +262,8 @@ typedef struct { #define UL_SCH_LCID_CCCH 0x00 #define UL_SCH_LCID_SRB1 0x01 #define UL_SCH_LCID_SRB2 0x02 -#define UL_SCH_LCID_SRB3 0x03 -#define UL_SCH_LCID_DTCH 0x04 +#define UL_SCH_LCID_DTCH 0x03 +#define UL_SCH_LCID_SRB3 0x04 #define UL_SCH_LCID_CCCH_MSG3 0x21 #define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 #define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 4751fb1237..3cf9c486b1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -482,7 +482,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, } //is_nr_DL_slot - if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) { + if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) { if (get_softmodem_params()->phy_test == 0) { schedule_nr_prach(module_idP, (frame_rxP+1)&1023, slot_rxP); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 9255d633f8..8b4275b763 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -539,8 +539,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, NR_sched_pucch *pucch_sched, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){ - LOG_I(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP); - int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; int lcid, offset, i, header_length_last, TBS_bytes; int UE_id = 0, CC_id = 0; @@ -577,9 +575,9 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (TBS_bytes == 0) return; - //The --NOS1 use case currently schedules DLSCH transmissions only when there is IP traffic arriving - //through the LTE stack - if (IS_SOFTMODEM_NOS1){ + //Corresponding to noS1 and EPC_MODE_ENABLED use cases where DLSCH transmissions are scheduled only when there is IP traffic + //at the upper layers + if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test == 0){ for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { @@ -635,7 +633,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } } - } //if (IS_SOFTMODEM_NOS1) + } //if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test) else { //When the --NOS1 option is not enabled, DLSCH transmissions with random data From 58bc9e5395ef02c9a04331e7009a5bdc681a938f Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 19 May 2020 15:27:08 +0200 Subject: [PATCH 010/171] Fix ULSCH slot scheduling mismatch between gNB and OAI UE --- executables/nr-ue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 514d5f0239..236ff2dad2 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -374,7 +374,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { nr_scheduled_response_t scheduled_response; // program PUSCH. this should actually be done by the MAC upon reception of an UL DCI - if (proc->nr_tti_tx == 8 || proc->nr_tti_tx == 19 || UE->frame_parms.frame_type == FDD){ + if (proc->nr_tti_tx == 8 || UE->frame_parms.frame_type == FDD){ //proc->nr_tti_tx == 19 || mod_id = UE->Mod_id; @@ -403,7 +403,7 @@ void processSlotTX( PHY_VARS_NR_UE *UE, UE_nr_rxtx_proc_t *proc) { rvidx = 0; //------------------------------------------------------------------------------// - scheduled_response.ul_config->slot = 8; + scheduled_response.ul_config->slot = proc->nr_tti_tx; scheduled_response.ul_config->number_pdus = 1; scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; scheduled_response.ul_config->ul_config_list[0].ulsch_config_pdu.rnti = n_rnti; From 47713f2a0865b65dc2d6066e62121cf32092ca2a Mon Sep 17 00:00:00 2001 From: matzakos Date: Mon, 25 May 2020 15:46:00 +0200 Subject: [PATCH 011/171] NR RB configuration: Remove dependencies from LTE structures -Remaining LTE dependency in RLC add_srb function (not used for NSA setup) -Rename function for DRB static preconfiguration used in noS1 mode --- executables/nr-uesoftmodem.c | 2 +- openair1/SIMULATION/NR_PHY/dlsim.c | 2 +- openair1/SIMULATION/NR_PHY/prachsim.c | 2 +- openair1/SIMULATION/NR_PHY/ulsim.c | 2 +- openair2/LAYER2/NR_MAC_UE/main_ue_nr.c | 3 +- openair2/LAYER2/NR_MAC_gNB/main.c | 3 +- openair2/LAYER2/PDCP_v10.1.0/pdcp.c | 95 ---------------- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h | 2 + openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 131 +++++++++------------- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 41 +------ 10 files changed, 66 insertions(+), 217 deletions(-) diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index d5c34fc728..8adfb26a84 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -642,7 +642,7 @@ void init_pdcp(void) { LOG_I(RLC, "Problem at RLC initiation \n"); } pdcp_layer_init(); - nr_ip_over_LTE_DRB_preconfiguration();*/ + nr_DRB_preconfiguration();*/ pdcp_module_init(pdcp_initmask); pdcp_set_rlc_data_req_func((send_rlc_data_req_func_t) rlc_data_req); pdcp_set_pdcp_data_ind_func((pdcp_data_ind_func_t) pdcp_data_ind); diff --git a/openair1/SIMULATION/NR_PHY/dlsim.c b/openair1/SIMULATION/NR_PHY/dlsim.c index 8e0ef92c81..cb94ff985d 100644 --- a/openair1/SIMULATION/NR_PHY/dlsim.c +++ b/openair1/SIMULATION/NR_PHY/dlsim.c @@ -123,7 +123,7 @@ int generate_dlsch_header(unsigned char *mac_header, unsigned char *ue_cont_res_id, unsigned char short_padding, unsigned short post_padding){return 0;} -void nr_ip_over_LTE_DRB_preconfiguration(void){} +void nr_DRB_preconfiguration(void){} // needed for some functions openair0_config_t openair0_cfg[MAX_CARDS]; diff --git a/openair1/SIMULATION/NR_PHY/prachsim.c b/openair1/SIMULATION/NR_PHY/prachsim.c index aed7eb4505..d0af529ec3 100644 --- a/openair1/SIMULATION/NR_PHY/prachsim.c +++ b/openair1/SIMULATION/NR_PHY/prachsim.c @@ -76,7 +76,7 @@ boolean_t pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, const sdu_size_t sdu_buffer_sizeP, mem_block_t *const sdu_buffer_pP) {return(false);} -void nr_ip_over_LTE_DRB_preconfiguration(void){} +void nr_DRB_preconfiguration(void){} void pdcp_layer_init(void) {} int8_t nr_mac_rrc_data_ind_ue(const module_id_t module_id, const int CC_id, const uint8_t gNB_index, const int8_t channel, const uint8_t* pduP, const sdu_size_t pdu_len) {return 0;} diff --git a/openair1/SIMULATION/NR_PHY/ulsim.c b/openair1/SIMULATION/NR_PHY/ulsim.c index 3fced2c83d..75143dc077 100644 --- a/openair1/SIMULATION/NR_PHY/ulsim.c +++ b/openair1/SIMULATION/NR_PHY/ulsim.c @@ -98,7 +98,7 @@ boolean_t pdcp_data_ind( ) { return(false);} void pdcp_run (const protocol_ctxt_t *const ctxt_pP) { return;} -void nr_ip_over_LTE_DRB_preconfiguration(void){} +void nr_DRB_preconfiguration(void){} int rrc_init_nr_global_param(void){return(0);} diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 2cb9e5971d..2e758d51da 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -39,6 +39,7 @@ #include "PHY/defs_UE.h" #include "openair2/LAYER2/RLC/rlc.h" #include "openair2/LAYER2/PDCP_v10.1.0/pdcp.h" +#include "openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "executables/softmodem-common.h" static NR_UE_MAC_INST_t *nr_ue_mac_inst; @@ -59,7 +60,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) LOG_I(RLC, "Problem at RLC initiation \n"); } pdcp_layer_init(); - nr_ip_over_LTE_DRB_preconfiguration(); + nr_DRB_preconfiguration(); } } else LOG_I(MAC,"Running without RRC instance\n"); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index d38a251a2b..ea43f1f735 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -35,6 +35,7 @@ #include "assertions.h" #include "LAYER2/PDCP_v10.1.0/pdcp.h" +#include "LAYER2/nr_pdcp/nr_pdcp_entity.h" #include "RRC/NR/nr_rrc_defs.h" #include "common/utils/LOG/log.h" //#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h" @@ -89,7 +90,7 @@ void mac_top_init_gNB(void) pdcp_layer_init(); if(IS_SOFTMODEM_NOS1) - nr_ip_over_LTE_DRB_preconfiguration(); + nr_DRB_preconfiguration(); rrc_init_nr_global_param(); diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c index b0e6143de1..03e5dd5d0b 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp.c @@ -2361,101 +2361,6 @@ void pdcp_module_cleanup (void) { } -void nr_ip_over_LTE_DRB_preconfiguration(void){ - - // Addition for the use-case of 4G stack on top of 5G-NR. - // We need to configure pdcp and rlc instances without having an actual - // UE RRC Connection. In order to be able to test the NR PHY with some injected traffic - // on top of the LTE stack. - protocol_ctxt_t ctxt; - LTE_DRB_ToAddModList_t* DRB_configList=NULL; - DRB_configList = CALLOC(1, sizeof(LTE_DRB_ToAddModList_t)); - struct LTE_LogicalChannelConfig *DRB_lchan_config = NULL; - struct LTE_RLC_Config *DRB_rlc_config = NULL; - struct LTE_PDCP_Config *DRB_pdcp_config = NULL; - struct LTE_PDCP_Config__rlc_UM *PDCP_rlc_UM = NULL; - - struct LTE_DRB_ToAddMod *DRB_config = NULL; - struct LTE_LogicalChannelConfig__ul_SpecificParameters *DRB_ul_SpecificParameters = NULL; - long *logicalchannelgroup_drb; - - - //Static preconfiguration of DRB - DRB_config = CALLOC(1, sizeof(*DRB_config)); - - DRB_config->eps_BearerIdentity = CALLOC(1, sizeof(long)); - // allowed value 5..15, value : x+4 - *(DRB_config->eps_BearerIdentity) = 1; //ue_context_pP->ue_context.e_rab[i].param.e_rab_id;//+ 4; // especial case generation - // DRB_config->drb_Identity = 1 + drb_identity_index + e_rab_done;// + i ;// (DRB_Identity_t) ue_context_pP->ue_context.e_rab[i].param.e_rab_id; - // 1 + drb_identiy_index; - DRB_config->drb_Identity = 1; - DRB_config->logicalChannelIdentity = CALLOC(1, sizeof(long)); - *(DRB_config->logicalChannelIdentity) = DRB_config->drb_Identity + 2; //(long) (ue_context_pP->ue_context.e_rab[i].param.e_rab_id + 2); // value : x+2 - - DRB_rlc_config = CALLOC(1, sizeof(*DRB_rlc_config)); - DRB_config->rlc_Config = DRB_rlc_config; - - DRB_pdcp_config = CALLOC(1, sizeof(*DRB_pdcp_config)); - DRB_config->pdcp_Config = DRB_pdcp_config; - DRB_pdcp_config->discardTimer = CALLOC(1, sizeof(long)); - *DRB_pdcp_config->discardTimer = LTE_PDCP_Config__discardTimer_infinity; - DRB_pdcp_config->rlc_AM = NULL; - DRB_pdcp_config->rlc_UM = NULL; - - DRB_rlc_config->present = LTE_RLC_Config_PR_um_Bi_Directional; - DRB_rlc_config->choice.um_Bi_Directional.ul_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.sn_FieldLength = LTE_SN_FieldLength_size10; - DRB_rlc_config->choice.um_Bi_Directional.dl_UM_RLC.t_Reordering = LTE_T_Reordering_ms35; - // PDCP - PDCP_rlc_UM = CALLOC(1, sizeof(*PDCP_rlc_UM)); - DRB_pdcp_config->rlc_UM = PDCP_rlc_UM; - PDCP_rlc_UM->pdcp_SN_Size = LTE_PDCP_Config__rlc_UM__pdcp_SN_Size_len12bits; - - DRB_pdcp_config->headerCompression.present = LTE_PDCP_Config__headerCompression_PR_notUsed; - - DRB_lchan_config = CALLOC(1, sizeof(*DRB_lchan_config)); - DRB_config->logicalChannelConfig = DRB_lchan_config; - DRB_ul_SpecificParameters = CALLOC(1, sizeof(*DRB_ul_SpecificParameters)); - DRB_lchan_config->ul_SpecificParameters = DRB_ul_SpecificParameters; - - DRB_ul_SpecificParameters->priority= 4; - - DRB_ul_SpecificParameters->prioritisedBitRate = LTE_LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_kBps8; - //LogicalChannelConfig__ul_SpecificParameters__prioritisedBitRate_infinity; - DRB_ul_SpecificParameters->bucketSizeDuration = - LTE_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms50; - - logicalchannelgroup_drb = CALLOC(1, sizeof(long)); - *logicalchannelgroup_drb = 1;//(i+1) % 3; - DRB_ul_SpecificParameters->logicalChannelGroup = logicalchannelgroup_drb; - - ASN_SEQUENCE_ADD(&DRB_configList->list,DRB_config); - - if (ENB_NAS_USE_TUN){ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_YES, 0x1234, 0, 0,0); - } - else{ - PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, 0, ENB_FLAG_NO, 0x1234, 0, 0,0); - } - - rrc_pdcp_config_asn1_req(&ctxt, - (LTE_SRB_ToAddModList_t *) NULL, - DRB_configList, - (LTE_DRB_ToReleaseList_t *) NULL, - 0xff, NULL, NULL, NULL - , (LTE_PMCH_InfoList_r9_t *) NULL, - &DRB_config->drb_Identity); - - rrc_rlc_config_asn1_req(&ctxt, - (LTE_SRB_ToAddModList_t*)NULL, - DRB_configList, - (LTE_DRB_ToReleaseList_t*)NULL - //#if (RRC_VERSION >= MAKE_VERSION(10, 0, 0)) - ,(LTE_PMCH_InfoList_r9_t *)NULL - , 0, 0 - //#endif - ); -} //----------------------------------------------------------------------------- void pdcp_layer_init(void) //----------------------------------------------------------------------------- diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 74f09352d6..45555ad6af 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -60,4 +60,6 @@ nr_pdcp_entity_t *new_nr_pdcp_entity_drb_am( char *buf, int size, int sdu_id), void *deliver_pdu_data); +void nr_DRB_preconfiguration(void); + #endif /* _NR_PDCP_ENTITY_H_ */ diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 613ef1026f..2f9a01c8a9 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -541,7 +541,7 @@ void pdcp_run(const protocol_ctxt_t *const ctxt_pP) } } -static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) +static void add_srb(int rnti, struct NR_SRB_ToAddMod *s) { TODO; } @@ -655,6 +655,7 @@ boolean_t nr_rrc_pdcp_config_asn1_req( return 0; } +/* Dummy function due to dependency from LTE libraries */ boolean_t rrc_pdcp_config_asn1_req( const protocol_ctxt_t *const ctxt_pP, LTE_SRB_ToAddModList_t *const srb2add_list, @@ -669,51 +670,10 @@ boolean_t rrc_pdcp_config_asn1_req( #endif ,rb_id_t *const defaultDRB) { - int rnti = ctxt_pP->rnti; - int i; - - if (//ctxt_pP->enb_flag != 1 || - ctxt_pP->module_id != 0 || - ctxt_pP->instance != 0 || - ctxt_pP->eNB_index != 0 || - //ctxt_pP->configured != 2 || - //srb2add_list == NULL || - //drb2add_list != NULL || - drb2release_list != NULL || - security_modeP != 255 || - //kRRCenc != NULL || - //kRRCint != NULL || - //kUPenc != NULL || - pmch_InfoList_r9 != NULL /*|| - defaultDRB != NULL */) { - TODO; - } - - if (srb2add_list != NULL) { - for (i = 0; i < srb2add_list->list.count; i++) { - add_srb(rnti, srb2add_list->list.array[i]); - } - } - - if (drb2add_list != NULL) { - for (i = 0; i < drb2add_list->list.count; i++) { - add_drb(rnti, drb2add_list->list.array[i], NULL); - } - } - - /* update security */ - if (kRRCint != NULL) { - /* todo */ - } - - free(kRRCenc); - free(kRRCint); - free(kUPenc); - return 0; } -void nr_ip_over_LTE_DRB_preconfiguration(void) +void nr_DRB_preconfiguration(void) { NR_RadioBearerConfig_t *rbconfig = NULL; @@ -723,47 +683,47 @@ void nr_ip_over_LTE_DRB_preconfiguration(void) rbconfig = calloc(1, sizeof(*rbconfig)); rbconfig->srb_ToAddModList = NULL; - rbconfig->srb3_ToRelease = NULL; - rbconfig->drb_ToAddModList = calloc(1,sizeof(*rbconfig->drb_ToAddModList)); - NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); - drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); - drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; - drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5; - drb_ToAddMod->drb_Identity = 1; - drb_ToAddMod->reestablishPDCP = NULL; - drb_ToAddMod->recoverPDCP = NULL; - drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); - drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb)); - drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer)); - *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30; - drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL)); - *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits; - drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL)); - *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; - drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; - drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0; + rbconfig->srb3_ToRelease = NULL; + rbconfig->drb_ToAddModList = calloc(1,sizeof(*rbconfig->drb_ToAddModList)); + NR_DRB_ToAddMod_t *drb_ToAddMod = calloc(1,sizeof(*drb_ToAddMod)); + drb_ToAddMod->cnAssociation = calloc(1,sizeof(*drb_ToAddMod->cnAssociation)); + drb_ToAddMod->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_eps_BearerIdentity; + drb_ToAddMod->cnAssociation->choice.eps_BearerIdentity= 5; + drb_ToAddMod->drb_Identity = 1; + drb_ToAddMod->reestablishPDCP = NULL; + drb_ToAddMod->recoverPDCP = NULL; + drb_ToAddMod->pdcp_Config = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config)); + drb_ToAddMod->pdcp_Config->drb = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb)); + drb_ToAddMod->pdcp_Config->drb->discardTimer = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->discardTimer)); + *drb_ToAddMod->pdcp_Config->drb->discardTimer=NR_PDCP_Config__drb__discardTimer_ms30; + drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL)); + *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len12bits; + drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL)); + *drb_ToAddMod->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len12bits; + drb_ToAddMod->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed; + drb_ToAddMod->pdcp_Config->drb->headerCompression.choice.notUsed = 0; - drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL; - drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL; - drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL; - drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL; + drb_ToAddMod->pdcp_Config->drb->integrityProtection=NULL; + drb_ToAddMod->pdcp_Config->drb->statusReportRequired=NULL; + drb_ToAddMod->pdcp_Config->drb->outOfOrderDelivery=NULL; + drb_ToAddMod->pdcp_Config->moreThanOneRLC = NULL; - drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering)); - *drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0; - drb_ToAddMod->pdcp_Config->ext1 = NULL; + drb_ToAddMod->pdcp_Config->t_Reordering = calloc(1,sizeof(*drb_ToAddMod->pdcp_Config->t_Reordering)); + *drb_ToAddMod->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0; + drb_ToAddMod->pdcp_Config->ext1 = NULL; - ASN_SEQUENCE_ADD(&rbconfig->drb_ToAddModList->list,drb_ToAddMod); + ASN_SEQUENCE_ADD(&rbconfig->drb_ToAddModList->list,drb_ToAddMod); - rbconfig->drb_ToReleaseList = NULL; + rbconfig->drb_ToReleaseList = NULL; - rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); - rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); - rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; - rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; - rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); - *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; + rbconfig->securityConfig = calloc(1,sizeof(*rbconfig->securityConfig)); + rbconfig->securityConfig->securityAlgorithmConfig = calloc(1,sizeof(*rbconfig->securityConfig->securityAlgorithmConfig)); + rbconfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm = NR_CipheringAlgorithm_nea0; + rbconfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm=NULL; + rbconfig->securityConfig->keyToUse = calloc(1,sizeof(*rbconfig->securityConfig->keyToUse)); + *rbconfig->securityConfig->keyToUse = NR_SecurityConfig__keyToUse_master; - xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); + xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void*)rbconfig); NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); @@ -787,6 +747,21 @@ void nr_ip_over_LTE_DRB_preconfiguration(void) *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15; + // RLC AM Bearer configuration + /*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am; + RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am)); + RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); + *RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; + RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.t_PollRetransmit = NR_T_PollRetransmit_ms45; + RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollPDU = NR_PollPDU_p64; + RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.pollByte = NR_PollByte_kB500; + RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.maxRetxThreshold = NR_UL_AM_RLC__maxRetxThreshold_t32; + + RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)); + *RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; + RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15; + RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;*/ + RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig)); RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters)); RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters->priority = 1; diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 5a21611f5b..933b83352d 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -821,7 +821,7 @@ __attribute__ ((unused)) static void add_drb(int rnti, struct NR_DRB_ToAddMod *s } } -//#if 0 +/* Dummy function due to dependency from LTE libraries */ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, const LTE_SRB_ToAddModList_t * const srb2add_listP, const LTE_DRB_ToAddModList_t * const drb2add_listP, @@ -830,46 +830,11 @@ rlc_op_status_t rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP const uint32_t sourceL2Id, const uint32_t destinationL2Id) { - int rnti = ctxt_pP->rnti; - int i; - - if (/*ctxt_pP->enb_flag != 1 ||*/ ctxt_pP->module_id != 0 /*|| - ctxt_pP->instance != 0 || ctxt_pP->eNB_index != 0 || - ctxt_pP->configured != 1 || ctxt_pP->brOption != 0 */) { - LOG_E(RLC, "%s: ctxt_pP not handled (%d %d %d %d %d %d)\n", __FUNCTION__, - ctxt_pP->enb_flag , ctxt_pP->module_id, ctxt_pP->instance, - ctxt_pP->eNB_index, ctxt_pP->configured, ctxt_pP->brOption); - exit(1); - } - - if (pmch_InfoList_r9_pP != NULL) { - LOG_E(RLC, "%s: pmch_InfoList_r9_pP not handled\n", __FUNCTION__); - exit(1); - } - - if (drb2release_listP != NULL) { - LOG_E(RLC, "%s:%d:%s: TODO\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); - } - - if (srb2add_listP != NULL) { - for (i = 0; i < srb2add_listP->list.count; i++) { - add_srb(rnti, srb2add_listP->list.array[i]); - } - } - - if (drb2add_listP != NULL) { - for (i = 0; i < drb2add_listP->list.count; i++) { - add_drb(rnti, drb2add_listP->list.array[i], NULL); - } - } - - return RLC_OP_STATUS_OK; + return 0; } -//#endif rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt_pP, - const NR_SRB_ToAddModList_t * const srb2add_listP, + const LTE_SRB_ToAddModList_t * const srb2add_listP, const NR_DRB_ToAddModList_t * const drb2add_listP, const NR_DRB_ToReleaseList_t * const drb2release_listP, const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP, From 72f1b2cb0966537dbd0a495ae6dfac058d9721ee Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 25 May 2020 20:55:12 +0200 Subject: [PATCH 012/171] Remove hack restriction for single time DL scheduling --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 3cf9c486b1..7ab1d4c51a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -470,7 +470,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, pucch_sched, NULL); // resetting ta flag gNB->ta_len = 0; - UE_list->fiveG_connected[UE_id] = false; + //UE_list->fiveG_connected[UE_id] = false; } diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 8b4275b763..eb373542ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -601,7 +601,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (rlc_status.bytes_in_buffer > 0) { - LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", + LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, lcid, header_length_total, TBS_bytes); @@ -617,7 +617,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, 0, 0); - LOG_D(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); + LOG_W(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); sdu_lcids[num_sdus] = lcid; sdu_length_total += sdu_lengths[num_sdus]; From 69b4211aba92df383bd5c66b081ccd1e2c1b54f8 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 25 May 2020 21:13:19 +0200 Subject: [PATCH 013/171] Change default NR DRB configuration to RLC UM --- openair2/RRC/NR/rrc_gNB_reconfig.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index 722281ef31..5457835126 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -72,17 +72,17 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco RLC_BearerConfig->rlc_Config=calloc(1,sizeof(*RLC_BearerConfig->rlc_Config)); // RLC UM Bi-directional Bearer configuration - /*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional; + RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_um_Bi_Directional; RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional)); RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength)); *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->ul_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength)); *RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.sn_FieldLength = NR_SN_FieldLengthUM_size12; - RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15;*/ + RLC_BearerConfig->rlc_Config->choice.um_Bi_Directional->dl_UM_RLC.t_Reassembly = NR_T_Reassembly_ms15; // RLC AM Bearer configuration - RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am; + /*RLC_BearerConfig->rlc_Config->present = NR_RLC_Config_PR_am; RLC_BearerConfig->rlc_Config->choice.am = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am)); RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength)); *RLC_BearerConfig->rlc_Config->choice.am->ul_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; @@ -94,7 +94,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = calloc(1,sizeof(*RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength)); *RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.sn_FieldLength = NR_SN_FieldLengthAM_size18; RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_Reassembly = NR_T_Reassembly_ms15; - RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15; + RLC_BearerConfig->rlc_Config->choice.am->dl_AM_RLC.t_StatusProhibit = NR_T_StatusProhibit_ms15;*/ RLC_BearerConfig->mac_LogicalChannelConfig = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig)); RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters = calloc(1,sizeof(*RLC_BearerConfig->mac_LogicalChannelConfig->ul_SpecificParameters)); From 072836d7b98ba0b0618d8b04d2361f4c769e8cfe Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 8 Jun 2020 14:38:54 +0200 Subject: [PATCH 014/171] NR-IP traffic: Make fapi dl pdu configuration be triggered only when there is data from the upper layers to be scheduled - To be used for NSA and noS1 modes --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index ca7291fa92..93277bbb96 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -258,6 +258,7 @@ int configure_fapi_dl_pdu(int Mod_idP, uint16_t *rbStart) { + LOG_I(MAC, "Inside configure_fapi_dl_pdu() \n"); gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = nr_mac->common_channels; @@ -569,7 +570,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, ta_len = gNB_mac->ta_len; - TBS_bytes = configure_fapi_dl_pdu(module_idP, + /*TBS_bytes = configure_fapi_dl_pdu(module_idP, dl_req, pucch_sched, dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, @@ -577,7 +578,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); if (TBS_bytes == 0) - return; + return;*/ //Corresponding to noS1 and EPC_MODE_ENABLED use cases where DLSCH transmissions are scheduled only when there is IP traffic //at the upper layers @@ -604,6 +605,18 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (rlc_status.bytes_in_buffer > 0) { + LOG_I(MAC, "configure fapi due to data availability \n"); + + TBS_bytes = configure_fapi_dl_pdu(module_idP, + dl_req, + pucch_sched, + dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, + dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, + dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); + + if (TBS_bytes == 0) + return; + LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, lcid, header_length_total, TBS_bytes); @@ -631,6 +644,18 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //ue_sched_ctl->uplane_inactivity_timer = 0; } + else if(ta_len > 0){ + LOG_I(MAC, "configure fapi due to TA \n"); + TBS_bytes = configure_fapi_dl_pdu(module_idP, + dl_req, + pucch_sched, + dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, + dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, + dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); + + if (TBS_bytes == 0) + return; + } } else { // no TBS_bytes left break; } @@ -639,6 +664,16 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } //if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test) else { + TBS_bytes = configure_fapi_dl_pdu(module_idP, + dl_req, + pucch_sched, + dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, + dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, + dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); + + if (TBS_bytes == 0) + return; + //When the --NOS1 option is not enabled, DLSCH transmissions with random data //occur every time that the current function is called (dlsch phytest mode) From 2e8092540ff60da8a5494dcde805da33e95eefc4 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 8 Jun 2020 16:31:30 +0200 Subject: [PATCH 015/171] moving function to prepare pucch scheduling inside dlsch_phytest --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c | 5 +---- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 14 ++++++++++---- .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 1 - openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 +- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c index 834c955b03..5e4e7b207c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler.c @@ -361,7 +361,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, int UE_id; uint64_t *dlsch_in_slot_bitmap=NULL; uint64_t *ulsch_in_slot_bitmap=NULL; - int pucch_sched; UE_id=0; int bwp_id = 1; @@ -468,8 +467,7 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, // Phytest scheduling if (UE_list->fiveG_connected[UE_id] && (is_xlsch_in_slot(*dlsch_in_slot_bitmap,slot_txP%num_slots_per_tdd))) { ue_sched_ctl->current_harq_pid = slot_txP % num_slots_per_tdd; - nr_update_pucch_scheduling(module_idP, UE_id, frame_txP, slot_txP, num_slots_per_tdd,&pucch_sched); - nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], NULL); + nr_schedule_uss_dlsch_phytest(module_idP, frame_txP, slot_txP, num_slots_per_tdd, NULL); // resetting ta flag gNB->ta_len = 0; } @@ -479,7 +477,6 @@ void gNB_dlsch_ulsch_scheduler(module_id_t module_idP, for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) allocate_CCEs(module_idP, CC_id, subframeP, 0); */ - } //is_nr_DL_slot if (is_nr_UL_slot(cc->ServingCellConfigCommon,slot_rxP)) { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 93277bbb96..5693a1e9c3 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -541,12 +541,13 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, - NR_sched_pucch *pucch_sched, + int num_slots_per_tdd, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){ int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; int lcid, offset, i, header_length_last, TBS_bytes; int UE_id = 0, CC_id = 0; + int pucch_sched; gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; //NR_COMMON_channels_t *cc = nr_mac->common_channels; @@ -607,9 +608,11 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, LOG_I(MAC, "configure fapi due to data availability \n"); + nr_update_pucch_scheduling(module_idP, UE_id, frameP, slotP, num_slots_per_tdd, &pucch_sched); + TBS_bytes = configure_fapi_dl_pdu(module_idP, dl_req, - pucch_sched, + &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); @@ -646,9 +649,11 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } else if(ta_len > 0){ LOG_I(MAC, "configure fapi due to TA \n"); + + nr_update_pucch_scheduling(module_idP, UE_id, frameP, slotP, num_slots_per_tdd, &pucch_sched); TBS_bytes = configure_fapi_dl_pdu(module_idP, dl_req, - pucch_sched, + &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); @@ -664,9 +669,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } //if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test) else { + nr_update_pucch_scheduling(module_idP, UE_id, frameP, slotP, num_slots_per_tdd, &pucch_sched); TBS_bytes = configure_fapi_dl_pdu(module_idP, dl_req, - pucch_sched, + &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index fa1e860c57..a87f406571 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -497,7 +497,6 @@ int nr_configure_pdcch(gNB_MAC_INST *nr_mac, //precoderGranularity pdcch_pdu->precoderGranularity = coreset->precoderGranularity; - pdcch_pdu->dci_pdu.RNTI[pdcch_pdu->numDlDci]=rnti; if (coreset->pdcch_DMRS_ScramblingID != NULL && diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 4e29adf978..b190866c5d 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -145,7 +145,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, - NR_sched_pucch *pucch_sched, + int num_slots_per_tdd, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config); void nr_schedule_uss_ulsch_phytest(int Mod_idP, From 6a9d606255473c28238615a00a246e5d9736a1f4 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 8 Jun 2020 19:09:03 +0200 Subject: [PATCH 016/171] Temporarily consider single LCID for DL traffic scheduling --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 5693a1e9c3..8713dc5e32 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -545,7 +545,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){ int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; - int lcid, offset, i, header_length_last, TBS_bytes; + int lcid, offset, i, header_length_last, TBS_bytes = 0; int UE_id = 0, CC_id = 0; int pucch_sched; @@ -585,14 +585,16 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //at the upper layers if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test == 0){ - for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + lcid = DTCH; + + //for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { // TODO: check if the lcid is active LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n", module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); - if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { + //if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, @@ -617,7 +619,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); - if (TBS_bytes == 0) + if (TBS_bytes == 0) return; LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", @@ -661,10 +663,10 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, if (TBS_bytes == 0) return; } - } else { // no TBS_bytes left + /*} else { // no TBS_bytes left break; - } - } + }*/ + //} for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { } //if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test) else { From 2381bd91d2e1fd35d3727426a311a7558bf18899 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Fri, 12 Jun 2020 19:30:17 +0200 Subject: [PATCH 017/171] Add detection of NR scgFailureInformation message at rrc eNB --- openair2/RRC/LTE/rrc_eNB.c | 59 ++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 8f1c5daccc..85134ac09a 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -8092,29 +8092,46 @@ rrc_eNB_decode_dcch( break; case LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2: //SidelinkUEInformation - //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation - LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); - LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, + if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == + LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_scgFailureInformationNR_r15){ + if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15. + criticalExtensions.present == LTE_SCGFailureInformationNR_r15__criticalExtensions_PR_c1){ + if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. + choice.c1.present == LTE_SCGFailureInformationNR_r15__criticalExtensions__c1_PR_scgFailureInformationNR_r15){ + if (ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. + choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15!=NULL) { + LOG_E(RRC, "Received NR scgFailureInformation from UE, failure type: %ld \n", + ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. + choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15); + } + } + } + } + else if(ul_dcch_msg->message.choice.messageClassExtension.choice.c2.present == LTE_UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12){ + //case UL_DCCH_MessageType__messageClassExtension__c2_PR_sidelinkUEInformation_r12: //SidelinkUEInformation + LOG_I(RRC,"THINH [LTE_UL_DCCH_MessageType__messageClassExtension_PR_c2]\n"); + LOG_DUMPMSG(RRC,DEBUG_RRC,(char *)Rx_sdu,sdu_sizeP, "[MSG] RRC SidelinkUEInformation \n"); - MSC_LOG_RX_MESSAGE( - MSC_RRC_ENB, - MSC_RRC_UE, - Rx_sdu, - sdu_sizeP, - MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", - MSC_AS_TIME_ARGS(ctxt_pP), - ue_context_p->ue_context.rnti, - sdu_sizeP); - LOG_I(RRC, - PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " - "(SidelinkUEInformation) ---> RRC_eNB\n", - PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), - DCCH, + MSC_LOG_RX_MESSAGE( + MSC_RRC_ENB, + MSC_RRC_UE, + Rx_sdu, + sdu_sizeP, + MSC_AS_TIME_FMT" SidelinkUEInformation UE %x size %u", + MSC_AS_TIME_ARGS(ctxt_pP), + ue_context_p->ue_context.rnti, sdu_sizeP); - rrc_eNB_process_SidelinkUEInformation( - ctxt_pP, - ue_context_p, - &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12); + LOG_I(RRC, + PROTOCOL_RRC_CTXT_UE_FMT" RLC RB %02d --- RLC_DATA_IND %d bytes " + "(SidelinkUEInformation) ---> RRC_eNB\n", + PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP), + DCCH, + sdu_sizeP); + rrc_eNB_process_SidelinkUEInformation( + ctxt_pP, + ue_context_p, + &ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.sidelinkUEInformation_r12); + } break; default: From c3e871257b05c04b507d321b2187ac6eab39dbec Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Fri, 19 Jun 2020 14:00:34 +0200 Subject: [PATCH 018/171] Add printing contents of NR scgFailureInformation message at rrc eNB --- openair2/RRC/LTE/rrc_eNB.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 85134ac09a..652a390122 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -8085,7 +8085,7 @@ rrc_eNB_decode_dcch( return 0; //TTN for D2D } else if (ul_dcch_msg->message.present == LTE_UL_DCCH_MessageType_PR_messageClassExtension) { - LOG_I(RRC, "THINH [LTE_UL_DCCH_MessageType_PR_messageClassExtension]\n"); + LOG_I(RRC, "[LTE_UL_DCCH_MessageType_PR_messageClassExtension]\n"); switch (ul_dcch_msg->message.choice.messageClassExtension.present) { case LTE_UL_DCCH_MessageType__messageClassExtension_PR_NOTHING: /* No components present */ @@ -8103,6 +8103,7 @@ rrc_eNB_decode_dcch( LOG_E(RRC, "Received NR scgFailureInformation from UE, failure type: %ld \n", ul_dcch_msg->message.choice.messageClassExtension.choice.c2.choice.scgFailureInformationNR_r15.criticalExtensions. choice.c1.choice.scgFailureInformationNR_r15.failureReportSCG_NR_r15->failureType_r15); + xer_fprint(stdout, &asn_DEF_LTE_UL_DCCH_Message, (void *)ul_dcch_msg); } } } From 7e33d11c3dbfdb7777453060f5c35c7964108bb1 Mon Sep 17 00:00:00 2001 From: matzakos Date: Wed, 3 Jun 2020 11:23:28 +0200 Subject: [PATCH 019/171] Change NR PDCP SN field to 18 instead of 12 bits length -Required because the 12 bits SN is not accepted from the phone --- openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c index c25f28aae8..85f638d66d 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity_drb_am.c @@ -32,7 +32,7 @@ void nr_pdcp_entity_drb_am_recv_pdu(nr_pdcp_entity_t *_entity, char *buffer, int if (size < 3) abort(); if (!(buffer[0] & 0x80)) { printf("%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } entity->common.deliver_sdu(entity->common.deliver_sdu_data, - (nr_pdcp_entity_t *)entity, buffer+2, size-2); + (nr_pdcp_entity_t *)entity, buffer+3, size-3); } void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int size, @@ -50,12 +50,13 @@ void nr_pdcp_entity_drb_am_recv_sdu(nr_pdcp_entity_t *_entity, char *buffer, int entity->common.tx_hfn++; } - buf[0] = 0x80 | ((sn >> 8) & 0x0f); - buf[1] = sn & 0xff; - memcpy(buf+2, buffer, size); + buf[0] = 0x80 | ((sn >> 16) & 0x3); + buf[1] = (sn >> 8) & 0xff; + buf[2] = sn & 0xff; + memcpy(buf+3, buffer, size); entity->common.deliver_pdu(entity->common.deliver_pdu_data, - (nr_pdcp_entity_t *)entity, buf, size+2, sdu_id); + (nr_pdcp_entity_t *)entity, buf, size+3, sdu_id); } void nr_pdcp_entity_drb_am_set_integrity_key(nr_pdcp_entity_t *_entity, char *key) From b90e57549ce137fb601f03af30f5f3bb8f8b43f2 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Wed, 17 Jun 2020 09:53:36 +0200 Subject: [PATCH 020/171] ignore inconsistent DCI instead of exiting --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 32 +++++++++++--------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 0da02bd7d1..b0437ea972 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2232,9 +2232,14 @@ int8_t nr_ue_process_dci_time_dom_resource_assignment(NR_UE_MAC_INST_t *mac, pdsch_TimeDomainAllocationList = mac->DLbwp[0]->bwp_Common->pdsch_ConfigCommon->choice.setup->pdsch_TimeDomainAllocationList; if (pdsch_TimeDomainAllocationList) { - AssertFatal(pdsch_TimeDomainAllocationList->list.count > time_domain_ind, - "time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n", - time_domain_ind,pdsch_TimeDomainAllocationList->list.count); + if (time_domain_ind >= pdsch_TimeDomainAllocationList->list.count) { + LOG_E(MAC, "time_domain_ind %d >= pdsch->TimeDomainAllocationList->list.count %d\n", + time_domain_ind, pdsch_TimeDomainAllocationList->list.count); + dlsch_config_pdu->start_symbol = 0; + dlsch_config_pdu->number_symbols = 0; + return -1; + } + int startSymbolAndLength = pdsch_TimeDomainAllocationList->list.array[time_domain_ind]->startSymbolAndLength; int S,L; SLIV2SL(startSymbolAndLength,&S,&L); @@ -2342,10 +2347,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_0,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(mac, - pusch_config_pdu_0_0,NULL, - dci->time_dom_resource_assignment); - + if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_0,NULL,dci->time_dom_resource_assignment) < 0) + break; /* FREQ_HOPPING_FLAG */ if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0)) @@ -2417,8 +2420,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr /* FREQ_DOM_RESOURCE_ASSIGNMENT_UL */ nr_ue_process_dci_freq_dom_resource_assignment(pusch_config_pdu_0_1,NULL,n_RB_ULBWP,0,dci->freq_dom_resource_assignment_UL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL, - dci->time_dom_resource_assignment); + if (nr_ue_process_dci_time_dom_resource_assignment(mac,pusch_config_pdu_0_1,NULL,dci->time_dom_resource_assignment) < 0) + break; /* FREQ_HOPPING_FLAG */ if ((mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.resource_allocation != 0) && (mac->phy_config.config_req.ul_bwp_dedicated.pusch_config_dedicated.frequency_hopping !=0)) @@ -2748,9 +2751,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_0,0,n_RB_DLBWP,dci->freq_dom_resource_assignment_DL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0, - dci->time_dom_resource_assignment); - + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_0,dci->time_dom_resource_assignment) < 0) + break; /* dmrs symbol positions*/ dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, @@ -2868,8 +2870,8 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr /* FREQ_DOM_RESOURCE_ASSIGNMENT_DL */ nr_ue_process_dci_freq_dom_resource_assignment(NULL,dlsch_config_pdu_1_1,0,n_RB_DLBWP,dci->freq_dom_resource_assignment_DL); /* TIME_DOM_RESOURCE_ASSIGNMENT */ - nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1, - dci->time_dom_resource_assignment); + if (nr_ue_process_dci_time_dom_resource_assignment(mac,NULL,dlsch_config_pdu_1_1,dci->time_dom_resource_assignment) < 0) + break; /* VRB_TO_PRB_MAPPING */ if (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.resource_allocation != 0) dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; @@ -3140,7 +3142,7 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac, pos+=4; dci_pdu_rel15->time_dom_resource_assignment = (*dci_pdu >> (dci_size-pos))&0xf; #ifdef DEBUG_EXTRACT_DCI - LOG_D(MAC,"time-domain assignment %d (3 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_dom_resource_assignment,dci_size-pos,*dci_pdu); + LOG_D(MAC,"time-domain assignment %d (4 bits)=> %d (0x%lx)\n",dci_pdu_rel15->time_dom_resource_assignment,dci_size-pos,*dci_pdu); #endif // VRB to PRB mapping From a5a1d7b918d9d26a7601aa3b53026427d01c31ef Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 29 Jun 2020 12:13:27 +0200 Subject: [PATCH 021/171] Improve stability by replacing AssertFatal() with LOG_E() in nr_rx_pdsch() --- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 7f941e5567..a8827b4e92 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -214,7 +214,8 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch1_harq->codeword); #endif - AssertFatal(1 == 0, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n"); + LOG_E(PHY, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n"); + return -1; } else { LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx); @@ -224,14 +225,16 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, break; default: - AssertFatal(1 == 0, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type); + LOG_E(PHY, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type); return(-1); break; } - if (dlsch0_harq == NULL) - AssertFatal(1 == 0, "Done\n"); + if (dlsch0_harq == NULL) { + LOG_E(PHY, "Done\n"); + return -1; + } dlsch0_harq->Qm = nr_get_Qm_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); dlsch0_harq->R = nr_get_code_rate_dl(dlsch[0]->harq_processes[harq_pid]->mcs, dlsch[0]->harq_processes[harq_pid]->mcs_table); From c5fdcd85cc936677e65daa378c11b6b35a8cb0cf Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 15:42:13 +0200 Subject: [PATCH 022/171] Bugfix FlexRAN: if a UE is in RRC but not S1AP, treat as no bug --- openair2/ENB_APP/flexran_agent_ran_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 32cb8c74e1..abade20846 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3644,7 +3644,7 @@ int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_con RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head){ if (ue->eNB_ue_s1ap_id == enb_ue_s1ap_id) break; } - if (ue == NULL) return -1; + if (!ue) return 0; // UE does not exist: it might be connected but CN did not answer if (ue->mme_ref->mme_s1_ip.ipv4) ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv4_address[0]; From 9072101a1a9c802de3334aa4e020417b6849b9ae Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 15 Apr 2020 21:25:42 +0200 Subject: [PATCH 023/171] Correctly decode IMSI also when not integrity protected --- openair2/RRC/LTE/rrc_eNB_S1AP.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 27a442ed05..9f92be366b 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -96,36 +96,34 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE)) return; + /* Decode plain NAS message */ + EMM_msg *e_msg = &nas_msg.plain.emm; + emm_msg_header_t *emm_header = &e_msg->header; + if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { /* Decode the message authentication code */ DECODE_U32((char *) pdu_buf+size, header->message_authentication_code, size); /* Decode the sequence number */ DECODE_U8((char *) pdu_buf+size, header->sequence_number, size); - } + /* Decode the security header type and the protocol discriminator */ + DECODE_U8(pdu_buf + size, *(uint8_t *)(emm_header), size); - /* Note: the value of the pointer (i.e. the address) is given by value, so we - * can modify it as we want. The callee retains the original address! */ + /* Check that this is the right message */ + if (emm_header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) + return; + } pdu_buf += size; pdu_len -= size; - /* Decode plain NAS message */ - EMM_msg *e_msg = &nas_msg.plain.emm; - emm_msg_header_t *emm_header = &e_msg->header; - /* First decode the EMM message header */ - int e_head_size = 0; /* Check that buffer contains more than only the header */ if (pdu_len <= sizeof(emm_msg_header_t)) return; - /* Decode the security header type and the protocol discriminator */ - DECODE_U8(pdu_buf + e_head_size, *(uint8_t *)(emm_header), e_head_size); + /* First decode the EMM message header */ + int e_head_size = 0; /* Decode the message type */ DECODE_U8(pdu_buf + e_head_size, emm_header->message_type, e_head_size); - /* Check that this is the right message */ - if (emm_header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) - return; - pdu_buf += e_head_size; pdu_len -= e_head_size; From b01d63ba4ecf7995c35a3fbbc097cc2bdda1dbf4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 00:20:24 +0200 Subject: [PATCH 024/171] Do not check for register_enb_pending The test seemingly ensures that this code block is hit only once. However, if we enable later activation of MMEs, it will be hit a second (and third, ...) time. The only thing in guards against, though, is an INIT message to the L1L2 thread, when register_enb_pending == 0, which should only be sent once. Therefore, functionality won't be changed if register_enb_pending becomes negative, and the assert can be removed. --- openair2/ENB_APP/enb_app.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 0e1c7e64bc..7c91e57813 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -273,7 +273,6 @@ void *eNB_app_task(void *args_p) { if (EPC_MODE_ENABLED) { LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); - DevAssert(register_enb_pending > 0); register_enb_pending--; /* Check if at least eNB is registered with one MME */ From 1363a53dd070fd49bf3efb21dea94abad288887d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 00:23:40 +0200 Subject: [PATCH 025/171] S1AP: Only register MME if we do not know it yet --- openair3/S1AP/s1ap_eNB.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c228034245..c703501847 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -220,8 +220,21 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * /* Trying to connect to provided list of MME ip address */ for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { + net_ip_address_t *mme_ip = &s1ap_register_eNB->mme_ip_address[index]; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &new_instance->s1ap_mme_head) { + /* Compare whether IPv4 and IPv6 information is already present, in which + * wase we do not register again */ + if (mme->mme_s1_ip.ipv4 == mme_ip->ipv4 && (!mme_ip->ipv4 + || strncmp(mme->mme_s1_ip.ipv4_address, mme_ip->ipv4_address, 16) == 0) + && mme->mme_s1_ip.ipv6 == mme_ip->ipv6 && (!mme_ip->ipv6 + || strncmp(mme->mme_s1_ip.ipv6_address, mme_ip->ipv6_address, 46) == 0)) + break; + } + if (mme) + continue; s1ap_eNB_register_mme(new_instance, - &s1ap_register_eNB->mme_ip_address[index], + mme_ip, &s1ap_register_eNB->enb_ip_address, s1ap_register_eNB->sctp_in_streams, s1ap_register_eNB->sctp_out_streams, From df3f7e1ecfe0556bc3363c643ed811a1c3772ec1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 10 Apr 2020 23:17:36 +0200 Subject: [PATCH 026/171] FlexRAN: Enable MME adding/removing --- .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.c | 33 +++++++ .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.h | 5 + openair2/ENB_APP/flexran_agent_common.c | 47 +++++----- openair2/ENB_APP/flexran_agent_ran_api.c | 91 +++++++++++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 6 ++ 5 files changed, 160 insertions(+), 22 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c index 04a47406e1..d5fc5627a0 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c @@ -125,6 +125,39 @@ void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply) { } } +void flexran_agent_handle_mme_update(mid_t mod_id, + size_t n_mme, + Protocol__FlexS1apMme **mme) { + if (n_mme == 0 || n_mme > 1) { + LOG_E(FLEXRAN_AGENT, "cannot handle %lu MMEs yet\n", n_mme); + return; + } + + if (!mme[0]->s1_ip) { + LOG_E(FLEXRAN_AGENT, "no S1 IP present, cannot handle request\n"); + return; + } + + if (mme[0]->has_state + && mme[0]->state == PROTOCOL__FLEX_MME_STATE__FLMMES_DISCONNECTED) { + int rc = flexran_remove_s1ap_mme(mod_id, 1, &mme[0]->s1_ip); + if (rc == 0) + LOG_I(FLEXRAN_AGENT, "remove MME at IP %s\n", mme[0]->s1_ip); + else + LOG_W(FLEXRAN_AGENT, + "could not remove MME: flexran_remove_s1ap_mme() returned %d\n", + rc); + } else { + int rc = flexran_add_s1ap_mme(mod_id, 1, &mme[0]->s1_ip); + if (rc == 0) + LOG_I(FLEXRAN_AGENT, "add MME at IP %s\n", mme[0]->s1_ip); + else + LOG_W(FLEXRAN_AGENT, + "could not add MME: flexran_add_s1ap_mme() returned %d\n", + rc); + } +} + int flexran_agent_register_s1ap_xface(mid_t mod_id) { if (agent_s1ap_xface[mod_id]) { LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h index 1cca6ac9c1..54ea2926a8 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h @@ -60,6 +60,11 @@ int flexran_agent_s1ap_stats_reply(mid_t mod_id, /* Free allocated S1AP stats message */ void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply); +/* Add or remove MME updates */ +void flexran_agent_handle_mme_update(mid_t mod_id, + size_t n_mme, + Protocol__FlexS1apMme **mme); + /* Register technology specific interface callbacks */ int flexran_agent_register_s1ap_xface(mid_t mod_id); diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index dc320ef974..ec0b780a3a 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -893,31 +893,34 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg; - if (enb_config->n_cell_config == 0) { - LOG_W(FLEXRAN_AGENT, - "received enb_config_reply message does not contain a cell_config\n"); - *msg = NULL; - return 0; - } - if (enb_config->n_cell_config > 1) LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n"); - if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { - prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); - } else if (enb_config->cell_config[0]->has_eutra_band - && enb_config->cell_config[0]->has_dl_freq - && enb_config->cell_config[0]->has_ul_freq - && enb_config->cell_config[0]->has_dl_bandwidth) { - initiate_soft_restart(mod_id, enb_config->cell_config[0]); - } else if (flexran_agent_get_rrc_xface(mod_id) - && enb_config->cell_config[0]->has_x2_ho_net_control) { - LOG_I(FLEXRAN_AGENT, - "setting X2 HO NetControl to %d\n", - enb_config->cell_config[0]->x2_ho_net_control); - const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control); - if (rc < 0) - LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network"); + if (enb_config->n_cell_config > 0) { + if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { + prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); + } + if (enb_config->cell_config[0]->has_eutra_band + && enb_config->cell_config[0]->has_dl_freq + && enb_config->cell_config[0]->has_ul_freq + && enb_config->cell_config[0]->has_dl_bandwidth) { + initiate_soft_restart(mod_id, enb_config->cell_config[0]); + } + if (flexran_agent_get_rrc_xface(mod_id) + && enb_config->cell_config[0]->has_x2_ho_net_control) { + LOG_I(FLEXRAN_AGENT, + "setting X2 HO NetControl to %d\n", + enb_config->cell_config[0]->x2_ho_net_control); + const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control); + if (rc < 0) + LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network"); + } + } + + if (flexran_agent_get_s1ap_xface(mod_id) && enb_config->s1ap) { + flexran_agent_handle_mme_update(mod_id, + enb_config->s1ap->n_mme, + enb_config->s1ap->mme); } *msg = NULL; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index abade20846..3306dfe61b 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3634,6 +3634,97 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM return 0; } +int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + if (!rrc_is_present(mod_id)) return -2; + + /* Reconstruct S1AP_REGISTER_ENB_REQ */ + MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, S1AP_REGISTER_ENB_REQ); + RCconfig_S1(m, mod_id); + + const int CC_id = 0; + eNB_RRC_INST *rrc = RC.rrc[CC_id]; + RrcConfigurationReq *conf = &rrc->configuration; + S1AP_REGISTER_ENB_REQ(m).num_plmn = conf->num_plmn; + for (int i = 0; i < conf->num_plmn; ++i) { + S1AP_REGISTER_ENB_REQ(m).mcc[i] = conf->mcc[i]; + S1AP_REGISTER_ENB_REQ(m).mnc[i] = conf->mnc[i]; + S1AP_REGISTER_ENB_REQ(m).mnc_digit_length[i] = conf->mnc_digit_length[i]; + } + + /* reconstruct MME list, it might have been updated since initial + * configuration */ + S1AP_REGISTER_ENB_REQ(m).nb_mme = 0; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { + const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = mme->mme_s1_ip.ipv4; + strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme->mme_s1_ip.ipv4_address); + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = mme->mme_s1_ip.ipv6; + strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6_address, mme->mme_s1_ip.ipv6_address); + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = mme->broadcast_plmn_num; + for (int i = 0; i < mme->broadcast_plmn_num; ++i) + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = mme->broadcast_plmn_index[i]; + S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; + } + + if (S1AP_REGISTER_ENB_REQ(m).nb_mme + n_mme > S1AP_MAX_NB_MME_IP_ADDRESS) + return -1; + + for (int i = 0; i < n_mme; ++i) { + const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; + strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]); + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1; + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0; + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn; + for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i) + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i; + S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; + } + + itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); + + return 0; +} + +int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { + if (mme->mme_s1_ip.ipv4 + && strncmp(mme->mme_s1_ip.ipv4_address, mme_ipv4[0], 16) == 0) + break; + } + if (!mme) + return -2; + + MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SCTP_CLOSE_ASSOCIATION); + SCTP_CLOSE_ASSOCIATION(m).assoc_id = mme->assoc_id; + itti_send_msg_to_task (TASK_SCTP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); + + switch (mme->state) { + case S1AP_ENB_STATE_WAITING: + s1ap->s1ap_mme_nb -= 1; + if (s1ap->s1ap_mme_pending_nb > 0) + s1ap->s1ap_mme_pending_nb -= 1; + break; + case S1AP_ENB_STATE_CONNECTED: + case S1AP_ENB_OVERLOAD: /* I am not sure the decrements are right here */ + s1ap->s1ap_mme_nb -= 1; + s1ap->s1ap_mme_associated_nb -= 1; + break; + case S1AP_ENB_STATE_DISCONNECTED: + default: + break; + } + RB_REMOVE(s1ap_mme_map, &s1ap->s1ap_mme_head, mme); + + return 0; +} + + int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){ if (!rrc_is_present(mod_id)) return -1; s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index ce32883852..3c2803d663 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -832,6 +832,12 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM /* Get the S1AP UE conf */ int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf); +/* Add MMEs and re-issue S1AP Registration Request */ +int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); + +/* Remove MMEs and and cut SCTP to MME */ +int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); + /********************* general information *****************/ /* get an ID for this BS (or part of a BS) */ uint64_t flexran_get_bs_id(mid_t mod_id); From f895a28645b277bfb3c061789594044839a6751a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 13:40:50 +0200 Subject: [PATCH 027/171] FlexRAN: Manage PLMNs --- .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.c | 24 +++++++ .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.h | 6 ++ openair2/ENB_APP/flexran_agent_common.c | 6 ++ openair2/ENB_APP/flexran_agent_ran_api.c | 71 +++++++++++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 3 + 5 files changed, 110 insertions(+) diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c index d5fc5627a0..c2d7cb9e55 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c @@ -158,6 +158,30 @@ void flexran_agent_handle_mme_update(mid_t mod_id, } } +void flexran_agent_handle_plmn_update(mid_t mod_id, + int CC_id, + size_t n_plmn, + Protocol__FlexPlmn **plmn_id) { + if (n_plmn < 1 || n_plmn > 6) { + LOG_E(FLEXRAN_AGENT, "cannot handle %lu PLMNs\n", n_plmn); + return; + } + + /* We assume the controller has checked all the parameters within each + * plmn_id */ + int rc = flexran_set_new_plmn_id(mod_id, CC_id, n_plmn, plmn_id); + if (rc == 0) { + LOG_I(FLEXRAN_AGENT, "set %lu new PLMNs:\n", n_plmn); + for (int i = 0; i < (int)n_plmn; ++i) + LOG_I(FLEXRAN_AGENT, " MCC %d MNC %d MNC length %d\n", + plmn_id[i]->mcc, plmn_id[i]->mnc, plmn_id[0]->mnc_length); + } else { + LOG_W(FLEXRAN_AGENT, + "could not set new PLMN configuration: flexran_set_new_plmn_id() returned %d\n", + rc); + } +} + int flexran_agent_register_s1ap_xface(mid_t mod_id) { if (agent_s1ap_xface[mod_id]) { LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h index 54ea2926a8..006eaa1d3c 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h @@ -65,6 +65,12 @@ void flexran_agent_handle_mme_update(mid_t mod_id, size_t n_mme, Protocol__FlexS1apMme **mme); +/* Set a new PLMN configuration */ +void flexran_agent_handle_plmn_update(mid_t mod_id, + int CC_id, + size_t n_plmn, + Protocol__FlexPlmn **plmn_id); + /* Register technology specific interface callbacks */ int flexran_agent_register_s1ap_xface(mid_t mod_id); diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index ec0b780a3a..e77b2fb386 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -915,6 +915,12 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (rc < 0) LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network"); } + if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->n_plmn_id > 0) { + flexran_agent_handle_plmn_update(mod_id, + 0, + enb_config->cell_config[0]->n_plmn_id, + enb_config->cell_config[0]->plmn_id); + } } if (flexran_agent_get_s1ap_xface(mod_id) && enb_config->s1ap) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 3306dfe61b..0fcc51782e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3724,6 +3724,77 @@ int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { return 0; } +int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id) { + if (!rrc_is_present(mod_id)) + return -1; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) + return -2; + + eNB_RRC_INST *rrc = RC.rrc[CC_id]; + RrcConfigurationReq *conf = &rrc->configuration; + + uint8_t num_plmn_old = conf->num_plmn; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + for (int i = 0; i < num_plmn_old; ++i) { + mcc[i] = conf->mcc[i]; + mnc[i] = conf->mnc[i]; + mnc_digit_length[i] = conf->mnc_digit_length[i]; + } + + conf->num_plmn = (uint8_t) n_plmn; + for (int i = 0; i < conf->num_plmn; ++i) { + conf->mcc[i] = plmn_id[i]->mcc; + conf->mnc[i] = plmn_id[i]->mnc; + conf->mnc_digit_length[i] = plmn_id[i]->mnc_length; + } + + rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id]; + extern uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, + int Mod_id, + int CC_id, + BOOLEAN_t brOption, + RrcConfigurationReq *configuration); + carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, FALSE, conf); + if (carrier->sizeof_SIB1 < 0) + return -1337; /* SIB1 encoding failed, hell will probably break loose */ + + s1ap->num_plmn = (uint8_t) n_plmn; + for (int i = 0; i < conf->num_plmn; ++i) { + s1ap->mcc[i] = plmn_id[i]->mcc; + s1ap->mnc[i] = plmn_id[i]->mnc; + s1ap->mnc_digit_length[i] = plmn_id[i]->mnc_length; + } + + int bpn_failed = 0; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { + for (int i = 0; i < mme->broadcast_plmn_num; ++i) { + /* search the new index and update. If we don't find, we count this using + * bpn_failed to now how many broadcast_plmns could not be updated */ + int idx = mme->broadcast_plmn_index[i]; + int omcc = mcc[idx]; + int omnc = mnc[idx]; + int omncl = mnc_digit_length[idx]; + int j = 0; + for (j = 0; j < s1ap->num_plmn; ++j) { + if (s1ap->mcc[j] == omcc + && s1ap->mnc[j] == omnc + && s1ap->mnc_digit_length[j] == omncl) { + mme->broadcast_plmn_index[i] = j; + break; + } + } + if (j == s1ap->num_plmn) /* could not find the old PLMN in the new ones */ + bpn_failed++; + } + } + if (bpn_failed > 0) + return -10000 - bpn_failed; + return 0; +} int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){ if (!rrc_is_present(mod_id)) return -1; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 3c2803d663..9d1bfb9d3e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -838,6 +838,9 @@ int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); /* Remove MMEs and and cut SCTP to MME */ int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); +/* Set a new PLMN configuration */ +int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id); + /********************* general information *****************/ /* get an ID for this BS (or part of a BS) */ uint64_t flexran_get_bs_id(mid_t mod_id); From d2cc43b4e772de499a406f0e199e1c26851d42d3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 14 Apr 2020 14:47:27 +0200 Subject: [PATCH 028/171] UE: Print all SIB1 decoded PLMNs --- openair2/RRC/LTE/rrc_UE.c | 65 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 4116f5367e..53348f5621 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -2794,44 +2794,43 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); - LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity; - int mccdigits = PLMN_identity->mcc->list.count; - int mncdigits = PLMN_identity->mnc.list.count; - int mcc; + const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; + for (int i = 0; i < n; ++i) { + LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->plmn_Identity; + int mccdigits = PLMN_identity->mcc->list.count; + int mncdigits = PLMN_identity->mnc.list.count; - if (mccdigits == 2) { - mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; - } else { - mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; + int mcc; + if (mccdigits == 2) { + mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; + } else { + mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; + } + + int mnc; + if (mncdigits == 2) { + mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; + } else { + mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; + } + + LOG_I( RRC, "PLMN %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc); + // search internal table for provider name + int plmn_ind = 0; + + while (plmn_data[plmn_ind].mcc > 0) { + if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { + LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); + break; + } + + plmn_ind++; + } } - - int mnc; - - if (mncdigits == 2) { - mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; - } else { - mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; - } - - LOG_I( RRC, "PLMN MCC %0*d, MNC %0*d, TAC 0x%04x\n", mccdigits, mcc, mncdigits, mnc, + LOG_I( RRC, "TAC 0x%04x\n", ((sib1->cellAccessRelatedInfo.trackingAreaCode.size == 2)?((sib1->cellAccessRelatedInfo.trackingAreaCode.buf[0]<<8) + sib1->cellAccessRelatedInfo.trackingAreaCode.buf[1]):0)); LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse, SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) ); - // search internal table for provider name - int plmn_ind = 0; - - while (plmn_data[plmn_ind].mcc > 0) { - if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { - LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); - break; - } - - plmn_ind++; - } - - if (plmn_data[plmn_ind].mcc < 0) { - LOG_I( RRC, "Found Unknown operator (no entry in internal table)\n" ); - } LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n", BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.cellIdentity ), From 9d5a46dcfa12985d5e52b8066bdfa6b696e008ef Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 14 Apr 2020 14:47:59 +0200 Subject: [PATCH 029/171] UE: Set correct selected PLMN Identity --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 4 ++-- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 6 +++++- openair2/RRC/LTE/rrc_UE.c | 26 +++++++++++++++++++++----- openair2/RRC/LTE/rrc_defs.h | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 583e10da94..9ede543003 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -2310,7 +2310,7 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_Destin return((enc_rval.encoded+7)/8); } -uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) { +uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) { asn_enc_rval_t enc_rval; LTE_UL_DCCH_Message_t ul_dcch_msg; LTE_RRCConnectionSetupComplete_t *rrcConnectionSetupComplete; @@ -2323,7 +2323,7 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin rrcConnectionSetupComplete->criticalExtensions.choice.c1.present = LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension)); - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1; + rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= sel_plmn_id; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME = NULL;//calloc(1,sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME)); /* diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index dda2340610..640d18a61f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -142,7 +142,11 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_Destina /** \brief Generate an RRCConnectionSetupComplete UL-DCCH-Message (UE) @param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU @returns Size of encoded bit stream in bytes*/ -uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, +uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, + uint8_t *buffer, + const uint8_t Transaction_id, + uint8_t sel_plmn_id, + const int dedicatedInfoNASLength, const char *dedicatedInfoNAS); /** \brief Generate an RRCConnectionReconfigurationComplete UL-DCCH-Message (UE) diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 53348f5621..bdf992c76a 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -128,8 +128,13 @@ static int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t * \param ctxt_pP Running context * \param eNB_index Index of corresponding eNB/CH * \param Transaction_id Transaction identifier + * \param sel_plmn_id selected PLMN Identity */ -static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ); +static void rrc_ue_generate_RRCConnectionSetupComplete( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t eNB_index, + const uint8_t Transaction_id, + uint8_t sel_plmn_id); /** \brief Generates/Encodes RRCConnectionReconfigurationComplete message at UE * \param ctxt_pP Running context @@ -367,6 +372,7 @@ char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_ rrc_set_state (ue_mod_idP, RRC_STATE_INACTIVE); rrc_set_sub_state (ue_mod_idP, RRC_SUB_STATE_INACTIVE); LOG_I(RRC,"[UE %d] INIT State = RRC_IDLE (eNB %d)\n",ctxt.module_id,eNB_index); + UE_rrc_inst[ctxt.module_id].selected_plmn_identity = 1; UE_rrc_inst[ctxt.module_id].Info[eNB_index].State=RRC_IDLE; UE_rrc_inst[ctxt.module_id].Info[eNB_index].T300_active = 0; UE_rrc_inst[ctxt.module_id].Info[eNB_index].T304_active = 0; @@ -490,7 +496,11 @@ rrc_t310_expiration( } //----------------------------------------------------------------------------- -static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) { +static void rrc_ue_generate_RRCConnectionSetupComplete( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t eNB_index, + const uint8_t Transaction_id, + uint8_t sel_plmn_id) { uint8_t buffer[100]; uint8_t size; const char *nas_msg; @@ -504,7 +514,7 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *c nas_msg_length = sizeof(nas_attach_req_imsi); } - size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, nas_msg_length, nas_msg); + size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); LOG_D(RLC, @@ -624,7 +634,8 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const SRB_INFO *co rrc_ue_generate_RRCConnectionSetupComplete( ctxt_pP, eNB_index, - dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier); + dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier, + UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); rval = 0; break; @@ -2969,6 +2980,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp; itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); cell_valid = 1; + UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1; break; } } @@ -2979,7 +2991,11 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); - LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); + LOG_E(RRC, + "Synched with a cell, but PLMN doesn't match our SIM " + "(selected_plmn_identity %d), the message PHY_FIND_NEXT_CELL_REQ " + "is sent but lost in current UE implementation!\n", + UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); } } diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index 42fa5f6de1..03b6c759b6 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -808,6 +808,7 @@ typedef struct UE_RRC_INST_s { Rrc_Sub_State_t RrcSubState; plmn_t plmnID; Byte_t rat; + uint8_t selected_plmn_identity; as_nas_info_t initialNasMsg; OAI_UECapability_t *UECap; uint8_t *UECapability; From 476d58a8deef0f15ce3a59870e4cc80a122313e8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 21 May 2020 21:18:26 +0200 Subject: [PATCH 030/171] Log TBS in every window --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 7621994ab2..2382af3636 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -588,6 +588,7 @@ schedule_ue_spec(module_id_t module_idP, UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id]; eNB_UE_STATS *eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id]; + eNB_UE_stats->TBS = 0; const rnti_t rnti = ue_template->rnti; // If TDD @@ -799,6 +800,7 @@ schedule_ue_spec(module_id_t module_idP, eNB_UE_stats->rbs_used_retx = nb_rb; eNB_UE_stats->total_rbs_used_retx += nb_rb; eNB_UE_stats->dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + eNB_UE_stats->TBS = TBS; } else { // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request From 71647eb4effe80bf5defada0e314acbd4e98f7a1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 12 Jun 2020 19:25:44 +0200 Subject: [PATCH 031/171] DLSCH: limit LC bytes according to preprocessor --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 2382af3636..c35af34a7f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -844,13 +844,18 @@ schedule_ue_spec(module_id_t module_idP, if (ue_sched_ctrl->dl_lc_bytes[i] == 0) // no data in this LC! continue; - LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + const uint32_t data = + min(ue_sched_ctrl->dl_lc_bytes[i], + TBS - ta_len - header_length_total - sdu_length_total - 3); + LOG_D(MAC, + "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d " + "bytes from RLC (RRC message)\n", module_idP, frameP, subframeP, lcid, CC_id, - TBS - ta_len - header_length_total - sdu_length_total - 3); + data); sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, @@ -859,7 +864,7 @@ schedule_ue_spec(module_id_t module_idP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3, + data, (char *)&dlsch_buffer[sdu_length_total], 0, 0 From b06dadbdb0d25162149d016650740f2b6a75f3e2 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 24 Jun 2020 14:24:02 +0200 Subject: [PATCH 032/171] Bugfix DLSCH: only warn when retx with less RB The preprocessor pre-allocates a CCE. Thus, when arriving at the check for the number of RBs for retransmission, it is too late to skip the UE. Therefore, only print a warning. The default schedulers allocate a correct amount of RBs for retransmissions, therefore it is ok. --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index c35af34a7f..783d4e8b1a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -680,15 +680,15 @@ schedule_ue_spec(module_id_t module_idP, const uint32_t rbc = allocate_prbs_sub( nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]); - if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id]) { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id]) + LOG_W(MAC, + "[eNB %d] %d.%d CC_id %d : should not schedule UE %d, its " + "retransmission takes more resources than we have\n", module_idP, frameP, + subframeP, CC_id, UE_id); - continue; - } /* CDRX */ ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer From 1401d21081805d42f45ced99becbb2dbd5907ee8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 20 May 2020 12:45:35 +0200 Subject: [PATCH 033/171] Default SCHED RR algo: optimize algo and defer RB calc. - Loop only to next UE instead of jumping multiple - mark used RBGs in rbg_mask - Only calculate number of RBs based on CQI when UE is selected, instead of calculating for all UEs which might be unnecessary. - When looping the list of UEs for RB allocation, remove UEs that have no data anymore instead of skipping them. --- openair2/LAYER2/MAC/pre_processor.c | 72 ++++++++++------------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 8569d8f166..d4e39b2b6b 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -86,9 +86,6 @@ int round_robin_dl(module_id_t Mod_id, int num_ue_req = 0; UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; - int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request - memset(rb_required, 0, sizeof(rb_required)); - int rbg = 0; for (; !rbgalloc_mask[rbg]; rbg++) ; /* fast-forward to first allowed RBG */ @@ -133,6 +130,7 @@ int round_robin_dl(module_id_t Mod_id, if (!rbgalloc_mask[rbg]) continue; ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; nb_rbg--; } LOG_D(MAC, @@ -150,22 +148,8 @@ int round_robin_dl(module_id_t Mod_id, return n_rbg_sched; for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { - const int dlsch_mcs1 = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; - UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = dlsch_mcs1; - rb_required[UE_id] = - find_nb_rb_DL(dlsch_mcs1, - UE_info->UE_template[CC_id][UE_id].dl_buffer_total, - n_rbg_sched * RBGsize, - RBGsize); - if (rb_required[UE_id] > 0) + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) num_ue_req++; - LOG_D(MAC, - "%d/%d UE_id %d rb_required %d n_rbg_sched %d\n", - frame, - subframe, - UE_id, - rb_required[UE_id], - n_rbg_sched); } } @@ -178,12 +162,13 @@ int round_robin_dl(module_id_t Mod_id, g_start_ue_dl = UE_list->head; int UE_id = g_start_ue_dl; UE_list_t UE_sched; - int rb_required_total = 0; + int *cur_UE = &UE_sched.head; + int num_ue_sched = 0; max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); - int *cur_UE = &UE_sched.head; + int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request while (num_ue_sched < max_num_ue) { - while (rb_required[UE_id] == 0) + while (UE_info->UE_template[CC_id][UE_id].dl_buffer_total <= 0) UE_id = next_ue_list_looped(UE_list, UE_id); const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); @@ -195,42 +180,42 @@ int round_robin_dl(module_id_t Mod_id, continue; } UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; + const int mcs = cqi_to_mcs[cqi]; + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; + const uint32_t B = UE_info->UE_template[CC_id][UE_id].dl_buffer_total; + rb_required[UE_id] = find_nb_rb_DL(mcs, B, n_rbg_sched * RBGsize, RBGsize); *cur_UE = UE_id; cur_UE = &UE_sched.next[UE_id]; - rb_required_total += rb_required[UE_id]; num_ue_sched++; UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate } *cur_UE = -1; /* for one UE after the next: allocate resources */ - for (int UE_id = UE_sched.head; UE_id >= 0; - UE_id = next_ue_list_looped(&UE_sched, UE_id)) { - if (rb_required[UE_id] <= 0) - continue; + cur_UE = &UE_sched.head; + while (*cur_UE >= 0) { + const int UE_id = *cur_UE; UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize; ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG; rb_required[UE_id] -= sRBG; - rb_required_total -= sRBG; - if (rb_required_total <= 0) - break; + if (rb_required[UE_id] <= 0) { + *cur_UE = UE_sched.next[*cur_UE]; + if (*cur_UE < 0) + cur_UE = &UE_sched.head; + } else { + cur_UE = UE_sched.next[*cur_UE] < 0 ? &UE_sched.head : &UE_sched.next[*cur_UE]; + } n_rbg_sched--; if (n_rbg_sched <= 0) break; for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - /* if not all UEs could be allocated in this round */ - if (num_ue_req > max_num_ue) { - /* go to the first one we missed */ - for (int i = 0; i < max_num_ue; ++i) - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); - } else { - /* else, just start with the next UE next time */ - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); - } + /* just start with the next UE next time */ + g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); return n_rbg_sched; } @@ -730,15 +715,8 @@ int round_robin_ul(module_id_t Mod_id, } } - /* if not all UEs could be allocated in this round */ - if (num_ue_req > max_num_ue) { - /* go to the first one we missed */ - for (int i = 0; i < max_num_ue; ++i) - g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); - } else { - /* else, just start with the next UE next time */ - g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); - } + /* just start with the next UE next time */ + g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0); } From 31ad66e146b0ceaabe45688e43bf9ae131bfd8ce Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 24 Jun 2020 14:20:27 +0200 Subject: [PATCH 034/171] Bugfix RR DL: a retx UE might not be allocated again --- openair2/LAYER2/MAC/pre_processor.c | 68 ++++++++++++++--------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index d4e39b2b6b..eea3b55f6e 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -83,15 +83,22 @@ int round_robin_dl(module_id_t Mod_id, const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); const int RBGsize = get_min_rb_unit(Mod_id, CC_id); const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); - int num_ue_req = 0; UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; int rbg = 0; for (; !rbgalloc_mask[rbg]; rbg++) ; /* fast-forward to first allowed RBG */ - // Calculate the amount of RBs every UE wants to send. - for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + /* just start with the UE after the one we had last time. If it does not + * exist, this will start at the head */ + int g_start_ue_dl = data; + g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); + + int UE_id = g_start_ue_dl; + UE_list_t UE_sched; + int *cur_UE = &UE_sched.head; + // Allocate retransmissions, and mark UEs with new transmissions + do { // check whether there are HARQ retransmissions const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); @@ -100,14 +107,14 @@ int round_robin_dl(module_id_t Mod_id, if (round != 8) { // retransmission: allocate const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; if (nb_rb == 0) - continue; + goto skip_ue; int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; // needs more RBGs than we can allocate if (nb_rbg > n_rbg_sched) { LOG_D(MAC, "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", UE_id, nb_rbg, n_rbg_sched); - continue; + goto skip_ue; } // ensure that the number of RBs can be contained by the RBGs (!), i.e. // if we allocate the last RBG this one should have the full RBGsize @@ -116,12 +123,12 @@ int round_robin_dl(module_id_t Mod_id, LOG_D(MAC, "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); - continue; + goto skip_ue; } const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); if (idx < 0) - continue; // cannot allocate CCE + goto skip_ue; // cannot allocate CCE ue_ctrl->pre_dci_dl_pdu_idx = idx; // retransmissions: directly allocate n_rbg_sched -= nb_rbg; @@ -148,35 +155,32 @@ int round_robin_dl(module_id_t Mod_id, return n_rbg_sched; for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { - if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) - num_ue_req++; + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) { + *cur_UE = UE_id; + cur_UE = &UE_sched.next[UE_id]; + } } - } - if (num_ue_req == 0) +skip_ue: + UE_id = next_ue_list_looped(UE_list, UE_id); + } while (UE_id != g_start_ue_dl); + *cur_UE = -1; // mark end + + if (UE_sched.head < 0) return n_rbg_sched; // no UE has a transmission - // after allocating retransmissions: build list of UE to allocate. - // if start_UE does not exist anymore (detach etc), start at first UE - if (g_start_ue_dl == -1) - g_start_ue_dl = UE_list->head; - int UE_id = g_start_ue_dl; - UE_list_t UE_sched; - int *cur_UE = &UE_sched.head; - - int num_ue_sched = 0; - max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); + // after allocating retransmissions: pre-allocate CCE, compute number of + // requested RBGs + max_num_ue = min(max_num_ue, n_rbg_sched); int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request - while (num_ue_sched < max_num_ue) { - while (UE_info->UE_template[CC_id][UE_id].dl_buffer_total <= 0) - UE_id = next_ue_list_looped(UE_list, UE_id); + cur_UE = &UE_sched.head; + while (*cur_UE >= 0 && max_num_ue > 0) { + const int UE_id = *cur_UE; + cur_UE = &UE_sched.next[UE_id]; // go to next const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); if (idx < 0) { LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", UE_id); - num_ue_req--; - max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); - UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate continue; } UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; @@ -184,12 +188,9 @@ int round_robin_dl(module_id_t Mod_id, UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; const uint32_t B = UE_info->UE_template[CC_id][UE_id].dl_buffer_total; rb_required[UE_id] = find_nb_rb_DL(mcs, B, n_rbg_sched * RBGsize, RBGsize); - *cur_UE = UE_id; - cur_UE = &UE_sched.next[UE_id]; - num_ue_sched++; - UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate + max_num_ue--; } - *cur_UE = -1; + *cur_UE = -1; // not all UEs might be allocated, mark end /* for one UE after the next: allocate resources */ cur_UE = &UE_sched.head; @@ -214,9 +215,6 @@ int round_robin_dl(module_id_t Mod_id, for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - /* just start with the next UE next time */ - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); - return n_rbg_sched; } From dc5357ca13d6dda0768e047168522c503bf3fb4a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 17 Jun 2020 11:05:35 +0200 Subject: [PATCH 035/171] Format to dynamically handle default DL SCHED algo --- openair2/LAYER2/MAC/mac.h | 15 +++++++ openair2/LAYER2/MAC/main.c | 6 ++- openair2/LAYER2/MAC/pre_processor.c | 69 +++++++++++++++++++---------- 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 329e262c82..0264951683 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1274,6 +1274,19 @@ typedef struct { int length; } contig_rbs_t; +/** + * definition of a scheduling algorithm implementation used in the + * default scheduler + */ +typedef struct { + char *name; + void *(*setup)(void); + void (*unset)(void **); + int (*run)( + module_id_t, int, int, int, UE_list_t *, int, int, uint8_t *, void *); + void *data; +} default_sched_dl_algo_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1432,6 +1445,8 @@ typedef struct eNB_MAC_INST_s { UE_free_list_t UE_free_list; /// for scheduling selection SCHEDULER_MODES scheduler_mode; + /// scheduling algorithm used in default scheduler + default_sched_dl_algo_t dl_algo; int32_t puSch10xSnr; int32_t puCch10xSnr; diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 1a88623a1f..39e342cba0 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -128,7 +128,11 @@ void mac_top_init_eNB(void) } mac[i]->if_inst = IF_Module_init(i); - + char *s = "round_robin_dl"; + void *d = dlsym(NULL, s); + AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); + mac[i]->dl_algo = *(default_sched_dl_algo_t *) d; + mac[i]->dl_algo.data = mac[i]->dl_algo.setup(); init_UE_info(&mac[i]->UE_info); init_slice_info(&mac[i]->slice_info); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index eea3b55f6e..8c4b91ce87 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -69,15 +69,26 @@ int get_rbg_size_last(module_id_t Mod_id, int CC_id) { return RBGsize; } -int g_start_ue_dl = -1; -int round_robin_dl(module_id_t Mod_id, - int CC_id, - int frame, - int subframe, - UE_list_t *UE_list, - int max_num_ue, - int n_rbg_sched, - uint8_t *rbgalloc_mask) { +void *rr_dl_setup(void) { + void *data = malloc(sizeof(int)); + *(int *) data = 0; + AssertFatal(data, "could not allocate data in %s()\n", __func__); + return data; +} +void rr_dl_unset(void **data) { + if (*data) + free(*data); + *data = NULL; +} +int rr_dl_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + UE_list_t *UE_list, + int max_num_ue, + int n_rbg_sched, + uint8_t *rbgalloc_mask, + void *data) { DevAssert(UE_list->head >= 0); DevAssert(n_rbg_sched > 0); const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); @@ -91,10 +102,10 @@ int round_robin_dl(module_id_t Mod_id, /* just start with the UE after the one we had last time. If it does not * exist, this will start at the head */ - int g_start_ue_dl = data; - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); + int *start_ue = data; + *start_ue = next_ue_list_looped(UE_list, *start_ue); - int UE_id = g_start_ue_dl; + int UE_id = *start_ue; UE_list_t UE_sched; int *cur_UE = &UE_sched.head; // Allocate retransmissions, and mark UEs with new transmissions @@ -163,7 +174,7 @@ int round_robin_dl(module_id_t Mod_id, skip_ue: UE_id = next_ue_list_looped(UE_list, UE_id); - } while (UE_id != g_start_ue_dl); + } while (UE_id != *start_ue); *cur_UE = -1; // mark end if (UE_sched.head < 0) @@ -217,6 +228,14 @@ skip_ue: return n_rbg_sched; } +default_sched_dl_algo_t round_robin_dl = { + .name = "round_robin_dl", + .setup = rr_dl_setup, + .unset = rr_dl_unset, + .run = rr_dl_run, + .data = NULL +}; + // This function stores the downlink buffer for all the logical channels void @@ -294,8 +313,9 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, int CC_id, frame_t frameP, sub_frame_t subframeP) { - UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; - const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + eNB_MAC_INST *mac = RC.mac[Mod_id]; + UE_info_t *UE_info = &mac->UE_info; + const int N_RBG = to_rbg(mac->common_channels[CC_id].mib->message.dl_Bandwidth); const int RBGsize = get_min_rb_unit(Mod_id, CC_id); store_dlsch_buffer(Mod_id, CC_id, frameP, subframeP); @@ -352,7 +372,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, if (UE_to_sched.head < 0) return; - uint8_t *vrb_map = RC.mac[Mod_id]->common_channels[CC_id].vrb_map; + uint8_t *vrb_map = mac->common_channels[CC_id].vrb_map; uint8_t rbgalloc_mask[N_RBG_MAX]; int n_rbg_sched = 0; for (int i = 0; i < N_RBG; i++) { @@ -364,14 +384,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, n_rbg_sched += rbgalloc_mask[i]; } - round_robin_dl(Mod_id, - CC_id, - frameP, - subframeP, - &UE_to_sched, - 4, // max_num_ue - n_rbg_sched, - rbgalloc_mask); + mac->dl_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + &UE_to_sched, + 4, // max_num_ue + n_rbg_sched, + rbgalloc_mask, + mac->dl_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for From a0b331415fc13ca49f5afbb9203f9ad5ee1fc83c Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 May 2020 16:17:52 +0200 Subject: [PATCH 036/171] Add Proportional Fair scheduler, wbCqi Selects UE with highest coefficient. Allocates until there are no more RBGs to allocate, or UE has no more data. In the latter case, continues with the next UE (second-highest coefficient). --- openair2/LAYER2/MAC/pre_processor.c | 164 ++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 8c4b91ce87..5c2b72d199 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -237,6 +237,170 @@ default_sched_dl_algo_t round_robin_dl = { }; +void *pf_dl_setup(void) { + void *data = calloc(MAX_MOBILES_PER_ENB, sizeof(float)); + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) + *(float *) data = 0.0f; + AssertFatal(data, "could not allocate data in %s()\n", __func__); + return data; +} +void pf_dl_unset(void **data) { + if (*data) + free(*data); + *data = NULL; +} +int pf_wbcqi_dl_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + UE_list_t *UE_list, + int max_num_ue, + int n_rbg_sched, + uint8_t *rbgalloc_mask, + void *data) { + DevAssert(UE_list->head >= 0); + DevAssert(n_rbg_sched > 0); + const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + const int RBGsize = get_min_rb_unit(Mod_id, CC_id); + const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); + UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; + + int rbg = 0; + for (; !rbgalloc_mask[rbg]; rbg++) + ; /* fast-forward to first allowed RBG */ + + UE_list_t UE_sched; // UEs that could be scheduled + int *uep = &UE_sched.head; + float *thr_ue = data; + float coeff_ue[MAX_MOBILES_PER_ENB]; + + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + const float a = 0.0005f; // corresponds to 200ms window + const uint32_t b = UE_info->eNB_UE_stats[CC_id][UE_id].TBS; + thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b; + + // check whether there are HARQ retransmissions + const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const uint8_t round = ue_ctrl->round[CC_id][harq_pid]; + if (round != 8) { // retransmission: allocate + const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + if (nb_rb == 0) + continue; + int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; + // needs more RBGs than we can allocate + if (nb_rbg > n_rbg_sched) { + LOG_D(MAC, + "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", + UE_id, nb_rbg, n_rbg_sched); + continue; + } + // ensure that the number of RBs can be contained by the RBGs (!), i.e. + // if we allocate the last RBG this one should have the full RBGsize + if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched + && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { + LOG_D(MAC, + "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", + UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); + continue; + } + const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; // cannot allocate CCE + ue_ctrl->pre_dci_dl_pdu_idx = idx; + // retransmissions: directly allocate + n_rbg_sched -= nb_rbg; + ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; + for (; nb_rbg > 0; rbg++) { + if (!rbgalloc_mask[rbg]) + continue; + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + nb_rbg--; + } + LOG_D(MAC, + "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " + "round %d retx nb_rb %d pre_nb_available_rbs %d\n", + frame, subframe, n_rbg_sched, UE_id, round, + UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], + ue_ctrl->pre_nb_available_rbs[CC_id]); + /* if there are no more RBG to give, return */ + if (n_rbg_sched <= 0) + return 0; + max_num_ue--; + /* if there are no UEs that can be allocated anymore, return */ + if (max_num_ue == 0) + return n_rbg_sched; + for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } else { + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0) + continue; + + const int mcs = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; + const uint32_t tbs = get_TBS_DL(mcs, RBGsize); + coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id]; + //LOG_I(MAC, " pf UE %d: old TBS %d thr %f MCS %d TBS %d coeff %f\n", + // UE_id, b, thr_ue[UE_id], mcs, tbs, coeff_ue[UE_id]); + *uep = UE_id; + uep = &UE_sched.next[UE_id]; + } + } + *uep = -1; + + while (max_num_ue > 0 && n_rbg_sched > 0 && UE_sched.head >= 0) { + int *max = &UE_sched.head; /* assume head is max */ + int *p = &UE_sched.next[*max]; + while (*p >= 0) { + /* if the current one has larger coeff, save for later */ + if (coeff_ue[*p] > coeff_ue[*max]) + max = p; + p = &UE_sched.next[*p]; + } + /* remove the max one */ + const int UE_id = *max; + p = &UE_sched.next[*max]; + *max = UE_sched.next[*max]; + *p = -1; + + const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; + UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; + + max_num_ue--; + + /* allocate as much as possible */ + const int mcs = cqi_to_mcs[cqi]; + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; + int req = find_nb_rb_DL(mcs, + UE_info->UE_template[CC_id][UE_id].dl_buffer_total, + n_rbg_sched * RBGsize, + RBGsize); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + while (req > 0 && n_rbg_sched > 0) { + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize; + ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG; + req -= sRBG; + n_rbg_sched--; + for (rbg++; n_rbg_sched > 0 && !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } + } + + return n_rbg_sched; +} +default_sched_dl_algo_t proportional_fair_wbcqi_dl = { + .name = "proportional_fair_wbcqi_dl", + .setup = pf_dl_setup, + .unset = pf_dl_unset, + .run = pf_wbcqi_dl_run, + .data = NULL +}; + // This function stores the downlink buffer for all the logical channels void store_dlsch_buffer(module_id_t Mod_id, From 36cd697b626a6133d9c0eecb1dfb8a659640fa4b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 22 May 2020 16:43:24 +0200 Subject: [PATCH 037/171] Add Maximum Throughput scheduler, wbCqi Selects the UE with the highest CQI. If two UEs have the same CQI, choses the one with highest number of bytes in RLC queue. Allocates as many RBGs as possible, and potentially continues with the next UE. --- openair2/LAYER2/MAC/pre_processor.c | 150 ++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 5c2b72d199..e7adbb7c80 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -401,6 +401,156 @@ default_sched_dl_algo_t proportional_fair_wbcqi_dl = { .data = NULL }; +void *mt_dl_setup(void) { + return NULL; +} +void mt_dl_unset(void **data) { + *data = NULL; +} +int mt_wbcqi_dl_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + UE_list_t *UE_list, + int max_num_ue, + int n_rbg_sched, + uint8_t *rbgalloc_mask, + void *data) { + DevAssert(UE_list->head >= 0); + DevAssert(n_rbg_sched > 0); + const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + const int RBGsize = get_min_rb_unit(Mod_id, CC_id); + const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); + UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; + + int rbg = 0; + for (; !rbgalloc_mask[rbg]; rbg++) + ; /* fast-forward to first allowed RBG */ + + UE_list_t UE_sched; // UEs that could be scheduled + int *uep = &UE_sched.head; + + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + // check whether there are HARQ retransmissions + const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const uint8_t round = ue_ctrl->round[CC_id][harq_pid]; + if (round != 8) { // retransmission: allocate + const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + if (nb_rb == 0) + continue; + int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; + // needs more RBGs than we can allocate + if (nb_rbg > n_rbg_sched) { + LOG_D(MAC, + "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", + UE_id, nb_rbg, n_rbg_sched); + continue; + } + // ensure that the number of RBs can be contained by the RBGs (!), i.e. + // if we allocate the last RBG this one should have the full RBGsize + if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched + && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { + LOG_D(MAC, + "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", + UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); + continue; + } + const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; // cannot allocate CCE + ue_ctrl->pre_dci_dl_pdu_idx = idx; + // retransmissions: directly allocate + n_rbg_sched -= nb_rbg; + ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; + for (; nb_rbg > 0; rbg++) { + if (!rbgalloc_mask[rbg]) + continue; + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + nb_rbg--; + } + LOG_D(MAC, + "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " + "round %d retx nb_rb %d pre_nb_available_rbs %d\n", + frame, subframe, n_rbg_sched, UE_id, round, + UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], + ue_ctrl->pre_nb_available_rbs[CC_id]); + /* if there are no more RBG to give, return */ + if (n_rbg_sched <= 0) + return 0; + max_num_ue--; + /* if there are no UEs that can be allocated anymore, return */ + if (max_num_ue == 0) + return n_rbg_sched; + for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } else { + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0) + continue; + *uep = UE_id; + uep = &UE_sched.next[UE_id]; + } + } + *uep = -1; + + while (max_num_ue > 0 && n_rbg_sched > 0 && UE_sched.head >= 0) { + int *max = &UE_sched.head; /* assume head is max */ + int *p = &UE_sched.next[*max]; + while (*p >= 0) { + /* if the current one has better CQI, or the same and more data */ + const uint8_t maxCqi = UE_info->UE_sched_ctrl[*max].dl_cqi[CC_id]; + const uint32_t maxB = UE_info->UE_template[CC_id][*max].dl_buffer_total; + const uint8_t pCqi = UE_info->UE_sched_ctrl[*p].dl_cqi[CC_id]; + const uint32_t pB = UE_info->UE_template[CC_id][*p].dl_buffer_total; + if (pCqi > maxCqi || (pCqi == maxCqi && pB > maxB)) + max = p; + p = &UE_sched.next[*p]; + } + /* remove the max one */ + const int UE_id = *max; + p = &UE_sched.next[*max]; + *max = UE_sched.next[*max]; + *p = -1; + + const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; + UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; + + max_num_ue--; + + /* allocate as much as possible */ + const int mcs = cqi_to_mcs[cqi]; + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; + int req = find_nb_rb_DL(mcs, + UE_info->UE_template[CC_id][UE_id].dl_buffer_total, + n_rbg_sched * RBGsize, + RBGsize); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + while (req > 0 && n_rbg_sched > 0) { + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize; + ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG; + req -= sRBG; + n_rbg_sched--; + for (rbg++; n_rbg_sched > 0 && !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } + } + + return n_rbg_sched; +} +default_sched_dl_algo_t maximum_throughput_wbcqi_dl = { + .name = "maximum_throughput_wbcqi_dl", + .setup = mt_dl_setup, + .unset = mt_dl_unset, + .run = mt_wbcqi_dl_run, + .data = NULL +}; + // This function stores the downlink buffer for all the logical channels void store_dlsch_buffer(module_id_t Mod_id, From 5d1d2bcd1c17e6e12d36e94f77babd8d7a8c4da5 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 17 Jun 2020 18:40:48 +0200 Subject: [PATCH 038/171] Configurable Default Scheduler DL Algo --- openair2/ENB_APP/MACRLC_paramdef.h | 3 +++ openair2/ENB_APP/enb_config.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h index 55ce9d5059..fcee6142f0 100644 --- a/openair2/ENB_APP/MACRLC_paramdef.h +++ b/openair2/ENB_APP/MACRLC_paramdef.h @@ -58,6 +58,7 @@ #define CONFIG_STRING_MACRLC_SCHED_MODE "scheduler_mode" #define CONFIG_MACRLC_PUSCH10xSNR "puSch10xSnr" #define CONFIG_MACRLC_PUCCH10xSNR "puCch10xSnr" +#define CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO "default_sched_dl_algo" /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* MacRLC configuration parameters */ @@ -84,6 +85,7 @@ {CONFIG_STRING_MACRLC_SCHED_MODE, NULL, 0, strptr:NULL, defstrval:"default", TYPE_STRING, 0}, \ {CONFIG_MACRLC_PUSCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {CONFIG_MACRLC_PUCCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ +{CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO, NULL, 0, strptr:NULL, defstrval:"round_robin_dl", TYPE_STRING, 0}, \ } #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 @@ -105,6 +107,7 @@ #define MACRLC_SCHED_MODE_IDX 17 #define MACRLC_PUSCH10xSNR_IDX 18 #define MACRLC_PUCCH10xSNR_IDX 19 +#define MACRLC_DEFAULT_SCHED_DL_ALGO_IDX 20 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 6dcc574746..3bde7da02c 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -29,6 +29,7 @@ #include #include +#include #include "common/utils/LOG/log.h" #include "assertions.h" @@ -260,6 +261,15 @@ void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) { global_scheduler_mode=SCHED_MODE_DEFAULT; printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); } + + char *s = *MacRLC_ParamList.paramarray[j][MACRLC_DEFAULT_SCHED_DL_ALGO_IDX].strptr; + void *d = dlsym(NULL, s); + AssertFatal(d, "%s(): no default scheduler DL algo '%s' found\n", __func__, s); + // release default, add new + RC.mac[j]->dl_algo.unset(&RC.mac[j]->dl_algo.data); + RC.mac[j]->dl_algo = *(default_sched_dl_algo_t *) d; + RC.mac[j]->dl_algo.data = RC.mac[j]->dl_algo.setup(); + LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", RC.mac[j]->dl_algo.name); }// j=0..num_inst } /*else {// MacRLC_ParamList.numelt > 0 // ignore it From 41de51b18744901df1368ae700b4b639d832d987 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jun 2020 17:32:01 +0200 Subject: [PATCH 039/171] Format to dynamically handle UL SCHED --- openair2/LAYER2/MAC/mac.h | 16 +++++- openair2/LAYER2/MAC/main.c | 5 ++ openair2/LAYER2/MAC/pre_processor.c | 79 ++++++++++++++++++----------- 3 files changed, 70 insertions(+), 30 deletions(-) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 0264951683..09585fae55 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1276,7 +1276,7 @@ typedef struct { /** * definition of a scheduling algorithm implementation used in the - * default scheduler + * default DL scheduler */ typedef struct { char *name; @@ -1287,6 +1287,19 @@ typedef struct { void *data; } default_sched_dl_algo_t; +/** + * definition of a scheduling algorithm implementation used in the + * default UL scheduler + */ +typedef struct { + char *name; + void *(*setup)(void); + void (*unset)(void **); + int (*run)( + module_id_t, int, int, int, int, int, UE_list_t *, int, int, contig_rbs_t *, void *); + void *data; +} default_sched_ul_algo_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1447,6 +1460,7 @@ typedef struct eNB_MAC_INST_s { SCHEDULER_MODES scheduler_mode; /// scheduling algorithm used in default scheduler default_sched_dl_algo_t dl_algo; + default_sched_ul_algo_t ul_algo; int32_t puSch10xSnr; int32_t puCch10xSnr; diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 39e342cba0..294eb12159 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -133,6 +133,11 @@ void mac_top_init_eNB(void) AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); mac[i]->dl_algo = *(default_sched_dl_algo_t *) d; mac[i]->dl_algo.data = mac[i]->dl_algo.setup(); + s = "round_robin_ul"; + d = dlsym(NULL, s); + AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); + mac[i]->ul_algo = *(default_sched_ul_algo_t *) d; + mac[i]->ul_algo.data = mac[i]->ul_algo.setup(); init_UE_info(&mac[i]->UE_info); init_slice_info(&mac[i]->slice_info); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index e7adbb7c80..72455f7125 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -818,17 +818,28 @@ int pp_find_rb_table_index(int approximate) { return p + 1; } -int g_start_ue_ul = -1; -int round_robin_ul(module_id_t Mod_id, - int CC_id, - int frame, - int subframe, - int sched_frame, - int sched_subframe, - UE_list_t *UE_list, - int max_num_ue, - int num_contig_rb, - contig_rbs_t *rbs) { +void *rr_ul_setup(void) { + void *data = malloc(sizeof(int)); + *(int *) data = 0; + AssertFatal(data, "could not allocate data in %s()\n", __func__); + return data; +} +void rr_ul_unset(void **data) { + if (*data) + free(*data); + *data = NULL; +} +int rr_ul_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + int sched_frame, + int sched_subframe, + UE_list_t *UE_list, + int max_num_ue, + int num_contig_rb, + contig_rbs_t *rbs, + void *data) { AssertFatal(num_contig_rb <= 2, "cannot handle more than two contiguous RB regions\n"); UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; const int max_rb = num_contig_rb > 1 ? MAX(rbs[0].length, rbs[1].length) : rbs[0].length; @@ -968,9 +979,10 @@ int round_robin_ul(module_id_t Mod_id, end = la > lb ? 2 : -1; } - if (g_start_ue_ul == -1) - g_start_ue_ul = UE_list->head; - int sUE_id = g_start_ue_ul; + int *start_ue = data; + if (*start_ue == -1) + *start_ue = UE_list->head; + int sUE_id = *start_ue; int rb_idx_given[MAX_MOBILES_PER_ENB]; memset(rb_idx_given, 0, sizeof(rb_idx_given)); @@ -1049,10 +1061,17 @@ int round_robin_ul(module_id_t Mod_id, } /* just start with the next UE next time */ - g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); + *start_ue = next_ue_list_looped(UE_list, *start_ue); return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0); } +default_sched_ul_algo_t round_robin_ul = { + .name = "round_robin_ul", + .setup = rr_ul_setup, + .unset = rr_ul_unset, + .run = rr_ul_run, + .data = NULL +}; void ulsch_scheduler_pre_processor(module_id_t Mod_id, int CC_id, @@ -1060,9 +1079,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, sub_frame_t subframeP, int sched_frameP, unsigned char sched_subframeP) { - UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; - const int N_RB_UL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].ul_Bandwidth); - COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + eNB_MAC_INST *mac = RC.mac[Mod_id]; + UE_info_t *UE_info = &mac->UE_info; + const int N_RB_UL = to_prb(mac->common_channels[CC_id].ul_Bandwidth); + COMMON_channels_t *cc = &mac->common_channels[CC_id]; UE_list_t UE_to_sched; UE_to_sched.head = -1; @@ -1119,16 +1139,17 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, } } - round_robin_ul(Mod_id, - CC_id, - frameP, - subframeP, - sched_frameP, - sched_subframeP, - &UE_to_sched, - 4, // max_num_ue - n_contig, - rbs); + mac->ul_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + sched_frameP, + sched_subframeP, + &UE_to_sched, + 4, // max_num_ue + n_contig, + rbs, + mac->ul_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for @@ -1147,7 +1168,7 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, continue; print = 1; - uint8_t harq_pid = subframe2harqpid(&RC.mac[Mod_id]->common_channels[CC_id], + uint8_t harq_pid = subframe2harqpid(&mac->common_channels[CC_id], sched_frameP, sched_subframeP); LOG_D(MAC, "%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s\n", frameP, From 9f26028ded0201efb7906c682568eb1519f4eb12 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jun 2020 10:27:45 +0200 Subject: [PATCH 040/171] Default pre-processor: efficiently build UE list --- openair2/LAYER2/MAC/pre_processor.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 72455f7125..5eb27699be 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -635,12 +635,10 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, store_dlsch_buffer(Mod_id, CC_id, frameP, subframeP); UE_list_t UE_to_sched; - UE_to_sched.head = -1; for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) UE_to_sched.next[i] = -1; + int *cur = &UE_to_sched.head; - int first = 1; - int last_UE_id = -1; for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; const UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id]; @@ -673,15 +671,10 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } /* define UEs to schedule */ - if (first) { - first = 0; - UE_to_sched.head = UE_id; - } else { - UE_to_sched.next[last_UE_id] = UE_id; - } - UE_to_sched.next[UE_id] = -1; - last_UE_id = UE_id; + *cur = UE_id; + cur = &UE_to_sched.next[UE_id]; } + *cur = -1; if (UE_to_sched.head < 0) return; @@ -1085,11 +1078,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, COMMON_channels_t *cc = &mac->common_channels[CC_id]; UE_list_t UE_to_sched; - UE_to_sched.head = -1; for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) UE_to_sched.next[i] = -1; + int *cur = &UE_to_sched.head; - int last_UE_id = -1; for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id]; UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; @@ -1112,13 +1104,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, continue; /* define UEs to schedule */ - if (UE_to_sched.head < 0) - UE_to_sched.head = UE_id; - else - UE_to_sched.next[last_UE_id] = UE_id; - UE_to_sched.next[UE_id] = -1; - last_UE_id = UE_id; + *cur = UE_id; + cur = &UE_to_sched.next[UE_id]; } + *cur = -1; if (UE_to_sched.head < 0) return; From 198822aa17cc47b8b563491f2a76bb0d4da51813 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 12:00:43 +0200 Subject: [PATCH 041/171] Remove any slice-related information from OAI --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 13 - .../MAC/flexran_agent_mac_internal.c | 28 +- .../flexran_agent_mac_slice_verification.c | 4 +- openair2/ENB_APP/flexran_agent_ran_api.c | 314 ++---------------- openair2/LAYER2/MAC/mac.h | 104 ------ openair2/LAYER2/MAC/mac_proto.h | 2 - openair2/LAYER2/MAC/main.c | 27 -- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 2 - 8 files changed, 39 insertions(+), 455 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 603ff25198..669eb33ea3 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -49,19 +49,6 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; -/* the slice config as kept in the underlying system */ -Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; -/* a structure that keeps updates which will be reflected in slice_config later */ -Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; -/* indicates whether sc_update contains new data */ -int perform_slice_config_update_count = 1; -/* queue of incoming new UE<>slice association commands */ -Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; -int n_ue_slice_assoc_updates = 0; -/* mutex for sc_update: do not receive new config and write it at the same time */ -pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER; - - int flexran_agent_mac_stats_reply_ue(mid_t mod_id, Protocol__FlexUeStatsReport **ue_report, int n_ue, diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index a85cbac543..84a28683b7 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -33,14 +33,6 @@ #include "flexran_agent_mac_internal.h" #include "flexran_agent_mac_slice_verification.h" -/* from flexran_agent_mac.c */ -extern Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; -extern Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; -extern int perform_slice_config_update_count; -extern Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; -extern int n_ue_slice_assoc_updates; -extern pthread_mutex_t sc_update_mtx; - Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message, Protocol__FlexranMessage *old_message) { @@ -1040,12 +1032,12 @@ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) if (!fsc) return NULL; protocol__flex_slice_config__init(fsc); - /* say there are n_dl slices but reserve memory for up to MAX_NUM_SLICES so + /* say there are n_dl slices but reserve memory for up to 10 so * we don't need to reserve again later */ fsc->n_dl = n_dl; - fsc->dl = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexDlSlice *)); + fsc->dl = calloc(10, sizeof(Protocol__FlexDlSlice *)); if (!fsc->dl) fsc->n_dl = 0; - for (i = 0; i < MAX_NUM_SLICES; i++) { + for (i = 0; i < 10; i++) { fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice)); if (!fsc->dl[i]) continue; protocol__flex_dl_slice__init(fsc->dl[i]); @@ -1053,9 +1045,9 @@ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) /* as above */ fsc->n_ul = m_ul; - fsc->ul = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexUlSlice *)); + fsc->ul = calloc(10, sizeof(Protocol__FlexUlSlice *)); if (!fsc->ul) fsc->n_ul = 0; - for (i = 0; i < MAX_NUM_SLICES; i++) { + for (i = 0; i < 10; i++) { fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice)); if (!fsc->ul[i]) continue; protocol__flex_ul_slice__init(fsc->ul[i]); @@ -1401,8 +1393,8 @@ Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id) mod_id, id); Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; sc_update[mod_id]->n_dl++; - AssertFatal(sc_update[mod_id]->n_dl <= MAX_NUM_SLICES, - "cannot create more than MAX_NUM_SLICES\n"); + AssertFatal(sc_update[mod_id]->n_dl <= 10, + "cannot create more than 10\n"); to->id = id; return to; } @@ -1468,8 +1460,8 @@ Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id) mod_id, id); Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; sc_update[mod_id]->n_ul++; - AssertFatal(sc_update[mod_id]->n_ul <= MAX_NUM_SLICES, - "cannot create more than MAX_NUM_SLICES\n"); + AssertFatal(sc_update[mod_id]->n_ul <= 10, + "cannot create more than 10\n"); to->id = id; return to; } @@ -1698,7 +1690,7 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) { - if (n_ue_slice_assoc_updates == MAX_NUM_SLICES) { + if (n_ue_slice_assoc_updates == 10) { LOG_E(FLEXRAN_AGENT, "[%d] can not handle flex_ue_config message, buffer is full; try again later\n", mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c index 67329e91be..f7f60541f5 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -132,7 +132,7 @@ int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existin /* else "only" an update */ } - if (n < 1 || n > MAX_NUM_SLICES) { + if (n < 1 || n > 10) { LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n", mod_id, n_ex, n); return 0; @@ -253,7 +253,7 @@ int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existin /* else "only" an update */ } - if (n < 1 || n > MAX_NUM_SLICES) { + if (n < 1 || n > 10) { LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n", mod_id, n_ex, n); return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 0fcc51782e..291c4dc7d8 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3015,469 +3015,209 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti) /**************************** SLICING ****************************/ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - - int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id]; - - if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl) - return RC.mac[mod_id]->slice_info.dl[slice_idx].id; - return 0; } void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { if (!mac_is_present(mod_id)) return; - - if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; - - if (!flexran_dl_slice_exists(mod_id, slice_idx)) return; - - //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id] = slice_idx; } int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - - int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id]; - - if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul) - return RC.mac[mod_id]->slice_info.ul[slice_idx].id; - return 0; } void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { if (!mac_is_present(mod_id)) return; - - if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; - - if (!flexran_ul_slice_exists(mod_id, slice_idx)) return; - - //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id] = slice_idx; } int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl; + return 0; } int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - int newidx = RC.mac[mod_id]->slice_info.n_dl; - - if (newidx >= MAX_NUM_SLICES) return -1; - - ++RC.mac[mod_id]->slice_info.n_dl; - flexran_set_dl_slice_id(mod_id, newidx, slice_id); - return newidx; + return -1; } int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - int n = sli->n_dl; - - for (int i = 0; i < n; i++) { - if (sli->dl[i].id == slice_id) return i; - } - return -1; } int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - - if (sli->n_dl <= 1) return -1; - - if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name); - - --sli->n_dl; - - /* move last element to the position of the removed one */ - if (slice_idx != sli->n_dl) - memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl])); - - memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl])); - /* all UEs that have been in the old slice are put into slice index 0 */ - //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_dl_slice_idx; - - //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { - // if (assoc_list[i] == slice_idx) - // assoc_list[i] = 0; - //} - - return 1; + return -1; } int flexran_get_num_dl_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.n_dl; + return 0; } int flexran_get_intraslice_sharing_active(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.intraslice_share_active; + return -1; } void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.intraslice_share_active = intraslice_active; } int flexran_get_interslice_sharing_active(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.interslice_share_active; + return -1; } void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.interslice_share_active = interslice_active; } slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].id; + return -1; } void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].id = slice_id; } int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].pct * 100.0f; + return -1; } void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].pct = percentage / 100.0f; } int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].isol; + return -1; } void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].isol = is_isolated; } int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].prio; + return -1; } void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].prio = priority; } int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low; + return -1; } void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low = poslow; } int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high; + return -1; } void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high = poshigh; } int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs; + return -1; } void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs = maxmcs; } int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) { if (!mac_is_present(mod_id)) return -1; - - if (!(*sorting_list)) { - *sorting_list = calloc(CR_NUM, sizeof(Protocol__FlexDlSorting)); - - if (!(*sorting_list)) return -1; - } - - uint32_t policy = RC.mac[mod_id]->slice_info.dl[slice_idx].sorting; - - for (int i = 0; i < CR_NUM; i++) { - switch (policy >> 4 * (CR_NUM - 1 - i) & 0xF) { - case CR_ROUND: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; - break; - - case CR_SRB12: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_SRB12; - break; - - case CR_HOL: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_HOL; - break; - - case CR_LC: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LC; - break; - - case CR_CQI: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_CQI; - break; - - case CR_LCP: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LCP; - break; - - default: - /* this should not happen, but a "default" */ - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; - break; - } - } - - return CR_NUM; + return -1; } void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) { if (!mac_is_present(mod_id)) return; - - uint32_t policy = 0; - - for (int i = 0; i < n && i < CR_NUM; i++) { - switch (sorting_list[i]) { - case PROTOCOL__FLEX_DL_SORTING__CR_ROUND: - policy = policy << 4 | CR_ROUND; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_SRB12: - policy = policy << 4 | CR_SRB12; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_HOL: - policy = policy << 4 | CR_HOL; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_LC: - policy = policy << 4 | CR_LC; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_CQI: - policy = policy << 4 | CR_CQI; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_LCP: - policy = policy << 4 | CR_LCP; - break; - - default: /* suppresses warnings */ - policy = policy << 4 | CR_ROUND; - break; - } - } - - /* fill up with 0 == CR_ROUND */ - if (CR_NUM > n) policy = policy << 4 * (CR_NUM - n); - - RC.mac[mod_id]->slice_info.dl[slice_idx].sorting = policy; } Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - - switch (RC.mac[mod_id]->slice_info.dl[slice_idx].accounting) { - case POL_FAIR: - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - - case POL_GREEDY: - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY; - - default: - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - } + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; } void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) { if (!mac_is_present(mod_id)) return; - - switch (accounting) { - case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR: - RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; - return; - - case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY: - RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_GREEDY; - return; - - default: - RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; - return; - } } char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return NULL; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name; + return NULL; } int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { if (!mac_is_present(mod_id)) return 0; - - if (RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name) - free(RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name); - - RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name); - RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name); - return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL; + return 0; } int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - int newidx = RC.mac[mod_id]->slice_info.n_ul; - - if (newidx >= MAX_NUM_SLICES) return -1; - - ++RC.mac[mod_id]->slice_info.n_ul; - flexran_set_ul_slice_id(mod_id, newidx, slice_id); - return newidx; + return -1; } int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - int n = sli->n_ul; - - for (int i = 0; i < n; i++) { - if (sli->ul[i].id == slice_id) return i; - } - return -1; } int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - - if (sli->n_ul <= 1) return -1; - - if (sli->ul[slice_idx].sched_name) free(sli->ul[slice_idx].sched_name); - - --sli->n_ul; - - /* move last element to the position of the removed one */ - if (slice_idx != sli->n_ul) - memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul])); - - memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul])); - /* all UEs that have been in the old slice are put into slice index 0 */ - //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_ul_slice_idx; - - //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { - // if (assoc_list[i] == slice_idx) - // assoc_list[i] = 0; - //} - - return sli->n_ul; + return -1; } int flexran_get_num_ul_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.n_ul; + return 0; } int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul; + return 0; } slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].id; + return -1; } void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].id = slice_id; } int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].pct * 100.0f; + return -1; } void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].pct = percentage / 100.0f; } int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb; + return -1; } void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb = first_rb; } int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs; + return -1; } void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs; } char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return NULL; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name; + return ""; } int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { if (!mac_is_present(mod_id)) return 0; - - if (RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name) - free(RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name); - - RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name); - RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name); - return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL; + return 0; } /************************** S1AP **************************/ diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 09585fae55..8349d84d48 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -155,9 +155,6 @@ /*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */ #define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE) -/*!\brief maximum number of slices / groups */ -#define MAX_NUM_SLICES 10 - #define U_PLANE_INACTIVITY_VALUE 0 /* defined 10ms order (zero means infinity) */ @@ -1150,9 +1147,6 @@ typedef struct { UE_list_t list; int num_UEs; boolean_t active[MAX_MOBILES_PER_ENB]; - - /// Sorting criteria for the UE list in the MAC preprocessor - uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; } UE_info_t; /*! \brief deleting control information*/ @@ -1171,101 +1165,6 @@ typedef struct { int tail_freelist; ///the tail position of the delete list } UE_free_list_t; -/** - * slice specific scheduler for the DL - */ -typedef void (*slice_scheduler_dl)(module_id_t mod_id, - int slice_idx, - frame_t frame, - sub_frame_t subframe, - int *mbsfn_flag); - -typedef struct { - slice_id_t id; - - /// RB share for each slice - float pct; - - /// whether this slice is isolated from the others - int isol; - - int prio; - - /// Frequency ranges for slice positioning - int pos_low; - int pos_high; - - // max mcs for each slice - int maxmcs; - - /// criteria for sorting policies of the slices - uint32_t sorting; - - /// Accounting policy (just greedy(1) or fair(0) setting for now) - int accounting; - - /// name of available scheduler - char *sched_name; - - /// pointer to the slice specific scheduler in DL - slice_scheduler_dl sched_cb; - -} slice_sched_conf_dl_t; - -typedef void (*slice_scheduler_ul)(module_id_t mod_id, - int slice_idx, - frame_t frame, - sub_frame_t subframe, - unsigned char sched_subframe, - uint16_t *first_rb); - -typedef struct { - slice_id_t id; - - /// RB share for each slice - float pct; - - // MAX MCS for each slice - int maxmcs; - - /// criteria for sorting policies of the slices - uint32_t sorting; - - /// starting RB (RB offset) of UL scheduling - int first_rb; - - /// name of available scheduler - char *sched_name; - - /// pointer to the slice specific scheduler in UL - slice_scheduler_ul sched_cb; - -} slice_sched_conf_ul_t; - - -typedef struct { - /// counter used to indicate when all slices have pre-allocated UEs - //int slice_counter; - - /// indicates whether remaining RBs after first intra-slice allocation will - /// be allocated to UEs of the same slice - int intraslice_share_active; - /// indicates whether remaining RBs after slice allocation will be - /// allocated to UEs of another slice. Isolated slices will be ignored - int interslice_share_active; - - /// number of active DL slices - int n_dl; - slice_sched_conf_dl_t dl[MAX_NUM_SLICES]; - - /// number of active UL slices - int n_ul; - slice_sched_conf_ul_t ul[MAX_NUM_SLICES]; - - /// common rb allocation list between slices - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; -} slice_info_t; - /** * describes contiguous RBs */ @@ -1421,9 +1320,6 @@ typedef struct eNB_MAC_INST_s { uint32_t ul_handle; UE_info_t UE_info; - /// slice-related configuration - slice_info_t slice_info; - ///subband bitmap configuration SBMAP_CONF sbmap_conf; /// CCE table used to build DCI scheduling information diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 2cb86c25af..61251ef088 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -187,8 +187,6 @@ void add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, void init_UE_info(UE_info_t *UE_info); -void init_slice_info(slice_info_t *sli); - int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 294eb12159..35b5136889 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -57,32 +57,6 @@ void init_UE_info(UE_info_t *UE_info) memset(UE_info->active, 0, sizeof(UE_info->active)); } -void init_slice_info(slice_info_t *sli) -{ - sli->intraslice_share_active = 1; - sli->interslice_share_active = 1; - - sli->n_dl = 1; - memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); - sli->dl[0].pct = 1.0; - sli->dl[0].prio = 10; - sli->dl[0].pos_high = N_RBG_MAX; - sli->dl[0].maxmcs = 28; - sli->dl[0].sorting = 0x012345; - sli->dl[0].sched_name = "schedule_ue_spec"; - sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); - AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); - - sli->n_ul = 1; - memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); - sli->ul[0].pct = 1.0; - sli->ul[0].maxmcs = 20; - sli->ul[0].sorting = 0x0123; - sli->ul[0].sched_name = "schedule_ulsch_rnti"; - sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); - AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); -} - void mac_top_init_eNB(void) { module_id_t i, j; @@ -139,7 +113,6 @@ void mac_top_init_eNB(void) mac[i]->ul_algo = *(default_sched_ul_algo_t *) d; mac[i]->ul_algo.data = mac[i]->ul_algo.setup(); init_UE_info(&mac[i]->UE_info); - init_slice_info(&mac[i]->slice_info); } RC.mac = mac; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d3412095e3..8afa3a04f5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -68,8 +68,6 @@ extern RAN_CONTEXT_t RC; -extern int n_active_slices; - // Note the 2 scs values in the table names represent resp. scs_common and pdcch_scs /// LUT for the number of symbols in the coreset indexed by coreset index (4 MSB rmsi_pdcch_config) uint8_t nr_coreset_nsymb_pdcch_type_0_scs_15_15[15] = {2,2,2,3,3,3,1,1,2,2,3,3,1,2,3}; From 8c76d6ab57e6088d317db51d454257f9bde0b463 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 14 Apr 2020 16:17:56 +0200 Subject: [PATCH 042/171] Delete old protobuf slice types flex_slice_{dl,ul} --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 206 +----- .../MAC/flexran_agent_mac_internal.c | 666 +----------------- .../MAC/flexran_agent_mac_internal.h | 20 - .../flexran_agent_mac_slice_verification.c | 343 --------- .../flexran_agent_mac_slice_verification.h | 6 - .../ENB_APP/MESSAGES/V2/config_common.proto | 77 -- .../ENB_APP/MESSAGES/V2/config_messages.proto | 8 - openair2/ENB_APP/flexran_agent_common.c | 20 +- openair2/ENB_APP/flexran_agent_ran_api.c | 178 +---- openair2/ENB_APP/flexran_agent_ran_api.h | 149 +--- 10 files changed, 47 insertions(+), 1626 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 669eb33ea3..4800fccea9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1468,10 +1468,12 @@ void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id, ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); ue_conf->has_rnti = 1; - ue_conf->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, ue_id); - ue_conf->has_dl_slice_id = 1; - ue_conf->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, ue_id); - ue_conf->has_ul_slice_id = 1; + int dl_id = flexran_get_ue_dl_slice_id(mod_id, ue_id); + ue_conf->dl_slice_id = dl_id; + ue_conf->has_dl_slice_id = dl_id >= 0; + int ul_id = flexran_get_ue_ul_slice_id(mod_id, ue_id); + ue_conf->ul_slice_id = ul_id; + ue_conf->has_ul_slice_id = ul_id >= 0; ue_conf->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, ue_id); ue_conf->has_ue_aggregated_max_bitrate_ul = 1; @@ -1576,149 +1578,24 @@ void flexran_create_config_structures(mid_t mod_id) sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); if (!slice_config[mod_id] || !sc_update[mod_id]) return; - flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); - flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); + //flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); + //flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); for (i = 0; i < n_dl; i++) { - flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); + //flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + //flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); } for (i = 0; i < m_ul; i++) { - flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); + //flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + //flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); } } void flexran_check_and_remove_slices(mid_t mod_id) { - Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl; - Protocol__FlexDlSlice **dlreal = slice_config[mod_id]->dl; - int i = 0; - while (i < sc_update[mod_id]->n_dl) { - /* remove slices whose percentage is zero */ - if (dl[i]->percentage > 0) { - ++i; - continue; - } - if (flexran_remove_dl_slice(mod_id, i) < 1) { - LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", - mod_id, i, dl[i]->id); - ++i; - continue; - } - LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", - mod_id, i, dl[i]->id); - if (dl[i]->n_sorting > 0) free(dl[i]->sorting); - free(dl[i]->scheduler_name); - if (dlreal[i]->n_sorting > 0) { - dlreal[i]->n_sorting = 0; - free(dlreal[i]->sorting); - } - free(dlreal[i]->scheduler_name); - --sc_update[mod_id]->n_dl; - --slice_config[mod_id]->n_dl; - const size_t last = sc_update[mod_id]->n_dl; - /* we need to memcpy the higher slice to the position we just deleted */ - memcpy(dl[i], dl[last], sizeof(*dl[last])); - memset(dl[last], 0, sizeof(*dl[last])); - memcpy(dlreal[i], dlreal[last], sizeof(*dlreal[last])); - memset(dlreal[last], 0, sizeof(*dlreal[last])); - /* dont increase i but recheck the slice which has been copied to here */ - } - Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul; - Protocol__FlexUlSlice **ulreal = slice_config[mod_id]->ul; - i = 0; - while (i < sc_update[mod_id]->n_ul) { - if (ul[i]->percentage > 0) { - ++i; - continue; - } - if (flexran_remove_ul_slice(mod_id, i) < 1) { - LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", - mod_id, i, ul[i]->id); - ++i; - continue; - } - LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", - mod_id, i, ul[i]->id); - free(ul[i]->scheduler_name); - free(ulreal[i]->scheduler_name); - --sc_update[mod_id]->n_ul; - --slice_config[mod_id]->n_ul; - const size_t last = sc_update[mod_id]->n_ul; - /* see DL remarks */ - memcpy(ul[i], ul[last], sizeof(*ul[last])); - memset(ul[last], 0, sizeof(*ul[last])); - memcpy(ulreal[i], ulreal[last], sizeof(*ulreal[last])); - memset(ulreal[last], 0, sizeof(*ulreal[last])); - /* dont increase i but recheck the slice which has been copied to here */ - } } void flexran_agent_slice_update(mid_t mod_id) { - int i; - int changes = 0; - - if (perform_slice_config_update_count <= 0) return; - perform_slice_config_update_count--; - - pthread_mutex_lock(&sc_update_mtx); - - if (!slice_config[mod_id]) { - /* if the configuration does not exist for agent, create from eNB structure - * and exit */ - flexran_create_config_structures(mod_id); - pthread_mutex_unlock(&sc_update_mtx); - return; - } - - /********* read existing config *********/ - /* simply update slice_config all the time and write new config - * (apply_new_slice_dl_config() only updates if changes are necessary) */ - slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); - slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); - for (i = 0; i < slice_config[mod_id]->n_dl; i++) { - flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - } - for (i = 0; i < slice_config[mod_id]->n_ul; i++) { - flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - } - - /********* write new config *********/ - /* check for removal (sc_update[X]->dl[Y].percentage == 0) - * and update sc_update & slice_config accordingly */ - flexran_check_and_remove_slices(mod_id); - - /* create new DL and UL slices if necessary */ - for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) { - flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id); - } - for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) { - flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id); - } - slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); - slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); - changes += apply_new_slice_config(mod_id, slice_config[mod_id], sc_update[mod_id]); - for (i = 0; i < slice_config[mod_id]->n_dl; i++) { - changes += apply_new_slice_dl_config(mod_id, - slice_config[mod_id]->dl[i], - sc_update[mod_id]->dl[i]); - flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - } - for (i = 0; i < slice_config[mod_id]->n_ul; i++) { - changes += apply_new_slice_ul_config(mod_id, - slice_config[mod_id]->ul[i], - sc_update[mod_id]->ul[i]); - flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - } - flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); - if (n_ue_slice_assoc_updates > 0) { - changes += apply_ue_slice_assoc_update(mod_id); - } - if (changes > 0) - LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes); - - pthread_mutex_unlock(&sc_update_mtx); } Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) @@ -1727,69 +1604,10 @@ Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) Protocol__FlexSliceConfig *config = NULL; pthread_mutex_lock(&sc_update_mtx); - config = flexran_agent_create_slice_config(slice_config[mod_id]->n_dl, - slice_config[mod_id]->n_ul); if (!config) { pthread_mutex_unlock(&sc_update_mtx); return NULL; } - config->has_intraslice_share_active = 1; - config->intraslice_share_active = slice_config[mod_id]->intraslice_share_active; - config->has_interslice_share_active = 1; - config->interslice_share_active = slice_config[mod_id]->interslice_share_active; - for (int i = 0; i < slice_config[mod_id]->n_dl; ++i) { - if (!config->dl[i]) continue; - config->dl[i]->has_id = 1; - config->dl[i]->id = slice_config[mod_id]->dl[i]->id; - config->dl[i]->has_label = 1; - config->dl[i]->label = slice_config[mod_id]->dl[i]->label; - config->dl[i]->has_percentage = 1; - config->dl[i]->percentage = slice_config[mod_id]->dl[i]->percentage; - config->dl[i]->has_isolation = 1; - config->dl[i]->isolation = slice_config[mod_id]->dl[i]->isolation; - config->dl[i]->has_priority = 1; - config->dl[i]->priority = slice_config[mod_id]->dl[i]->priority; - config->dl[i]->has_position_low = 1; - config->dl[i]->position_low = slice_config[mod_id]->dl[i]->position_low; - config->dl[i]->has_position_high = 1; - config->dl[i]->position_high = slice_config[mod_id]->dl[i]->position_high; - config->dl[i]->has_maxmcs = 1; - config->dl[i]->maxmcs = slice_config[mod_id]->dl[i]->maxmcs; - config->dl[i]->n_sorting = slice_config[mod_id]->dl[i]->n_sorting; - config->dl[i]->sorting = calloc(config->dl[i]->n_sorting, sizeof(Protocol__FlexDlSorting)); - if (!config->dl[i]->sorting) config->dl[i]->n_sorting = 0; - for (int j = 0; j < config->dl[i]->n_sorting; ++j) - config->dl[i]->sorting[j] = slice_config[mod_id]->dl[i]->sorting[j]; - config->dl[i]->has_accounting = 1; - config->dl[i]->accounting = slice_config[mod_id]->dl[i]->accounting; - config->dl[i]->scheduler_name = strdup(slice_config[mod_id]->dl[i]->scheduler_name); - } - for (int i = 0; i < slice_config[mod_id]->n_ul; ++i) { - if (!config->ul[i]) continue; - config->ul[i]->has_id = 1; - config->ul[i]->id = slice_config[mod_id]->ul[i]->id; - config->ul[i]->has_label = 1; - config->ul[i]->label = slice_config[mod_id]->ul[i]->label; - config->ul[i]->has_percentage = 1; - config->ul[i]->percentage = slice_config[mod_id]->ul[i]->percentage; - config->ul[i]->has_isolation = 1; - config->ul[i]->isolation = slice_config[mod_id]->ul[i]->isolation; - config->ul[i]->has_priority = 1; - config->ul[i]->priority = slice_config[mod_id]->ul[i]->priority; - config->ul[i]->has_first_rb = 1; - config->ul[i]->first_rb = slice_config[mod_id]->ul[i]->first_rb; - config->ul[i]->has_maxmcs = 1; - config->ul[i]->maxmcs = slice_config[mod_id]->ul[i]->maxmcs; - config->ul[i]->n_sorting = slice_config[mod_id]->ul[i]->n_sorting; - config->ul[i]->sorting = calloc(config->ul[i]->n_sorting, sizeof(Protocol__FlexUlSorting)); - if (!config->ul[i]->sorting) config->ul[i]->n_sorting = 0; - for (int j = 0; j < config->ul[i]->n_sorting; ++j) - config->ul[i]->sorting[j] = slice_config[mod_id]->ul[i]->sorting[j]; - config->ul[i]->has_accounting = 1; - config->ul[i]->accounting = slice_config[mod_id]->ul[i]->accounting; - config->ul[i]->scheduler_name = strdup(slice_config[mod_id]->ul[i]->scheduler_name); - } - pthread_mutex_unlock(&sc_update_mtx); return config; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 84a28683b7..4c80c561ee 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1027,666 +1027,18 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) { - int i; Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig)); if (!fsc) return NULL; protocol__flex_slice_config__init(fsc); - /* say there are n_dl slices but reserve memory for up to 10 so - * we don't need to reserve again later */ - fsc->n_dl = n_dl; - fsc->dl = calloc(10, sizeof(Protocol__FlexDlSlice *)); - if (!fsc->dl) fsc->n_dl = 0; - for (i = 0; i < 10; i++) { - fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice)); - if (!fsc->dl[i]) continue; - protocol__flex_dl_slice__init(fsc->dl[i]); - } - - /* as above */ - fsc->n_ul = m_ul; - fsc->ul = calloc(10, sizeof(Protocol__FlexUlSlice *)); - if (!fsc->ul) fsc->n_ul = 0; - for (i = 0; i < 10; i++) { - fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice)); - if (!fsc->ul[i]) continue; - protocol__flex_ul_slice__init(fsc->ul[i]); - } + /* TODO */ return fsc; } -void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s) -{ - s->intraslice_share_active = flexran_get_intraslice_sharing_active(mod_id); - s->has_intraslice_share_active = 1; - s->interslice_share_active = flexran_get_interslice_sharing_active(mod_id); - s->has_interslice_share_active = 1; -} - -void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice) -{ - dl_slice->id = flexran_get_dl_slice_id(mod_id, slice_idx); - dl_slice->has_id = 1; - /* read label from corresponding sc_update entry or give default */ - dl_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; - dl_slice->has_label = 1; - for (int i = 0; i < sc_update[mod_id]->n_dl; i++) { - if (sc_update[mod_id]->dl[i]->id == dl_slice->id - && sc_update[mod_id]->dl[i]->has_label) { - dl_slice->label = sc_update[mod_id]->dl[i]->label; - break; - } - } - dl_slice->percentage = flexran_get_dl_slice_percentage(mod_id, slice_idx); - dl_slice->has_percentage = 1; - dl_slice->isolation = flexran_get_dl_slice_isolation(mod_id, slice_idx); - dl_slice->has_isolation = 1; - dl_slice->priority = flexran_get_dl_slice_priority(mod_id, slice_idx); - dl_slice->has_priority = 1; - dl_slice->position_low = flexran_get_dl_slice_position_low(mod_id, slice_idx); - dl_slice->has_position_low = 1; - dl_slice->position_high = flexran_get_dl_slice_position_high(mod_id, slice_idx); - dl_slice->has_position_high = 1; - dl_slice->maxmcs = flexran_get_dl_slice_maxmcs(mod_id, slice_idx); - dl_slice->has_maxmcs = 1; - dl_slice->n_sorting = flexran_get_dl_slice_sorting(mod_id, slice_idx, &dl_slice->sorting); - if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL; - dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx); - dl_slice->has_accounting = 1; - const char *s_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx); - if (!dl_slice->scheduler_name - || strcmp(dl_slice->scheduler_name, s_name) != 0) { - dl_slice->scheduler_name = realloc(dl_slice->scheduler_name, strlen(s_name) + 1); - strcpy(dl_slice->scheduler_name, s_name); - } -} - -void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice) -{ - ul_slice->id = flexran_get_ul_slice_id(mod_id, slice_idx); - ul_slice->has_id = 1; - /* read label from corresponding sc_update entry or give default */ - ul_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; - ul_slice->has_label = 1; - for (int i = 0; i < sc_update[mod_id]->n_ul; i++) { - if (sc_update[mod_id]->ul[i]->id == ul_slice->id - && sc_update[mod_id]->ul[i]->has_label) { - ul_slice->label = sc_update[mod_id]->ul[i]->label; - break; - } - } - ul_slice->percentage = flexran_get_ul_slice_percentage(mod_id, slice_idx); - ul_slice->has_percentage = 1; - /*ul_slice->isolation = flexran_get_ul_slice_isolation(mod_id, slice_idx);*/ - ul_slice->has_isolation = 0; - /*ul_slice->priority = flexran_get_ul_slice_priority(mod_id, slice_idx);*/ - ul_slice->has_priority = 0; - ul_slice->first_rb = flexran_get_ul_slice_first_rb(mod_id, slice_idx); - ul_slice->has_first_rb = 1; - /*ul_slice-> = flexran_get_ul_slice_length_rb(mod_id, slice_idx); - ul_slice->has_length_rb = 0;*/ - ul_slice->maxmcs = flexran_get_ul_slice_maxmcs(mod_id, slice_idx); - ul_slice->has_maxmcs = 1; - ul_slice->n_sorting = 0; - /*if (ul_slice->sorting) { - free(ul_slice->sorting); - ul_slice->sorting = NULL; - } - ul_slice->n_sorting = flexran_get_ul_slice_sorting(mod_id, slice_idx, &ul_slice->sorting); - if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/ - /*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/ - ul_slice->has_accounting = 0; - const char *s_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx); - if (!ul_slice->scheduler_name - || strcmp(ul_slice->scheduler_name, s_name) != 0) { - ul_slice->scheduler_name = realloc(ul_slice->scheduler_name, strlen(s_name) + 1); - strcpy(ul_slice->scheduler_name, s_name); - } -} - -int check_dl_sorting_update(Protocol__FlexDlSlice *old, Protocol__FlexDlSlice *new) -{ - /* sorting_update => true when old->n_sorting == 0 or different numbers of - * elements; otherwise will check * element-wise */ - int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); - for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { - sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); - } - return sorting_update; -} - -int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *new) -{ - /* sorting_update => true when old->n_sorting == 0 or different numbers of - * elements; otherwise will check * element-wise */ - int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); - for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { - sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); - } - return sorting_update; -} - -void overwrite_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *exist, Protocol__FlexSliceConfig *update) -{ - if (update->has_intraslice_share_active - && exist->intraslice_share_active != update->intraslice_share_active) { - LOG_I(FLEXRAN_AGENT, "[%d] update intraslice_share_active: %d -> %d\n", - mod_id, exist->intraslice_share_active, update->intraslice_share_active); - exist->intraslice_share_active = update->intraslice_share_active; - exist->has_intraslice_share_active = 1; - } - if (update->has_interslice_share_active - && exist->interslice_share_active != update->interslice_share_active) { - LOG_I(FLEXRAN_AGENT, "[%d] update interslice_share_active: %d -> %d\n", - mod_id, exist->interslice_share_active, update->interslice_share_active); - exist->interslice_share_active = update->interslice_share_active; - exist->has_interslice_share_active = 1; - } -} - -void overwrite_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) -{ - if (update->label != exist->label) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update label: %d -> %d\n", - mod_id, update->id, exist->label, update->label); - exist->label = update->label; - exist->has_label = 1; - } - if (update->percentage != exist->percentage) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update percentage: %d -> %d\n", - mod_id, update->id, exist->percentage, update->percentage); - exist->percentage = update->percentage; - exist->has_percentage = 1; - } - if (update->isolation != exist->isolation) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update isolation: %d -> %d\n", - mod_id, update->id, exist->isolation, update->isolation); - exist->isolation = update->isolation; - exist->has_isolation = 1; - } - if (update->priority != exist->priority) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update priority: %d -> %d\n", - mod_id, update->id, exist->priority, update->priority); - exist->priority = update->priority; - exist->has_priority = 1; - } - if (update->position_low != exist->position_low) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_low: %d -> %d\n", - mod_id, update->id, exist->position_low, update->position_low); - exist->position_low = update->position_low; - exist->has_position_low = 1; - } - if (update->position_high != exist->position_high) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_high: %d -> %d\n", - mod_id, update->id, exist->position_high, update->position_high); - exist->position_high = update->position_high; - exist->has_position_high = 1; - } - if (update->maxmcs != exist->maxmcs) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update maxmcs: %d -> %d\n", - mod_id, update->id, exist->maxmcs, update->maxmcs); - exist->maxmcs = update->maxmcs; - exist->has_maxmcs = 1; - } - if (check_dl_sorting_update(exist, update)) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update sorting array\n", mod_id, update->id); - if (exist->n_sorting != update->n_sorting) { - exist->n_sorting = update->n_sorting; - exist->sorting = realloc(exist->sorting, exist->n_sorting * sizeof(Protocol__FlexDlSorting)); - if (!exist->sorting) exist->n_sorting = 0; - } - for (int i = 0; i < exist->n_sorting; i++) - exist->sorting[i] = update->sorting[i]; - } - if (update->accounting != exist->accounting) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update accounting: %d -> %d\n", - mod_id, update->id, exist->accounting, update->accounting); - exist->accounting = update->accounting; - exist->has_accounting = 1; - } - if (!exist->scheduler_name - || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update scheduler: %s -> %s\n", - mod_id, update->id, exist->scheduler_name, update->scheduler_name); - if (exist->scheduler_name) free(exist->scheduler_name); - exist->scheduler_name = strdup(update->scheduler_name); - } -} - -void overwrite_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update) -{ - if (update->label != exist->label) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update label: %d -> %d\n", - mod_id, update->id, exist->label, update->label); - exist->label = update->label; - exist->has_label = 1; - } - if (update->percentage != exist->percentage) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update percentage: %d -> %d\n", - mod_id, update->id, exist->percentage, update->percentage); - exist->percentage = update->percentage; - exist->has_percentage = 1; - } - if (update->isolation != exist->isolation) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update isolation: %d -> %d\n", - mod_id, update->id, exist->isolation, update->isolation); - exist->isolation = update->isolation; - exist->has_isolation = 1; - } - if (update->priority != exist->priority) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update priority: %d -> %d\n", - mod_id, update->id, exist->priority, update->priority); - exist->priority = update->priority; - exist->has_priority = 1; - } - if (update->first_rb != exist->first_rb) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update first_rb: %d -> %d\n", - mod_id, update->id, exist->first_rb, update->first_rb); - exist->first_rb = update ->first_rb; - exist->has_first_rb = 1; - } - /*if (update->lenght_rb != exist->lenght_rb) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update lenght_rb: %d -> %d\n", - mod_id, update->id, exist->lenght_rb, update->lenght_rb); - exist->lenght_rb = update->lenght_rb; - }*/ - if (update->maxmcs != exist->maxmcs) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update maxmcs: %d -> %d\n", - mod_id, update->id, exist->maxmcs, update->maxmcs); - exist->maxmcs = update->maxmcs; - exist->has_maxmcs = 1; - } - /* TODO - int sorting_update = 0; - int n = min(exist->n_sorting, update->n_sorting); - int i = 0; - while (i < n && !sorting_update) { - sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]); - i++; - } - if (sorting_update) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update sorting array\n", update->id, mod_id); - if (exist->n_sorting != update->n_sorting) - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] only writing %d elements\n", - mod_id, update->id, n); - for (i = 0; i < n; i++) - exist->sorting[i] = update->sorting[i]; - } - */ - if (update->accounting != exist->accounting) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update accounting: %d -> %d\n", - mod_id, update->id, exist->accounting, update->accounting); - exist->accounting = update->accounting; - exist->has_accounting = 1; - } - if (!exist->scheduler_name - || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update scheduler: %s -> %s\n", - mod_id, update->id, exist->scheduler_name, update->scheduler_name); - if (exist->scheduler_name) free(exist->scheduler_name); - exist->scheduler_name = strdup(update->scheduler_name); - } -} - -void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s, Protocol__FlexDlSlice *from) -{ - /* function fills slice with information from another slice or with default - * values (currently slice 0) if from is NULL */ - /* TODO fill the slice depending on the chosen label */ - if (!s->has_label) { - s->has_label = 1; - s->label = from ? from->label : sc_update[mod_id]->dl[0]->label; - } - if (!s->has_percentage) { - s->has_percentage = 1; - s->percentage = from ? from->percentage : sc_update[mod_id]->dl[0]->percentage; - } - if (!s->has_isolation) { - s->has_isolation = 1; - s->isolation = from ? from->isolation : sc_update[mod_id]->dl[0]->isolation; - } - if (!s->has_priority) { - s->has_priority = 1; - s->priority = from ? from->priority : sc_update[mod_id]->dl[0]->priority; - } - if (!s->has_position_low) { - s->has_position_low = 1; - s->position_low = from ? from->position_low : sc_update[mod_id]->dl[0]->position_low; - } - if (!s->has_position_high) { - s->has_position_high = 1; - s->position_high = from ? from->position_high : sc_update[mod_id]->dl[0]->position_high; - } - if (!s->has_maxmcs) { - s->has_maxmcs = 1; - s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->dl[0]->maxmcs; - } - if (s->n_sorting == 0) { - s->n_sorting = from ? from->n_sorting : sc_update[mod_id]->dl[0]->n_sorting; - s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexDlSorting)); - if (!s->sorting) s->n_sorting = 0; - for (int i = 0; i < s->n_sorting; ++i) - s->sorting[i] = from ? from->sorting[i] : sc_update[0]->dl[0]->sorting[i]; - } - if (!s->has_accounting) { - s->accounting = from ? from->accounting : sc_update[mod_id]->dl[0]->accounting; - } - if (!s->scheduler_name) { - s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name); - } -} - -Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id) -{ - for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) { - if (id == sc_update[mod_id]->dl[i]->id) { - return sc_update[mod_id]->dl[i]; - } - } - return NULL; -} - -Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id) -{ - LOG_I(FLEXRAN_AGENT, - "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n", - mod_id, id); - Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; - sc_update[mod_id]->n_dl++; - AssertFatal(sc_update[mod_id]->n_dl <= 10, - "cannot create more than 10\n"); - to->id = id; - return to; -} - -void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s, Protocol__FlexUlSlice *from) -{ - /* function fills slice with information from another slice or with default - * values (currently slice 0) if from is NULL */ - /* TODO fill the slice depending on the chosen label */ - if (!s->has_label) { - s->has_label = 1; - s->label = from ? from->label : sc_update[mod_id]->ul[0]->label; - } - if (!s->has_percentage) { - s->has_percentage = 1; - s->percentage = from ? from->percentage : sc_update[mod_id]->ul[0]->percentage; - } - if (!s->has_isolation) { - s->has_isolation = 1; - s->isolation = from ? from->isolation : sc_update[mod_id]->ul[0]->isolation; - } - if (!s->has_priority) { - s->has_priority = 1; - s->priority = from ? from->priority : sc_update[mod_id]->ul[0]->priority; - } - if (!s->has_first_rb) { - s->has_first_rb = 1; - s->first_rb = from ? from->first_rb : sc_update[mod_id]->ul[0]->first_rb; - } - if (!s->has_maxmcs) { - s->has_maxmcs = 1; - s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->ul[0]->maxmcs; - } - if (s->n_sorting == 0) { - s->n_sorting = from ? from->n_sorting : sc_update[0]->ul[0]->n_sorting; - s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexUlSorting)); - if (!s->sorting) s->n_sorting = 0; - for (int i = 0; i < s->n_sorting; ++i) - s->sorting[i] = from ? from->sorting[i] : sc_update[0]->ul[0]->sorting[i]; - } - if (!s->has_accounting) { - s->accounting = from ? from->accounting : sc_update[0]->ul[0]->accounting; - } - if (!s->scheduler_name) { - s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name); - } -} - -Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id) -{ - for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) { - if (id == sc_update[mod_id]->ul[i]->id) { - return sc_update[mod_id]->ul[i]; - } - } - return NULL; -} - -Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id) -{ - LOG_I(FLEXRAN_AGENT, - "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n", - mod_id, id); - Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; - sc_update[mod_id]->n_ul++; - AssertFatal(sc_update[mod_id]->n_ul <= 10, - "cannot create more than 10\n"); - to->id = id; - return to; -} - void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) { - int verified = 1; - if (!sc_update[mod_id]) { - LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n"); - return; - } - - pthread_mutex_lock(&sc_update_mtx); - /* no need for tests in the current state as there are only two protobuf - * bools for intra-/interslice sharing. The function applies new values if - * applicable */ - overwrite_slice_config(mod_id, sc_update[mod_id], sup); - - if (sup->n_dl == 0) { - LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); - } else { - /* verify slice parameters */ - for (int i = 0; i < sup->n_dl; i++) { - if (!sup->dl[i]->has_id) { - verified = 0; - break; - } - Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); - /* fill up so that the slice is complete. This way, we don't need to - * worry about it later */ - fill_dl_slice(mod_id, sup->dl[i], dls); - verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]); - if (!verified) break; - } - - /* verify group-based parameters (e.g. sum percentage should not exceed - * 100%). Can be used to perform admission control */ - verified = verified && flexran_verify_group_dl_slices(mod_id, - sc_update[mod_id]->dl, sc_update[mod_id]->n_dl, sup->dl, sup->n_dl); - - if (verified) { - for (int i = 0; i < sup->n_dl; i++) { - /* if all verifications were successful, get existing slice for ID or - * create new one and overwrite with the update */ - Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); - if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id); - overwrite_slice_config_dl(mod_id, dls, sup->dl[i]); - } - } else { - LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id); - } - } - - verified = 1; - if (sup->n_ul == 0) { - LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id); - } else { - /* verify slice parameters */ - for (int i = 0; i < sup->n_ul; i++) { - if (!sup->ul[i]->has_id) { - verified = 0; - break; - } - Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); - /* fill up so that the slice is complete. This way, we don't need to - * worry about it later */ - fill_ul_slice(mod_id, sup->ul[i], uls); - verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]); - if (!verified) break; - } - - /* verify group-based parameters (e.g. sum percentage should not exceed - * 100%). Can be used to perform admission control */ - verified = verified && flexran_verify_group_ul_slices(mod_id, - sc_update[mod_id]->ul, sc_update[mod_id]->n_ul, sup->ul, sup->n_ul); - - if (verified) { - for (int i = 0; i < sup->n_ul; i++) { - /* if all verifications were successful, get existing slice for ID or - * create new one and overwrite with the update */ - Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); - if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id); - overwrite_slice_config_ul(mod_id, uls, sup->ul[i]); - } - } else { - LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id); - } - } - pthread_mutex_unlock(&sc_update_mtx); - - perform_slice_config_update_count = 1; } -int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news) -{ - /* not setting the old configuration is intentional, as it will be picked up - * later when reading the configuration. There is thus a direct feedback - * whether it has been set. */ - int changes = 0; - if (olds->intraslice_share_active != news->intraslice_share_active) { - flexran_set_intraslice_sharing_active(mod_id, news->intraslice_share_active); - changes++; - } - if (olds->interslice_share_active != news->interslice_share_active) { - flexran_set_interslice_sharing_active(mod_id, news->interslice_share_active); - changes++; - } - return changes; -} - -int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc) -{ - /* not setting the old configuration is intentional, as it will be picked up - * later when reading the configuration. There is thus a direct feedback - * whether it has been set. */ - int changes = 0; - int slice_idx = flexran_find_dl_slice(mod_id, newc->id); - if (slice_idx < 0) { - LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); - return 0; - } - if (oldc->percentage != newc->percentage) { - flexran_set_dl_slice_percentage(mod_id, slice_idx, newc->percentage); - changes++; - } - if (oldc->isolation != newc->isolation) { - flexran_set_dl_slice_isolation(mod_id, slice_idx, newc->isolation); - changes++; - } - if (oldc->priority != newc->priority) { - flexran_set_dl_slice_priority(mod_id, slice_idx, newc->priority); - changes++; - } - if (oldc->position_low != newc->position_low) { - flexran_set_dl_slice_position_low(mod_id, slice_idx, newc->position_low); - changes++; - } - if (oldc->position_high != newc->position_high) { - flexran_set_dl_slice_position_high(mod_id, slice_idx, newc->position_high); - changes++; - } - if (oldc->maxmcs != newc->maxmcs) { - flexran_set_dl_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); - changes++; - } - if (check_dl_sorting_update(oldc, newc)) { - flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, newc->n_sorting); - changes++; - } - if (oldc->accounting != newc->accounting) { - flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); - changes++; - } - if (!oldc->scheduler_name - || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - int ret = flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); - AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", - newc->id, slice_idx); - changes++; - } - return changes; -} - -int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc) -{ - /* not setting the old configuration is intentional, as it will be picked up - * later when reading the configuration. There is thus a direct feedback - * whether it has been set. */ - int changes = 0; - int slice_idx = flexran_find_ul_slice(mod_id, newc->id); - if (slice_idx < 0) { - LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); - return 0; - } - if (oldc->percentage != newc->percentage) { - flexran_set_ul_slice_percentage(mod_id, slice_idx, newc->percentage); - changes++; - } - if (oldc->isolation != newc->isolation) { - /*flexran_set_ul_slice_isolation(mod_id, slice_idx, newc->isolation); - *changes++;*/ - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting isolation is not supported\n", - mod_id, newc->id); - } - if (oldc->priority != newc->priority) { - /*flexran_set_ul_slice_priority(mod_id, slice_idx, newc->priority); - *changes++;*/ - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the priority is not supported\n", - mod_id, newc->id); - } - if (oldc->first_rb != newc->first_rb) { - flexran_set_ul_slice_first_rb(mod_id, slice_idx, newc->first_rb); - changes++; - } - /*if (oldc->length_rb != newc->length_rb) { - flexran_set_ul_slice_length_rb(mod_id, slice_idx, newc->length_rb); - changes++; - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting length_rb is not supported\n", - mod_id, newc->id); - }*/ - if (oldc->maxmcs != newc->maxmcs) { - flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); - changes++; - } - /*if (check_ul_sorting_update(oldc, newc)) { - flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); - changes++; - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", - mod_id, newc->id); - }*/ - if (oldc->accounting != newc->accounting) { - /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting); - *changes++;*/ - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", - mod_id, newc->id); - } - if (!oldc->scheduler_name - || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - int ret = flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); - AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", - newc->id, slice_idx); - changes++; - } - return changes; -} void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) { @@ -1723,24 +1075,8 @@ int apply_ue_slice_assoc_update(mid_t mod_id) continue; } if (ue_slice_assoc_update[i]->has_dl_slice_id) { - int slice_idx = flexran_find_dl_slice(mod_id, ue_slice_assoc_update[i]->dl_slice_id); - if (flexran_dl_slice_exists(mod_id, slice_idx)) { - flexran_set_ue_dl_slice_idx(mod_id, ue_id, slice_idx); - changes++; - } else { - LOG_W(FLEXRAN_AGENT, "[%d] DL slice %d does not exist, refusing change\n", - mod_id, ue_slice_assoc_update[i]->dl_slice_id); - } } if (ue_slice_assoc_update[i]->has_ul_slice_id) { - int slice_idx = flexran_find_ul_slice(mod_id, ue_slice_assoc_update[i]->ul_slice_id); - if (flexran_ul_slice_exists(mod_id, slice_idx)) { - flexran_set_ue_ul_slice_idx(mod_id, ue_id, slice_idx); - changes++; - } else { - LOG_W(FLEXRAN_AGENT, "[%d] UL slice %d does not exist, refusing change\n", - mod_id, ue_slice_assoc_update[i]->ul_slice_id); - } } } n_ue_slice_assoc_updates = 0; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index 957fe6065e..ef2a7e40a9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -111,30 +111,10 @@ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) * Protocol__FlexSliceConfig struct */ void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s); -/* read the DL slice config via the RAN into a given Protocol__FlexDlSlice - * struct */ -void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice); - -/* read the UL slice config via the RAN into a given Protocol__FlexUlSlice - * struct */ -void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice); - /* reads content of slice over the sc_update structure, so that it can be * applied later by performing a diff between slice_config and sc_update */ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice); -/* apply generic slice parameters (e.g. intra-/interslice sharing activated or - * not) if there are changes. Returns the number of changed parameters. */ -int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news); - -/* apply new configuration of slice in DL if there are changes between the - * parameters. Returns the number of changed parameters. */ -int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc); - -/* apply new configuration of slice in UL if there are changes between the - * parameters. Returns the number of changed parameters. */ -int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc); - /* inserts a new ue_config into the structure keeping ue to slice association * updates and marks so it can be applied */ void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c index f7f60541f5..6e54e155c2 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -28,346 +28,3 @@ #include "flexran_agent_mac_slice_verification.h" - -/* overlap check for UL slices, helper type */ -struct sregion_s { - int start; - int length; -}; - -/* forward declaration of locally-used verification functions */ -int flexran_dl_slice_verify_pct(int pct); -int flexran_dl_slice_verify_priority(int prio); -int flexran_dl_slice_verify_position(int pos_low, int pos_high); -int flexran_dl_slice_verify_maxmcs(int maxmcs); -int flexran_ul_slice_verify_pct(int pct); -int flexran_ul_slice_verify_priority(int prio); -int flexran_ul_slice_verify_first_rb(int first_rb); -int flexran_ul_slice_verify_maxmcs(int maxmcs); -int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n); - -int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls) -{ - /* check mandatory parameters */ - if (!dls->has_id) { - LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id); - return 0; - } - - /* verify parameters individualy */ - /* label is enum */ - if (!flexran_dl_slice_verify_pct(dls->percentage)) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice percentage (%d)\n", - mod_id, dls->id, dls->percentage); - return 0; - } - /* isolation is a protobuf bool */ - if (!flexran_dl_slice_verify_priority(dls->priority)) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice priority (%d)\n", - mod_id, dls->id, dls->priority); - return 0; - } - if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) { - LOG_E(FLEXRAN_AGENT, - "[%d][DL slice %d] illegal DL slice position low (%d) and/or high (%d)\n", - mod_id, dls->id, dls->position_low, dls->position_high); - return 0; - } - if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice max mcs %d\n", - mod_id, dls->id, dls->maxmcs); - return 0; - } - if (dls->n_sorting == 0) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting in DL slice\n", - mod_id, dls->id); - return 0; - } - if (!dls->sorting) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting found in DL slice\n", - mod_id, dls->id); - return 0; - } - /* sorting is an enum */ - /* accounting is an enum */ - if (!dls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no scheduler name found\n", - mod_id, dls->id); - return 0; - } - if (strcmp(dls->scheduler_name, "schedule_ue_spec") != 0) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the scheduler to something " - "different than schedule_ue_spec is currently not allowed\n", - mod_id, dls->id); - return 0; - } - - return 1; -} - -int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, - int n_ex, Protocol__FlexDlSlice **update, int n_up) -{ - int i, j, n; - int pct, pct_orig; - /* for every update, array points to existing slice, or NULL if update - * creates new slice */ - Protocol__FlexDlSlice *s[n_up]; - for (i = 0; i < n_up; i++) { - s[i] = NULL; - for (j = 0; j < n_ex; j++) { - if (existing[j]->id == update[i]->id) - s[i] = existing[j]; - } - } - - /* check that number of created and number of added slices in total matches - * [1,10] */ - n = n_ex; - for (i = 0; i < n_up; i++) { - /* new slice */ - if (!s[i]) n += 1; - /* slice will be deleted */ - else if (s[i]->percentage == 0) n -= 1; - /* else "only" an update */ - } - - if (n < 1 || n > 10) { - LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n", - mod_id, n_ex, n); - return 0; - } - - /* check that the sum of all slices percentages (including removed/added - * slices) matches [1,100] */ - pct = 0; - for (i = 0; i < n_ex; i++) { - pct += existing[i]->percentage; - } - pct_orig = pct; - for (i = 0; i < n_up; i++) { - /* if there is an existing slice, subtract its percentage and add the - * update's percentage */ - if (s[i]) - pct -= s[i]->percentage; - pct += update[i]->percentage; - } - if (pct < 1 || pct > 100) { - LOG_E(FLEXRAN_AGENT, - "[%d] invalid total RB share for DL slices (%d%% -> %d%%)\n", - mod_id, pct_orig, pct); - return 0; - } - - return 1; -} - -int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) -{ - /* check mandatory parameters */ - if (!uls->has_id) { - LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id); - return 0; - } - - /* verify parameters individually */ - /* label is enum */ - if (!flexran_ul_slice_verify_pct(uls->percentage)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", - mod_id, uls->id, uls->percentage); - return 0; - } - /* isolation is a protobuf bool */ - if (!flexran_ul_slice_verify_priority(uls->priority)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", - mod_id, uls->id, uls->priority); - return 0; - } - if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice first RB (%d)\n", - mod_id, uls->id, uls->first_rb); - return 0; - } - if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice max mcs (%d)\n", - mod_id, uls->id, uls->maxmcs); - return 0; - } - /* TODO - if (uls->n_sorting == 0) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting in UL slice\n", - mod_id, uls->id); - return 0; - } - if (!uls->sorting) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting found in UL slice\n", - mod_id, uls->id); - return 0; - } - */ - /* sorting is an enum */ - /* accounting is an enum */ - if (!uls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no scheduler name found\n", - mod_id, uls->id); - return 0; - } - if (strcmp(uls->scheduler_name, "schedule_ulsch_rnti") != 0) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the scheduler to something " - "different than schedule_ulsch_rnti is currently not allowed\n", - mod_id, uls->id); - return 0; - } - - return 1; -} - -int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, - int n_ex, Protocol__FlexUlSlice **update, int n_up) -{ - int i, j, n; - int pct, pct_orig; - /* for every update, array "s" points to existing slice, or NULL if update - * creates new slice; array "offs" gives the offset of this slice */ - Protocol__FlexUlSlice *s[n_up]; - int offs[n_up]; - for (i = 0; i < n_up; i++) { - s[i] = NULL; - offs[i] = 0; - for (j = 0; j < n_ex; j++) { - if (existing[j]->id == update[i]->id) { - s[i] = existing[j]; - offs[i] = j; - } - } - } - - /* check that number of created and number of added slices in total matches - * [1,10] */ - n = n_ex; - for (i = 0; i < n_up; i++) { - /* new slice */ - if (!s[i]) n += 1; - /* slice will be deleted */ - else if (s[i]->percentage == 0) n -= 1; - /* else "only" an update */ - } - - if (n < 1 || n > 10) { - LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n", - mod_id, n_ex, n); - return 0; - } - - /* check that the sum of all slices percentages (including removed/added - * slices) matches [1,100] */ - pct = 0; - for (i = 0; i < n_ex; i++) { - pct += existing[i]->percentage; - } - pct_orig = pct; - for (i = 0; i < n_up; i++) { - /* if there is an existing slice, subtract its percentage and add the - * update's percentage */ - if (s[i]) - pct -= s[i]->percentage; - pct += update[i]->percentage; - } - if (pct < 1 || pct > 100) { - LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", - mod_id, pct_orig, pct); - return 0; - } - - /* check that there is no overlap in slices resulting as the combination of - * first_rb and percentage */ - struct sregion_s sregion[n]; - const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ - int k = n_ex; - for (i = 0; i < n_ex; i++) { - sregion[i].start = existing[i]->first_rb; - sregion[i].length = existing[i]->percentage * N_RB / 100; - } - for (i = 0; i < n_up; i++) { - ptrdiff_t d = s[i] ? offs[i] : k++; - AssertFatal(d >= 0 && d < k, "illegal pointer offset (%ld, k=%d)\n", d, k); - sregion[d].start = update[i]->first_rb; - sregion[d].length = update[i]->percentage * N_RB / 100; - } - AssertFatal(k == n, "illegal number of slices while calculating overlap\n"); - if (!check_ul_slice_overlap(mod_id, sregion, k)) { - LOG_E(FLEXRAN_AGENT, "[%d] UL slices are overlapping\n", mod_id); - return 0; - } - - return 1; -} - -int flexran_dl_slice_verify_pct(int pct) -{ - return pct >= 0 && pct <= 100; -} - -int flexran_dl_slice_verify_priority(int prio) -{ - return prio >= 0; -} - -int flexran_dl_slice_verify_position(int pos_low, int pos_high) -{ - return pos_low < pos_high && pos_low >= 0 && pos_high <= N_RBG_MAX; -} - -int flexran_dl_slice_verify_maxmcs(int maxmcs) -{ - return maxmcs >= 0 && maxmcs <= 28; -} - -int flexran_ul_slice_verify_pct(int pct) -{ - return pct >= 0 && pct <= 100; -} - -int flexran_ul_slice_verify_priority(int prio) -{ - return prio >= 0; -} - -int flexran_ul_slice_verify_first_rb(int first_rb) -{ - return first_rb >= 0 && first_rb < 100; -} - -int flexran_ul_slice_verify_maxmcs(int maxmcs) -{ - return maxmcs >= 0 && maxmcs <= 20; -} - -int sregion_compare(const void *_a, const void *_b) -{ - const struct sregion_s *a = (const struct sregion_s *)_a; - const struct sregion_s *b = (const struct sregion_s *)_b; - const int res = a->start - b->start; - if (res < 0) return -1; - else if (res == 0) return 0; - else return 1; -} - -int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n) -{ - int i; - int overlap, op, u; - const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ - qsort(sr, n, sizeof(sr[0]), sregion_compare); - for (i = 0; i < n; i++) { - u = i == n-1 ? N_RB : sr[i+1].start; - AssertFatal(sr[i].start <= u, "unsorted slice list\n"); - overlap = sr[i].start + sr[i].length - u; - if (overlap <= 0) continue; - op = overlap * 100 / sr[i].length; - LOG_W(FLEXRAN_AGENT, "[%d] slice overlap of %d%% detected\n", mod_id, op); - if (op >= 10) /* more than 10% overlap -> refuse */ - return 0; - } - return 1; -} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h index a8f4030d36..c9e66b6f88 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h @@ -29,9 +29,3 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" -int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls); -int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, - int n_ex, Protocol__FlexDlSlice **update, int n_up); -int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls); -int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, - int n_ex, Protocol__FlexUlSlice **update, int n_up); diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index 733d883c92..e5d01ebdc0 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -61,83 +61,6 @@ enum flex_qam { // // Slice config related structures and enums // -enum flex_dl_sorting { - - CR_ROUND = 0; // Highest HARQ first - CR_SRB12 = 1; // Highest SRB1+2 first - CR_HOL = 2; // Highest HOL first - CR_LC = 3; // Greatest RLC buffer first - CR_CQI = 4; // Highest CQI first - CR_LCP = 5; // Highest LC priority first -} - -enum flex_ul_sorting { - CRU_ROUND = 0; // Highest HARQ first - CRU_BUF = 1; // Highest BSR first - CRU_BTS = 2; // More bytes to schedule first - CRU_MCS = 3; // Highest MCS first - CRU_LCP = 4; // Highest LC priority first - CRU_HOL = 5; // Highest HOL first -} - -enum flex_dl_accounting_policy { - POL_FAIR = 0; - POL_GREEDY = 1; - POL_NUM = 2; -} - -enum flex_ul_accounting_policy { - POLU_FAIR = 0; - POLU_GREEDY = 1; - POLU_NUM = 2; -} - -enum flex_slice_label { - xMBB = 0; - URLLC = 1; - mMTC = 2; - xMTC = 3; - Other = 4; -} - -message flex_dl_slice { - optional uint32 id = 1; - optional flex_slice_label label = 2; - // should be between 0 and 100 - optional uint32 percentage = 3; - // whether this slice should be exempted form interslice sharing - optional bool isolation = 4; - // increasing value means increasing prio - optional uint32 priority = 5; - // min and max RB to use (in frequency) in the range [0, N_RBG_MAX] - optional uint32 position_low = 6; - optional uint32 position_high = 7; - // maximum MCS to be allowed in this slice - optional uint32 maxmcs = 8; - repeated flex_dl_sorting sorting = 9; - optional flex_dl_accounting_policy accounting = 10; - optional string scheduler_name = 11; -} - -message flex_ul_slice { - optional uint32 id = 1; - optional flex_slice_label label = 2; - // should be between 0 and 100 - optional uint32 percentage = 3; - // whether this slice should be exempted form interslice sharing - optional bool isolation = 4; - // increasing value means increasing prio - optional uint32 priority = 5; - // RB start to use (in frequency) in the range [0, N_RB_MAX] - optional uint32 first_rb = 6; - // TODO RB number - //optional uint32 length_rb = 7; - // maximum MCS to be allowed in this slice - optional uint32 maxmcs = 8; - repeated flex_ul_sorting sorting = 9; - optional flex_ul_accounting_policy accounting = 10; - optional string scheduler_name = 11; -} // // UE config related structures and enums diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 324153613d..1a66a4f20f 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -49,14 +49,6 @@ message flex_cell_config { } message flex_slice_config { - // whether remaining RBs after first intra-slice allocation will - // be allocated to UEs of the same slice - optional bool intraslice_share_active = 3; - // whether remaining RBs after slice allocation will be allocated - // to UEs of another slice. Isolated slices will be ignored. - optional bool interslice_share_active = 4; - repeated flex_dl_slice dl = 1; - repeated flex_ul_slice ul = 2; } message flex_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index e77b2fb386..3dd9f5b957 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -316,25 +316,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { } if (reply->cell_config[i]->slice_config) { - for (int j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) { - if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0) - free(reply->cell_config[i]->slice_config->dl[j]->sorting); - - free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name); - free(reply->cell_config[i]->slice_config->dl[j]); - } - - free(reply->cell_config[i]->slice_config->dl); - - for (int j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) { - if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0) - free(reply->cell_config[i]->slice_config->ul[j]->sorting); - - free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name); - free(reply->cell_config[i]->slice_config->ul[j]); - } - - free(reply->cell_config[i]->slice_config->ul); + /* TODO */ free(reply->cell_config[i]->slice_config); } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 291c4dc7d8..cd8b0b8f67 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3018,142 +3018,44 @@ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { return 0; } -void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { - if (!mac_is_present(mod_id)) return; -} - int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; return 0; } -void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return 0; -} - +/* TODO */ int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; return -1; } +/* TODO */ +int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { + if (!mac_is_present(mod_id)) return -1; + return -1; +} + int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; return -1; } -int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} +//int flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { +//} int flexran_get_num_dl_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; return 0; } -int flexran_get_intraslice_sharing_active(mid_t mod_id) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) { +/* TODO */ +void flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return; + return; } -int flexran_get_interslice_sharing_active(mid_t mod_id) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) { - if (!mac_is_present(mod_id)) return; -} - -slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) { - if (!mac_is_present(mod_id)) return; -} - -Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; -} -void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) { - if (!mac_is_present(mod_id)) return; -} - -char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return NULL; - return NULL; -} -int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { - if (!mac_is_present(mod_id)) return 0; - return 0; -} - -int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { +/* TODO */ +int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; return -1; } @@ -3163,62 +3065,14 @@ int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) { return -1; } -int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} +//int flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { +//} int flexran_get_num_ul_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; return 0; } -int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return 0; -} - -slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} - -void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { - if (!mac_is_present(mod_id)) return; -} - -char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return NULL; - return ""; -} -int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { - if (!mac_is_present(mod_id)) return 0; - return 0; -} /************************** S1AP **************************/ int flexran_get_s1ap_mme_pending(mid_t mod_id){ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 9d1bfb9d3e..c29ba53c11 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -659,153 +659,38 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti); /* Get the DL slice ID for a UE */ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id); - /* Set the DL slice index(!) for a UE */ -void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +//void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); /* Get the UL slice ID for a UE */ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id); - /* Set the UL slice index(!) for a UE */ -void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +//void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); -/* Whether intraslice sharing is active, return boolean */ -int flexran_get_intraslice_sharing_active(mid_t mod_id); -/* Set whether intraslice sharing is active */ -void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active); - -/* Whether intraslice sharing is active, return boolean */ -int flexran_get_interslice_sharing_active(mid_t mod_id); -/* Set whether intraslice sharing is active */ -void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active); +/* Create slice in DL, returns the new slice index */ +//int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in DL, returns new number of slices or -1 on error */ +//int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); +/* Finds slice in DL with given slice_id and returns slice index */ +int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); +/* Return the parameters of slice at index slice_idx */ +//void flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); /* Get the number of slices in DL */ int flexran_get_num_dl_slices(mid_t mod_id); -/* Query slice existence in DL. Return is boolean value */ -int flexran_dl_slice_exists(mid_t mod_id, int slice_idx); +/* Create slice in UL, returns the new slice index */ +//int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in UL */ +//int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); -/* Create slice in DL, returns the new slice index */ -int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); /* Finds slice in DL with given slice_id and returns slice index */ -int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); -/* Remove slice in DL, returns new number of slices or -1 on error */ -int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); - -/* Get the ID of a slice in DL */ -slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx); -/* Set the ID of a slice in DL */ -void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); - -/* Get the RB share a slice in DL, value 0-100 */ -int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx); -/* Set the RB share a slice in DL, value 0-100 */ -void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage); - -/* Whether a slice in DL is isolated */ -int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx); -/* Set whether a slice in DL is isolated */ -void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated); - -/* Get the priority of a slice in DL */ -int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx); -/* Get the priority of a slice in DL */ -void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority); - -/* Get the lower end of the frequency range for the slice positioning in DL */ -int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx); -/* Set the lower end of the frequency range for the slice positioning in DL */ -void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow); - -/* Get the higher end of the frequency range for the slice positioning in DL */ -int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx); -/* Set the higher end of the frequency range for the slice positioning in DL */ -void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh); - -/* Get the maximum MCS for slice in DL */ -int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx); -/* Set the maximum MCS for slice in DL */ -void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); - -/* Get the sorting order of a slice in DL, return value is number of elements - * in sorting_list */ -int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list); -/* Set the sorting order of a slice in DL */ -void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n); - -/* Get the accounting policy for a slice in DL */ -Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx); -/* Set the accounting policy for a slice in DL */ -void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting); - -/* Get the scheduler name for a slice in DL */ -char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx); -/* Set the scheduler name for a slice in DL */ -int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name); - +int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); +/* Return the parameters of slice at index slice_idx */ +//void flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); /* Get the number of slices in UL */ int flexran_get_num_ul_slices(mid_t mod_id); -/* Query slice existence in UL. Return is boolean value */ -int flexran_ul_slice_exists(mid_t mod_id, int slice_idx); - -/* Create slice in UL, returns the new slice index */ -int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); -/* Finds slice in UL with given slice_id and returns slice index */ -int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); -/* Remove slice in UL */ -int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); - -/* Get the ID of a slice in UL */ -slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx); -/* Set the ID of a slice in UL */ -void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); - -/* Get the RB share a slice in UL, value 0-100 */ -int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx); -/* Set the RB share a slice in UL, value 0-100 */ -void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage); - -/* TODO Whether a slice in UL is isolated */ -/*int flexran_get_ul_slice_isolation(mid_t mod_id, int slice_idx);*/ -/* TODO Set whether a slice in UL is isolated */ -/*void flexran_set_ul_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);*/ - -/* TODO Get the priority of a slice in UL */ -/*int flexran_get_ul_slice_priority(mid_t mod_id, int slice_idx);*/ -/* TODO Set the priority of a slice in UL */ -/*void flexran_set_ul_slice_priority(mid_t mod_id, int slice_idx, int priority);*/ - -/* Get the first RB for allocation in a slice in UL */ -int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx); -/* Set the first RB for allocation in a slice in UL */ -void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb); - -/* TODO Get the number of RB for the allocation in a slice in UL */ -/*int flexran_get_ul_slice_length_rb(mid_t mod_id, int slice_idx);*/ -/* TODO Set the of number of RB for the allocation in a slice in UL */ -/*void flexran_set_ul_slice_length_rb(mid_t mod_id, int slice_idx, int poshigh);*/ - -/* Get the maximum MCS for slice in UL */ -int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx); -/* Set the maximum MCS for slice in UL */ -void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); - -/* TODO Get the sorting order of a slice in UL, return value is number of elements - * in sorting_list */ -/*int flexran_get_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting **sorting_list);*/ -/* TODO Set the sorting order of a slice in UL */ -/*void flexran_set_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting *sorting_list, int n);*/ - -/* TODO Get the accounting policy for a slice in UL */ -/*Protocol__UlAccountingPolicy flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx);*/ -/* TODO Set the accounting policy for a slice in UL */ -/*void flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__UlAccountingPolicy accountin);*/ - -/* Get the scheduler name for a slice in UL */ -char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx); -/* Set the scheduler name for a slice in UL */ -int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name); /************************** S1AP **************************/ /* Get the number of MMEs to be connected */ From a21e9aa6ef4a840a343abab0da7e5df9153e8f4b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 15:16:21 +0200 Subject: [PATCH 043/171] Simplify add_ue_list(), remove_ue_list(); add init_ue_list() --- .../LAYER2/MAC/eNB_scheduler_primitives.c | 43 ++++++++++--------- openair2/LAYER2/MAC/mac_proto.h | 1 + openair2/LAYER2/MAC/main.c | 5 +-- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 78d6f6a3d7..b75ab774c6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2131,33 +2131,36 @@ dump_ue_list(UE_list_t *listP) { * Add a UE to UE_list listP */ inline void add_ue_list(UE_list_t *listP, int UE_id) { - if (listP->head == -1) { - listP->head = UE_id; - listP->next[UE_id] = -1; - } else { - int i = listP->head; - while (listP->next[i] >= 0) - i = listP->next[i]; - listP->next[i] = UE_id; - listP->next[UE_id] = -1; - } + int *cur = &listP->head; + while (*cur >= 0) + cur = &listP->next[*cur]; + *cur = UE_id; } //------------------------------------------------------------------------------ /* - * Remove a UE from the UE_list listP, return the previous element + * Remove a UE from the UE_list listP */ inline int remove_ue_list(UE_list_t *listP, int UE_id) { - listP->next[UE_id] = -1; - if (listP->head == UE_id) { - listP->head = listP->next[UE_id]; - return -1; - } + int *cur = &listP->head; + while (*cur != -1 && *cur != UE_id) + cur = &listP->next[*cur]; + if (*cur == -1) + return 0; + int *next = &listP->next[*cur]; + *cur = listP->next[*cur]; + *next = -1; + return 1; +} - int previous = prev(listP, UE_id); - if (previous != -1) - listP->next[previous] = listP->next[UE_id]; - return previous; +//------------------------------------------------------------------------------ +/* + * Initialize the UE_list listP + */ +inline void init_ue_list(UE_list_t *listP) { + listP->head = -1; + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + listP->next[i] = -1; } //------------------------------------------------------------------------------ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 61251ef088..818eb834fb 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -659,6 +659,7 @@ int prev(UE_list_t *listP, int nodeP); void add_ue_list(UE_list_t *listP, int UE_id); int remove_ue_list(UE_list_t *listP, int UE_id); void dump_ue_list(UE_list_t *listP); +void init_ue_list(UE_list_t *listP); int UE_num_active_CC(UE_info_t *listP, int ue_idP); int UE_PCCID(module_id_t mod_idP, int ue_idP); rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 35b5136889..659c7250e8 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -45,11 +45,8 @@ extern RAN_CONTEXT_t RC; void init_UE_info(UE_info_t *UE_info) { - int list_el; UE_info->num_UEs = 0; - UE_info->list.head = -1; - for (list_el = 0; list_el < MAX_MOBILES_PER_ENB; list_el++) - UE_info->list.next[list_el] = -1; + init_ue_list(&UE_info->list); memset(UE_info->DLSCH_pdu, 0, sizeof(UE_info->DLSCH_pdu)); memset(UE_info->UE_template, 0, sizeof(UE_info->UE_template)); memset(UE_info->eNB_UE_stats, 0, sizeof(UE_info->eNB_UE_stats)); From 115c1f38f6164786123c443ecac0df727123a07f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 14:38:05 +0200 Subject: [PATCH 044/171] Use fptr for preproc and align UL PP definition --- openair2/ENB_APP/enb_config.c | 9 +-- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 5 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 12 ++++ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 4 +- openair2/LAYER2/MAC/mac.h | 59 +++++++++++++++++-- openair2/LAYER2/MAC/mac_proto.h | 6 +- openair2/LAYER2/MAC/main.c | 13 ++-- openair2/LAYER2/MAC/pre_processor.c | 46 +++++++-------- 8 files changed, 110 insertions(+), 44 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 3bde7da02c..2e8ee0329f 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -266,10 +266,11 @@ void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) { void *d = dlsym(NULL, s); AssertFatal(d, "%s(): no default scheduler DL algo '%s' found\n", __func__, s); // release default, add new - RC.mac[j]->dl_algo.unset(&RC.mac[j]->dl_algo.data); - RC.mac[j]->dl_algo = *(default_sched_dl_algo_t *) d; - RC.mac[j]->dl_algo.data = RC.mac[j]->dl_algo.setup(); - LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", RC.mac[j]->dl_algo.name); + pp_impl_param_t *dl_pp = &RC.mac[j]->pre_processor_dl; + dl_pp->dl_algo.unset(&dl_pp->dl_algo.data); + dl_pp->dl_algo = *(default_sched_dl_algo_t *) d; + dl_pp->dl_algo.data = dl_pp->dl_algo.setup(); + LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", dl_pp->dl_algo.name); }// j=0..num_inst } /*else {// MacRLC_ParamList.numelt > 0 // ignore it diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 783d4e8b1a..1f99f50ece 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -573,10 +573,7 @@ schedule_ue_spec(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); - dlsch_scheduler_pre_processor(module_idP, - CC_id, - frameP, - subframeP); + eNB->pre_processor_dl.dl(module_idP, CC_id, frameP, subframeP); stop_meas(&eNB->schedule_dlsch_preprocessor); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index b75ab774c6..89c2ecc83d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2199,6 +2199,12 @@ add_new_ue(module_id_t mod_idP, UE_info->active[UE_id] = TRUE; add_ue_list(&UE_info->list, UE_id); dump_ue_list(&UE_info->list); + pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl; + if (dl->slices) // inform slice implementation about new UE + dl->add_UE(dl->slices, UE_id); + pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul; + if (ul->slices) // inform slice implementation about new UE + ul->add_UE(ul->slices, UE_id); if (IS_SOFTMODEM_IQPLAYER)// not specific to record/playback ? UE_info->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; UE_info->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type; @@ -2262,6 +2268,12 @@ rrc_mac_remove_ue(module_id_t mod_idP, UE_info->num_UEs--; remove_ue_list(&UE_info->list, UE_id); + pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl; + if (dl->slices) // inform slice implementation about new UE + dl->remove_UE(dl->slices, UE_id); + pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul; + if (ul->slices) // inform slice implementation about new UE + ul->remove_UE(ul->slices, UE_id); /* Clear all remaining pending transmissions */ memset(&UE_info->UE_template[pCC_id][UE_id], 0, sizeof(UE_TEMPLATE)); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 3062e5c964..2de45db856 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1301,11 +1301,11 @@ schedule_ulsch_rnti(module_id_t module_idP, /* * ULSCH preprocessor: set UE_template-> - * pre_allocated_nb_rb_ul[slice_idx] + * pre_allocated_nb_rb_ul * pre_assigned_mcs_ul * pre_allocated_rb_table_index_ul */ - ulsch_scheduler_pre_processor(module_idP, CC_id, frameP, subframeP, sched_frame, sched_subframeP); + mac->pre_processor_ul.ul(module_idP, CC_id, frameP, subframeP, sched_frame, sched_subframeP); for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { if (UE_info->UE_template[CC_id][UE_id].rach_resource_type > 0) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 8349d84d48..faefc481f6 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -540,7 +540,6 @@ typedef enum { SCHED_MODE_FAIR_RR /// fair raund robin } SCHEDULER_MODES; - /*! \brief temporary struct for ULSCH sched */ typedef struct { rnti_t rnti; @@ -1199,6 +1198,56 @@ typedef struct { void *data; } default_sched_ul_algo_t; +typedef void (*pp_impl_dl)(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe); +typedef void (*pp_impl_ul)(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe, + frame_t sched_frame, + sub_frame_t sched_subframe); + +struct slice_info_s; +typedef struct { + int algorithm; + + /// inform the slice algorithm about a new UE + void (*add_UE)(struct slice_info_s *s, int UE_id); + /// inform the slice algorithm about a UE that disconnected + void (*remove_UE)(struct slice_info_s *s, int UE_id); + /// move a UE to a slice in DL/UL, -1 means don't move (no-op). + void (*move_UE)(struct slice_info_s *s, int UE_id, int idx); + + /// Adds a new slice through admission control. slice_params are + /// algorithm-specific parameters. sched is either a default_sched_ul_algo_t + /// or default_sched_dl_algo_t, depending on whether this implementation + /// handles UL/DL. If slice at index exists, updates existing + /// slice. Returns index of new slice or -1 on failure. + int (*addmod_slice)(struct slice_info_s *s, + int id, + char *label, + void *sched, + void *slice_params); + /// Returns slice through slice_idx. 1 if successful, 0 if not. + int (*remove_slice)(struct slice_info_s *s, uint8_t slice_idx); + + union { + pp_impl_dl dl; + pp_impl_ul ul; + }; + + union { + default_sched_ul_algo_t ul_algo; + default_sched_dl_algo_t dl_algo; + }; + + void (*destroy)(struct slice_info_s **s); + + struct slice_info_s *slices; +} pp_impl_param_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1354,9 +1403,11 @@ typedef struct eNB_MAC_INST_s { UE_free_list_t UE_free_list; /// for scheduling selection SCHEDULER_MODES scheduler_mode; - /// scheduling algorithm used in default scheduler - default_sched_dl_algo_t dl_algo; - default_sched_ul_algo_t ul_algo; + /// Default scheduler: Pre-processor implementation. Algorithms for UL/DL + /// are called by ULSCH/DLSCH, respectively. Pro-processor implementation can + /// encapsulate slicing. + pp_impl_param_t pre_processor_dl; + pp_impl_param_t pre_processor_ul; int32_t puSch10xSnr; int32_t puCch10xSnr; diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 818eb834fb..9d49fdffd5 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -674,10 +674,10 @@ void set_ul_DAI(int module_idP, void ulsch_scheduler_pre_processor(module_id_t module_idP, int CC_id, - int frameP, + frame_t frameP, sub_frame_t subframeP, - int sched_frameP, - unsigned char sched_subframeP); + frame_t sched_frameP, + sub_frame_t sched_subframeP); int phy_stats_exist(module_id_t Mod_id, int rnti); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 659c7250e8..24038e60d5 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -99,16 +99,21 @@ void mac_top_init_eNB(void) } mac[i]->if_inst = IF_Module_init(i); + + mac[i]->pre_processor_dl.dl = dlsch_scheduler_pre_processor; char *s = "round_robin_dl"; void *d = dlsym(NULL, s); AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); - mac[i]->dl_algo = *(default_sched_dl_algo_t *) d; - mac[i]->dl_algo.data = mac[i]->dl_algo.setup(); + mac[i]->pre_processor_dl.dl_algo = *(default_sched_dl_algo_t *) d; + mac[i]->pre_processor_dl.dl_algo.data = mac[i]->pre_processor_dl.dl_algo.setup(); + + mac[i]->pre_processor_ul.ul = ulsch_scheduler_pre_processor; s = "round_robin_ul"; d = dlsym(NULL, s); AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); - mac[i]->ul_algo = *(default_sched_ul_algo_t *) d; - mac[i]->ul_algo.data = mac[i]->ul_algo.setup(); + mac[i]->pre_processor_ul.ul_algo = *(default_sched_ul_algo_t *) d; + mac[i]->pre_processor_ul.ul_algo.data = mac[i]->pre_processor_ul.ul_algo.setup(); + init_UE_info(&mac[i]->UE_info); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 5eb27699be..b39ce62bb7 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -691,15 +691,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, n_rbg_sched += rbgalloc_mask[i]; } - mac->dl_algo.run(Mod_id, - CC_id, - frameP, - subframeP, - &UE_to_sched, - 4, // max_num_ue - n_rbg_sched, - rbgalloc_mask, - mac->dl_algo.data); + mac->pre_processor_dl.dl_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + &UE_to_sched, + 4, // max_num_ue + n_rbg_sched, + rbgalloc_mask, + mac->pre_processor_dl.dl_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for @@ -1068,10 +1068,10 @@ default_sched_ul_algo_t round_robin_ul = { void ulsch_scheduler_pre_processor(module_id_t Mod_id, int CC_id, - int frameP, + frame_t frameP, sub_frame_t subframeP, - int sched_frameP, - unsigned char sched_subframeP) { + frame_t sched_frameP, + sub_frame_t sched_subframeP) { eNB_MAC_INST *mac = RC.mac[Mod_id]; UE_info_t *UE_info = &mac->UE_info; const int N_RB_UL = to_prb(mac->common_channels[CC_id].ul_Bandwidth); @@ -1128,17 +1128,17 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, } } - mac->ul_algo.run(Mod_id, - CC_id, - frameP, - subframeP, - sched_frameP, - sched_subframeP, - &UE_to_sched, - 4, // max_num_ue - n_contig, - rbs, - mac->ul_algo.data); + mac->pre_processor_ul.ul_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + sched_frameP, + sched_subframeP, + &UE_to_sched, + 4, // max_num_ue + n_contig, + rbs, + mac->pre_processor_ul.ul_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for From d2fe5af67a844744c3b455a0129397ee5e4c1e2f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 18:33:55 +0200 Subject: [PATCH 045/171] Implement Static Slicing --- cmake_targets/CMakeLists.txt | 1 + openair2/LAYER2/MAC/slicing/slicing.c | 586 ++++++++++++++++++ openair2/LAYER2/MAC/slicing/slicing.h | 74 +++ .../LAYER2/MAC/slicing/slicing_internal.h | 46 ++ 4 files changed, 707 insertions(+) create mode 100644 openair2/LAYER2/MAC/slicing/slicing.c create mode 100644 openair2/LAYER2/MAC/slicing/slicing.h create mode 100644 openair2/LAYER2/MAC/slicing/slicing_internal.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 525c9eae56..8d964821c0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1830,6 +1830,7 @@ set (MAC_SRC ${MAC_DIR}/eNB_scheduler_fairRR.c ${MAC_DIR}/eNB_scheduler_phytest.c ${MAC_DIR}/pre_processor.c + ${MAC_DIR}/slicing/slicing.c ${MAC_DIR}/config.c ${MAC_DIR}/config_ue.c ) diff --git a/openair2/LAYER2/MAC/slicing/slicing.c b/openair2/LAYER2/MAC/slicing/slicing.c new file mode 100644 index 0000000000..a1de326df0 --- /dev/null +++ b/openair2/LAYER2/MAC/slicing/slicing.c @@ -0,0 +1,586 @@ +/* + * 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 slicing.c + * \brief Generic slicing helper functions and Static Slicing Implementation + * \author Robert Schmidt + * \date 2020 + * \email robert.schmidt@eurecom.fr + */ + +#define _GNU_SOURCE +#include +#include + +#include "assertions.h" +#include "common/utils/LOG/log.h" + +#include "slicing.h" +#include "slicing_internal.h" + +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + +#define RET_FAIL(ret, x...) do { LOG_E(MAC, x); return ret; } while (0) + +int slicing_get_UE_slice_idx(slice_info_t *si, int UE_id) { + return si->UE_assoc_slice[UE_id]; +} + +void slicing_add_UE(slice_info_t *si, int UE_id) { + add_ue_list(&si->s[0]->UEs, UE_id); + si->UE_assoc_slice[UE_id] = 0; +} + +void _remove_UE(slice_t **s, uint8_t *assoc, int UE_id) { + const uint8_t i = assoc[UE_id]; + DevAssert(remove_ue_list(&s[i]->UEs, UE_id)); + assoc[UE_id] = -1; +} + +void slicing_remove_UE(slice_info_t *si, int UE_id) { + _remove_UE(si->s, si->UE_assoc_slice, UE_id); +} + +void _move_UE(slice_t **s, uint8_t *assoc, int UE_id, int to) { + const uint8_t i = assoc[UE_id]; + const int ri = remove_ue_list(&s[i]->UEs, UE_id); + if (!ri) + LOG_W(MAC, "did not find UE %d in DL slice index %d\n", UE_id, i); + add_ue_list(&s[to]->UEs, UE_id); + assoc[UE_id] = to; +} + +void slicing_move_UE(slice_info_t *si, int UE_id, int idx) { + DevAssert(idx >= -1 && idx < si->num); + if (idx >= 0) + _move_UE(si->s, si->UE_assoc_slice, UE_id, idx); +} + +int _exists_slice(uint8_t n, slice_t **s, int id) { + for (int i = 0; i < n; ++i) + if (s[i]->id == id) + return i; + return -1; +} + +slice_t *_add_slice(uint8_t *n, slice_t **s) { + s[*n] = calloc(1, sizeof(slice_t)); + if (!s[*n]) + return NULL; + init_ue_list(&s[*n]->UEs); + *n += 1; + return s[*n - 1]; +} + +slice_t *_remove_slice(uint8_t *n, slice_t **s, uint8_t *assoc, int idx) { + if (idx >= *n) + return NULL; + + slice_t *sr = s[idx]; + while (sr->UEs.head >= 0) + _move_UE(s, assoc, sr->UEs.head, 0); + + for (int i = idx + 1; i < *n; ++i) + s[i - 1] = s[i]; + *n -= 1; + s[*n] = NULL; + + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + if (assoc[i] > idx) + assoc[i] -= 1; + + if (sr->label) + free(sr->label); + + return sr; +} + +/************************ Static Slicing Implementation ************************/ + +int addmod_static_slice_dl(slice_info_t *si, + int id, + char *label, + void *algo, + void *slice_params_dl) { + static_slice_param_t *dl = slice_params_dl; + if (dl && dl->posLow > dl->posHigh) + RET_FAIL(-1, "%s(): slice id %d posLow > posHigh\n", __func__, id); + + uint8_t rbgMap[25] = { 0 }; + int index = _exists_slice(si->num, si->s, id); + if (index >= 0) { + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *sd = dl && si->s[s]->id == id ? dl : si->s[s]->algo_data; + for (int i = sd->posLow; i <= sd->posHigh; ++i) { + if (rbgMap[i]) + RET_FAIL(-33, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + rbgMap[i] = 1; + } + } + /* no problem, can allocate */ + slice_t *s = si->s[index]; + if (label) { + if (s->label) free(s->label); + s->label = label; + } + if (algo) { + s->dl_algo.unset(&s->dl_algo.data); + s->dl_algo = *(default_sched_dl_algo_t *) algo; + if (!s->dl_algo.data) + s->dl_algo.data = s->dl_algo.setup(); + } + if (dl) { + free(s->algo_data); + s->algo_data = dl; + } + return index; + } + + if (!dl) + RET_FAIL(-100, "%s(): no parameters for new slice %d, aborting\n", __func__, id); + + if (si->num >= MAX_STATIC_SLICES) + RET_FAIL(-2, "%s(): cannot have more than %d slices\n", __func__, MAX_STATIC_SLICES); + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *sd = si->s[s]->algo_data; + for (int i = sd->posLow; i <= sd->posHigh; ++i) + rbgMap[i] = 1; + } + + for (int i = dl->posLow; i <= dl->posHigh; ++i) + if (rbgMap[i]) + RET_FAIL(-3, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + + if (!algo) + RET_FAIL(-14, "%s(): no scheduler algorithm provided\n", __func__); + + slice_t *ns = _add_slice(&si->num, si->s); + if (!ns) + RET_FAIL(-4, "%s(): could not create new slice\n", __func__); + ns->id = id; + ns->label = label; + ns->dl_algo = *(default_sched_dl_algo_t *) algo; + if (!ns->dl_algo.data) + ns->dl_algo.data = ns->dl_algo.setup(); + ns->algo_data = dl; + + return si->num - 1; +} + +int addmod_static_slice_ul(slice_info_t *si, + int id, + char *label, + void *algo, + void *slice_params_ul) { + static_slice_param_t *ul = slice_params_ul; + /* Minimum 3RBs, because LTE stack requires this */ + if (ul && ul->posLow + 2 > ul->posHigh) + RET_FAIL(-1, "%s(): slice id %d posLow + 2 > posHigh\n", __func__, id); + + uint8_t rbMap[110] = { 0 }; + int index = _exists_slice(si->num, si->s, id); + if (index >= 0) { + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *su = ul && si->s[s]->id == id && ul ? ul : si->s[s]->algo_data; + for (int i = su->posLow; i <= su->posHigh; ++i) { + if (rbMap[i]) + RET_FAIL(-33, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + rbMap[i] = 1; + } + } + /* no problem, can allocate */ + slice_t *s = si->s[index]; + if (algo) { + s->ul_algo.unset(&s->ul_algo.data); + s->ul_algo = *(default_sched_ul_algo_t *) algo; + if (!s->ul_algo.data) + s->ul_algo.data = s->ul_algo.setup(); + } + if (label) { + if (s->label) free(s->label); + s->label = label; + } + if (ul) { + free(s->algo_data); + s->algo_data = ul; + } + return index; + } + + if (!ul) + RET_FAIL(-100, "%s(): no parameters for new slice %d, aborting\n", __func__, id); + + if (si->num >= MAX_STATIC_SLICES) + RET_FAIL(-2, "%s(): cannot have more than %d slices\n", __func__, MAX_STATIC_SLICES); + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *sd = si->s[s]->algo_data; + for (int i = sd->posLow; i <= sd->posHigh; ++i) + rbMap[i] = 1; + } + + for (int i = ul->posLow; i <= ul->posHigh; ++i) + if (rbMap[i]) + RET_FAIL(-3, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + + if (!algo) + RET_FAIL(-14, "%s(): no scheduler algorithm provided\n", __func__); + + slice_t *ns = _add_slice(&si->num, si->s); + if (!ns) + RET_FAIL(-4, "%s(): could not create new slice\n", __func__); + ns->id = id; + ns->label = label; + ns->ul_algo = *(default_sched_ul_algo_t *) algo; + if (!ns->ul_algo.data) + ns->ul_algo.data = ns->ul_algo.setup(); + ns->algo_data = ul; + + return si->num - 1; +} + +int remove_static_slice(slice_info_t *si, uint8_t slice_idx) { + if (slice_idx == 0) + return 0; + slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx); + if (!sr) + return 0; + free(sr->algo_data); + free(sr); + return 1; +} + +void static_dl(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe) { + UE_info_t *UE_info = &RC.mac[mod_id]->UE_info; + + store_dlsch_buffer(mod_id, CC_id, frame, subframe); + + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + + /* initialize per-UE scheduling information */ + ue_sched_ctrl->pre_nb_available_rbs[CC_id] = 0; + ue_sched_ctrl->dl_pow_off[CC_id] = 2; + memset(ue_sched_ctrl->rballoc_sub_UE[CC_id], 0, sizeof(ue_sched_ctrl->rballoc_sub_UE[CC_id])); + ue_sched_ctrl->pre_dci_dl_pdu_idx = -1; + } + + const int N_RBG = to_rbg(RC.mac[mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + const int RBGsize = get_min_rb_unit(mod_id, CC_id); + uint8_t *vrb_map = RC.mac[mod_id]->common_channels[CC_id].vrb_map; + uint8_t rbgalloc_mask[N_RBG_MAX]; + for (int i = 0; i < N_RBG; i++) { + // calculate mask: init to one + "AND" with vrb_map: + // if any RB in vrb_map is blocked (1), the current RBG will be 0 + rbgalloc_mask[i] = 1; + for (int j = 0; j < RBGsize; j++) + rbgalloc_mask[i] &= !vrb_map[RBGsize * i + j]; + } + + slice_info_t *s = RC.mac[mod_id]->pre_processor_dl.slices; + int max_num_ue; + switch (s->num) { + case 1: + max_num_ue = 4; + break; + case 2: + max_num_ue = 2; + break; + default: + max_num_ue = 1; + break; + } + for (int i = 0; i < s->num; ++i) { + if (s->s[i]->UEs.head < 0) + continue; + uint8_t rbgalloc_slice_mask[N_RBG_MAX]; + memset(rbgalloc_slice_mask, 0, sizeof(rbgalloc_slice_mask)); + static_slice_param_t *p = s->s[i]->algo_data; + int n_rbg_sched = 0; + for (int rbg = p->posLow; rbg <= p->posHigh && rbg <= N_RBG; ++rbg) { + rbgalloc_slice_mask[rbg] = rbgalloc_mask[rbg]; + n_rbg_sched += rbgalloc_mask[rbg]; + } + + s->s[i]->dl_algo.run(mod_id, + CC_id, + frame, + subframe, + &s->s[i]->UEs, + max_num_ue, // max_num_ue + n_rbg_sched, + rbgalloc_slice_mask, + s->s[i]->dl_algo.data); + } + + // the following block is meant for validation of the pre-processor to check + // whether all UE allocations are non-overlapping and is not necessary for + // scheduling functionality + char t[26] = "_________________________"; + t[N_RBG] = 0; + for (int i = 0; i < N_RBG; i++) + for (int j = 0; j < RBGsize; j++) + if (vrb_map[RBGsize*i+j] != 0) + t[i] = 'x'; + int print = 0; + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + const UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + + if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0) + continue; + + LOG_D(MAC, + "%4d.%d UE%d %d RBs allocated, pre MCS %d\n", + frame, + subframe, + UE_id, + ue_sched_ctrl->pre_nb_available_rbs[CC_id], + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1); + + print = 1; + + for (int i = 0; i < N_RBG; i++) { + if (!ue_sched_ctrl->rballoc_sub_UE[CC_id][i]) + continue; + for (int j = 0; j < RBGsize; j++) { + if (vrb_map[RBGsize*i+j] != 0) { + LOG_I(MAC, "%4d.%d DL scheduler allocation list: %s\n", frame, subframe, t); + LOG_E(MAC, "%4d.%d: UE %d allocated at locked RB %d/RBG %d\n", frame, + subframe, UE_id, RBGsize * i + j, i); + } + vrb_map[RBGsize*i+j] = 1; + } + t[i] = '0' + UE_id; + } + } + if (print) + LOG_D(MAC, "%4d.%d DL scheduler allocation list: %s\n", frame, subframe, t); +} + +void static_ul(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe, + frame_t sched_frame, + sub_frame_t sched_subframe) { + UE_info_t *UE_info = &RC.mac[mod_id]->UE_info; + const int N_RB_UL = to_prb(RC.mac[mod_id]->common_channels[CC_id].ul_Bandwidth); + COMMON_channels_t *cc = &RC.mac[mod_id]->common_channels[CC_id]; + + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id]; + UE_template->pre_assigned_mcs_ul = 0; + UE_template->pre_allocated_nb_rb_ul = 0; + UE_template->pre_allocated_rb_table_index_ul = -1; + UE_template->pre_first_nb_rb_ul = 0; + UE_template->pre_dci_ul_pdu_idx = -1; + } + + slice_info_t *s = RC.mac[mod_id]->pre_processor_ul.slices; + int max_num_ue; + switch (s->num) { + case 1: + max_num_ue = 4; + break; + case 2: + max_num_ue = 2; + break; + default: + max_num_ue = 1; + break; + } + for (int i = 0; i < s->num; ++i) { + if (s->s[i]->UEs.head < 0) + continue; + int last_rb_blocked = 1; + int n_contig = 0; + contig_rbs_t rbs[2]; // up to two contig RBs for PRACH in between + static_slice_param_t *p = s->s[i]->algo_data; + for (int rb = p->posLow; rb <= p->posHigh && rb < N_RB_UL; ++rb) { + if (cc->vrb_map_UL[rb] == 0 && last_rb_blocked) { + last_rb_blocked = 0; + n_contig++; + AssertFatal(n_contig <= 2, "cannot handle more than two contiguous RB regions\n"); + rbs[n_contig - 1].start = rb; + } + if (cc->vrb_map_UL[rb] == 1 && !last_rb_blocked) { + last_rb_blocked = 1; + rbs[n_contig - 1].length = rb - rbs[n_contig - 1].start; + } + } + if (!last_rb_blocked) + rbs[n_contig - 1].length = p->posHigh - rbs[n_contig - 1].start + 1; + + s->s[i]->ul_algo.run(mod_id, + CC_id, + frame, + subframe, + sched_frame, + sched_subframe, + &s->s[i]->UEs, + max_num_ue, // max_num_ue + n_contig, + rbs, + s->s[i]->ul_algo.data); + } + + // the following block is meant for validation of the pre-processor to check + // whether all UE allocations are non-overlapping and is not necessary for + // scheduling functionality + char t[101] = "__________________________________________________" + "__________________________________________________"; + t[N_RB_UL] = 0; + for (int j = 0; j < N_RB_UL; j++) + if (cc->vrb_map_UL[j] != 0) + t[j] = 'x'; + int print = 0; + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id]; + if (UE_template->pre_allocated_nb_rb_ul == 0) + continue; + + print = 1; + uint8_t harq_pid = subframe2harqpid(&RC.mac[mod_id]->common_channels[CC_id], + sched_frame, sched_subframe); + LOG_D(MAC, "%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s\n", + frame, + subframe, + UE_id, + UE_template->pre_allocated_nb_rb_ul, + UE_template->pre_allocated_rb_table_index_ul, + UE_template->pre_first_nb_rb_ul, + UE_template->pre_assigned_mcs_ul, + UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] > 0 ? "(retx)" : ""); + + for (int i = 0; i < UE_template->pre_allocated_nb_rb_ul; ++i) { + /* only check if this is not a retransmission */ + if (UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] == 0 + && cc->vrb_map_UL[UE_template->pre_first_nb_rb_ul + i] == 1) { + + LOG_I(MAC, "%4d.%d UL scheduler allocation list: %s\n", frame, subframe, t); + LOG_E(MAC, + "%4d.%d: UE %d allocated at locked RB %d (is: allocated start " + "%d/length %d)\n", + frame, subframe, UE_id, UE_template->pre_first_nb_rb_ul + i, + UE_template->pre_first_nb_rb_ul, + UE_template->pre_allocated_nb_rb_ul); + } + cc->vrb_map_UL[UE_template->pre_first_nb_rb_ul + i] = 1; + t[UE_template->pre_first_nb_rb_ul + i] = UE_id + '0'; + } + } + if (print) + LOG_D(MAC, + "%4d.%d UL scheduler allocation list: %s\n", + sched_frame, + sched_subframe, + t); +} + +void static_destroy(slice_info_t **si) { + const int n = (*si)->num; + (*si)->num = 0; + for (int i = 0; i < n; ++i) { + slice_t *s = (*si)->s[i]; + if (s->label) + free(s->label); + free(s->algo_data); + free(s); + } + free((*si)->s); + free(*si); +} + +pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) { + slice_info_t *si = calloc(1, sizeof(slice_info_t)); + DevAssert(si); + + si->num = 0; + si->s = calloc(MAX_STATIC_SLICES, sizeof(slice_t)); + DevAssert(si->s); + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + si->UE_assoc_slice[i] = -1; + + /* insert default slice, all resources */ + static_slice_param_t *dlp = malloc(sizeof(static_slice_param_t)); + dlp->posLow = 0; + dlp->posHigh = to_rbg(RC.mac[mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - 1; + default_sched_dl_algo_t *algo = &RC.mac[mod_id]->pre_processor_dl.dl_algo; + DevAssert(0 == addmod_static_slice_dl(si, 0, strdup("default"), algo, dlp)); + const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) + slicing_add_UE(si, UE_id); + + pp_impl_param_t sttc; + sttc.algorithm = STATIC_SLICING; + sttc.add_UE = slicing_add_UE; + sttc.remove_UE = slicing_remove_UE; + sttc.move_UE = slicing_move_UE; + sttc.addmod_slice = addmod_static_slice_dl; + sttc.remove_slice = remove_static_slice; + sttc.dl = static_dl; + // current DL algo becomes default scheduler + sttc.dl_algo = *algo; + sttc.destroy = static_destroy; + sttc.slices = si; + + return sttc; +} + +pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) { + slice_info_t *si = calloc(1, sizeof(slice_info_t)); + DevAssert(si); + + si->num = 0; + si->s = calloc(MAX_STATIC_SLICES, sizeof(slice_t)); + DevAssert(si->s); + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + si->UE_assoc_slice[i] = -1; + + /* insert default slice, all resources */ + static_slice_param_t *ulp = malloc(sizeof(static_slice_param_t)); + ulp->posLow = 0; + ulp->posHigh = to_prb(RC.mac[mod_id]->common_channels[CC_id].ul_Bandwidth) - 1; + default_sched_ul_algo_t *algo = &RC.mac[mod_id]->pre_processor_ul.ul_algo; + DevAssert(0 == addmod_static_slice_ul(si, 0, strdup("default"), algo, ulp)); + const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) + slicing_add_UE(si, UE_id); + + pp_impl_param_t sttc; + sttc.algorithm = STATIC_SLICING; + sttc.add_UE = slicing_add_UE; + sttc.remove_UE = slicing_remove_UE; + sttc.move_UE = slicing_move_UE; + sttc.addmod_slice = addmod_static_slice_ul; + sttc.remove_slice = remove_static_slice; + sttc.ul = static_ul; + // current DL algo becomes default scheduler + sttc.ul_algo = *algo; + sttc.destroy = static_destroy; + sttc.slices = si; + + return sttc; +} diff --git a/openair2/LAYER2/MAC/slicing/slicing.h b/openair2/LAYER2/MAC/slicing/slicing.h new file mode 100644 index 0000000000..1099b50ea0 --- /dev/null +++ b/openair2/LAYER2/MAC/slicing/slicing.h @@ -0,0 +1,74 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! + * \file slicing.h + * \brief General slice definition and helper parameters + * \author Robert Schmidt + * \date 2020 + * \email robert.schmidt@eurecom.fr + */ + +#ifndef __SLICING_H__ +#define __SLICING_H__ + +#include "openair2/LAYER2/MAC/mac.h" + +typedef struct slice_s { + /// Arbitrary ID + slice_id_t id; + /// Arbitrary label + char *label; + + union { + default_sched_dl_algo_t dl_algo; + default_sched_ul_algo_t ul_algo; + }; + + /// A specific algorithm's implementation parameters + void *algo_data; + /// Internal data that might be kept alongside a slice's params + void *int_data; + + // list of users in this slice + UE_list_t UEs; +} slice_t; + +typedef struct slice_info_s { + uint8_t num; + slice_t **s; + uint8_t UE_assoc_slice[MAX_MOBILES_PER_ENB]; +} slice_info_t; + +int slicing_get_UE_slice_idx(slice_info_t *si, int UE_id); + +#define STATIC_SLICING 10 +/* only four static slices for UL, DL resp. (not enough DCIs) */ +#define MAX_STATIC_SLICES 4 +typedef struct { + uint16_t posLow; + uint16_t posHigh; +} static_slice_param_t; +pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id); +pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id); + + +#endif /* __SLICING_H__ */ diff --git a/openair2/LAYER2/MAC/slicing/slicing_internal.h b/openair2/LAYER2/MAC/slicing/slicing_internal.h new file mode 100644 index 0000000000..744f8924d9 --- /dev/null +++ b/openair2/LAYER2/MAC/slicing/slicing_internal.h @@ -0,0 +1,46 @@ +/* + * 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 slicing_internal.h + * \brief Internal slice helper functions + * \author Robert Schmidt + * \date 2020 + * \email robert.schmidt@eurecom.fr + */ + +#ifndef __SLICING_INTERNAL_H__ +#define __SLICING_INTERNAL_H__ + +#include "slicing.h" + +void slicing_add_UE(slice_info_t *si, int UE_id); + +void _remove_UE(slice_t **s, uint8_t *assoc, int UE_id); +void slicing_remove_UE(slice_info_t *si, int UE_id); + +void _move_UE(slice_t **s, uint8_t *assoc, int UE_id, int to); +void slicing_move_UE(slice_info_t *si, int UE_id, int idx); + +slice_t *_add_slice(uint8_t *n, slice_t **s); +slice_t *_remove_slice(uint8_t *n, slice_t **s, uint8_t *assoc, int idx); + +#endif /* __SLICING_INTERNAL_H__ */ From d926a9a9c818e01fff34e3b96e0611929325faca Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jun 2020 19:12:15 +0200 Subject: [PATCH 046/171] FlexRAN: New protobuf slice structure + Static Slice handling --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 139 ++++++--- .../CONTROL_MODULES/MAC/flexran_agent_mac.h | 13 +- .../MAC/flexran_agent_mac_internal.c | 202 ++++++++++--- .../MAC/flexran_agent_mac_internal.h | 20 +- .../ENB_APP/MESSAGES/V2/config_common.proto | 25 ++ .../ENB_APP/MESSAGES/V2/config_messages.proto | 2 + openair2/ENB_APP/flexran_agent_common.c | 12 +- openair2/ENB_APP/flexran_agent_ran_api.c | 277 ++++++++++++++++-- openair2/ENB_APP/flexran_agent_ran_api.h | 45 ++- openair2/LAYER2/MAC/main.c | 2 + openair2/LAYER2/MAC/slicing/slicing.c | 21 +- 11 files changed, 614 insertions(+), 144 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 4800fccea9..e5d1c94c95 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1452,9 +1452,74 @@ void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id, conf->si_config->has_sfn = 1; } - /* get a pointer to the config which is maintained in the agent throughout - * its lifetime */ - conf->slice_config = flexran_agent_get_slice_config(mod_id); + conf->slice_config = malloc(sizeof(Protocol__FlexSliceConfig)); + if (conf->slice_config) { + protocol__flex_slice_config__init(conf->slice_config); + Protocol__FlexSliceConfig *sc = conf->slice_config; + + sc->dl = malloc(sizeof(Protocol__FlexSliceDlUlConfig)); + DevAssert(sc->dl); + protocol__flex_slice_dl_ul_config__init(sc->dl); + sc->dl->algorithm = flexran_get_dl_slice_algo(mod_id); + sc->dl->has_algorithm = 1; + sc->dl->n_slices = flexran_get_num_dl_slices(mod_id); + if (sc->dl->n_slices > 0) { + sc->dl->slices = calloc(sc->dl->n_slices, sizeof(Protocol__FlexSlice *)); + DevAssert(sc->dl->slices); + for (int i = 0; i < sc->dl->n_slices; ++i) { + sc->dl->slices[i] = malloc(sizeof(Protocol__FlexSlice)); + DevAssert(sc->dl->slices[i]); + protocol__flex_slice__init(sc->dl->slices[i]); + flexran_get_dl_slice(mod_id, i, sc->dl->slices[i], sc->dl->algorithm); + } + } else { + sc->dl->scheduler = flexran_get_dl_scheduler_name(mod_id); + } + + sc->ul = malloc(sizeof(Protocol__FlexSliceDlUlConfig)); + DevAssert(sc->ul); + protocol__flex_slice_dl_ul_config__init(sc->ul); + sc->ul->algorithm = flexran_get_ul_slice_algo(mod_id); + sc->ul->has_algorithm = 1; + sc->ul->n_slices = flexran_get_num_ul_slices(mod_id); + if (sc->ul->n_slices > 0) { + sc->ul->slices = calloc(sc->ul->n_slices, sizeof(Protocol__FlexSlice *)); + DevAssert(sc->ul->slices); + for (int i = 0; i < sc->ul->n_slices; ++i) { + sc->ul->slices[i] = malloc(sizeof(Protocol__FlexSlice)); + DevAssert(sc->ul->slices[i]); + protocol__flex_slice__init(sc->ul->slices[i]); + flexran_get_ul_slice(mod_id, i, sc->ul->slices[i], sc->ul->algorithm); + } + } else { + sc->ul->scheduler = flexran_get_ul_scheduler_name(mod_id); + } + } +} + +void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf) { + Protocol__FlexSliceConfig *sc = conf->slice_config; + for (int i = 0; i < sc->dl->n_slices; ++i) { + free(sc->dl->slices[i]); + sc->dl->slices[i] = NULL; + /* scheduler names are not freed: we assume we read them directly from the + * underlying memory and do not dispose it */ + } + free(sc->dl->slices); + /* scheduler name is not freed */ + free(sc->dl); + sc->dl = NULL; + for (int i = 0; i < sc->ul->n_slices; ++i) { + free(sc->ul->slices[i]); + sc->ul->slices[i] = NULL; + /* scheduler names are not freed */ + } + free(sc->ul->slices); + /* scheduler name is not freed */ + free(sc->ul); + sc->ul = NULL; + free(conf->slice_config); + conf->slice_config = NULL; } void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id, @@ -1568,46 +1633,46 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) return 0; } - -void flexran_create_config_structures(mid_t mod_id) -{ - int i; - int n_dl = flexran_get_num_dl_slices(mod_id); - int m_ul = flexran_get_num_ul_slices(mod_id); - slice_config[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); - sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); - if (!slice_config[mod_id] || !sc_update[mod_id]) return; - - //flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); - //flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); - for (i = 0; i < n_dl; i++) { - //flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - //flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); +void helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) { + if (slice_config->dl) { + if (slice_config->dl->scheduler) + free(slice_config->dl->scheduler); + for (int i = 0; i < slice_config->dl->n_slices; i++) + if (slice_config->dl->slices[i]->scheduler) + free(slice_config->dl->slices[i]->scheduler); } - for (i = 0; i < m_ul; i++) { - //flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - //flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); + if (slice_config->ul) { + if (slice_config->ul->scheduler) + free(slice_config->ul->scheduler); + for (int i = 0; i < slice_config->ul->n_slices; i++) + if (slice_config->ul->slices[i]->scheduler) + free(slice_config->ul->slices[i]->scheduler); } + + Protocol__FlexCellConfig helper; + helper.slice_config = slice_config; + flexran_agent_destroy_mac_slice_config(&helper); } -void flexran_check_and_remove_slices(mid_t mod_id) -{ +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) { + if (!*slice_config) return; + Protocol__FlexSliceConfig *sc = *slice_config; + *slice_config = NULL; + + /* TODO handle using lock-free queue */ + apply_update_dl_slice_config(mod_id, sc->dl); + apply_update_ul_slice_config(mod_id, sc->ul); + + helper_destroy_mac_slice_config(*slice_config); } -void flexran_agent_slice_update(mid_t mod_id) -{ +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config) { + /* TODO handle using lock-free queue */ + apply_ue_slice_assoc_update(mod_id, *ue_config); + + free(*ue_config); + *ue_config = NULL; } -Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) -{ - if (!slice_config[mod_id]) return NULL; - Protocol__FlexSliceConfig *config = NULL; - - pthread_mutex_lock(&sc_update_mtx); - if (!config) { - pthread_mutex_unlock(&sc_update_mtx); - return NULL; - } - pthread_mutex_unlock(&sc_update_mtx); - return config; +void flexran_agent_slice_update(mid_t mod_id) { } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 2f9f99c740..5a8d4f31aa 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -115,7 +115,16 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id); /* Inform controller about possibility to update slice configuration */ void flexran_agent_slice_update(mid_t mod_id); -/* return a pointer to the current config */ -Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id); +/* marks slice_config so that it can be applied later. Takes ownership of the + * FlexSliceConfig message */ +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice); + +/* inserts a new ue_config into the structure keeping ue to slice association + * updates and marks so it can be applied. Takes ownership of the FlexUeConfig message */ +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config); + +/* free slice_config part of flexCellConfig, filled in + * flexran_agent_fill_mac_cell_config() */ +void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf); #endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 4c80c561ee..93de0b11ec 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1025,60 +1025,166 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { } -Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) -{ - Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig)); - if (!fsc) return NULL; - protocol__flex_slice_config__init(fsc); - - /* TODO */ - return fsc; -} - -void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) -{ -} - - -void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) -{ - if (n_ue_slice_assoc_updates == 10) { - LOG_E(FLEXRAN_AGENT, - "[%d] can not handle flex_ue_config message, buffer is full; try again later\n", - mod_id); - return; +void update_or_remove_dl(mid_t mod_id, Protocol__FlexSlice *s) { + if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET + && !s->label && !s->scheduler) { + LOG_I(FLEXRAN_AGENT, "remove DL slice ID %d\n", s->id); + const int rc = flexran_remove_dl_slice(mod_id, s); + if (!rc) + LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id); + } else { + LOG_I(FLEXRAN_AGENT, "updating DL slice ID %d\n", s->id); + const int rc = flexran_create_dl_slice(mod_id, s); + if (rc < 0) + LOG_W(FLEXRAN_AGENT, + "error while update slice ID %d: flexran_create_dl_slice() -> %d\n", + s->id, rc); } +} + +void update_or_remove_ul(mid_t mod_id, Protocol__FlexSlice *s) { + if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET + && !s->label && !s->scheduler) { + LOG_I(FLEXRAN_AGENT, "remove UL slice ID %d\n", s->id); + const int rc = flexran_remove_ul_slice(mod_id, s); + if (!rc) + LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id); + } else { + LOG_I(FLEXRAN_AGENT, "updating UL slice ID %d\n", s->id); + const int rc = flexran_create_ul_slice(mod_id, s); + if (rc < 0) + LOG_W(FLEXRAN_AGENT, + "error while updating slice ID %d: flexran_create_ul_slice() -> %d)\n", + s->id, rc); + } +} + +void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *dl) { + if (!dl) + return; + + Protocol__FlexSliceAlgorithm dl_algo = flexran_get_dl_slice_algo(mod_id); + if (dl->has_algorithm && dl_algo != dl->algorithm) { + LOG_I(FLEXRAN_AGENT, "loading new DL slice algorithm %d\n", dl->algorithm); + dl_algo = dl->algorithm; + flexran_set_dl_slice_algo(mod_id, dl_algo); + } + + /* first update existing slices, then create new. Thus, we go through the + * list twice. First round, if a slice exists, handle and mark as such. Then, + * apply all others in the second round */ + if (dl->n_slices > 0) { + if (dl_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n"); + return; + } + int handled_dl[dl->n_slices]; + for (int i = 0; i < dl->n_slices; ++i) { + if (flexran_find_dl_slice(mod_id, dl->slices[i]->id) < 0) { + handled_dl[i] = 0; + continue; + } + update_or_remove_dl(mod_id, dl->slices[i]); + handled_dl[i] = 1; + } + for (int i = 0; i < dl->n_slices; ++i) { + if (handled_dl[i]) + continue; + update_or_remove_dl(mod_id, dl->slices[i]); + } + } + + if (dl->scheduler) { + if (dl_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n"); + return; + } + LOG_I(FLEXRAN_AGENT, "loading DL new scheduling algorithm '%s'\n", dl->scheduler); + const int rc = flexran_set_dl_scheduler(mod_id, dl->scheduler); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, + "error while updating scheduling algorithm: " + "flexran_update_dl_sched_algo() -> %d)\n", + rc); + return; + } + } +} + +void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *ul) { + if (!ul) + return; + + Protocol__FlexSliceAlgorithm ul_algo = flexran_get_ul_slice_algo(mod_id); + if (ul->has_algorithm && ul_algo != ul->algorithm) { + LOG_I(FLEXRAN_AGENT, "loading new UL slice algorithm %d\n", ul->algorithm); + ul_algo = ul->algorithm; + flexran_set_ul_slice_algo(mod_id, ul_algo); + } + if (ul->n_slices > 0) { + if (ul_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n"); + return; + } + int handled_ul[ul->n_slices]; + for (int i = 0; i < ul->n_slices; ++i) { + if (flexran_find_ul_slice(mod_id, ul->slices[i]->id) < 0) { + handled_ul[i] = 0; + continue; + } + update_or_remove_ul(mod_id, ul->slices[i]); + handled_ul[i] = 1; + } + for (int i = 0; i < ul->n_slices; ++i) { + if (handled_ul[i]) + continue; + update_or_remove_ul(mod_id, ul->slices[i]); + } + } + + if (ul->scheduler) { + if (ul_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n"); + return; + } + LOG_I(FLEXRAN_AGENT, "loading new UL scheduling algorithm '%s'\n", ul->scheduler); + const int rc = flexran_set_ul_scheduler(mod_id, ul->scheduler); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, + "error while updating scheduling algorithm: " + "flexran_update_dl_sched_algo() -> %d)\n", + rc); + return; + } + } +} + +int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) +{ if (!ue_config->has_rnti) { LOG_E(FLEXRAN_AGENT, "[%d] cannot update UE to slice association, no RNTI in flex_ue_config message\n", mod_id); - return; + return 0; } - if (ue_config->has_dl_slice_id) - LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to DL slice ID %d\n", - mod_id, ue_config->rnti, ue_config->dl_slice_id); - if (ue_config->has_ul_slice_id) - LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to UL slice ID %d\n", - mod_id, ue_config->rnti, ue_config->ul_slice_id); - ue_slice_assoc_update[n_ue_slice_assoc_updates++] = ue_config; - perform_slice_config_update_count = 2; -} - -int apply_ue_slice_assoc_update(mid_t mod_id) -{ - int i; - int changes = 0; - for (i = 0; i < n_ue_slice_assoc_updates; i++) { - int ue_id = find_UE_id(mod_id, ue_slice_assoc_update[i]->rnti); - if (ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB){ - LOG_E(FLEXRAN_AGENT,"UE_id %d is wrong!!\n",ue_id); - continue; - } - if (ue_slice_assoc_update[i]->has_dl_slice_id) { - } - if (ue_slice_assoc_update[i]->has_ul_slice_id) { + int UE_id = flexran_get_mac_ue_id_rnti(mod_id, ue_config->rnti); + if (ue_config->has_dl_slice_id) { + if (flexran_get_dl_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "no DL slice algorithm loaded\n"); + } else { + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to DL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->dl_slice_id); + flexran_set_ue_dl_slice_id(mod_id, UE_id, ue_config->dl_slice_id); } } - n_ue_slice_assoc_updates = 0; - return changes; + if (ue_config->has_ul_slice_id) { + if (flexran_get_ul_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "no UL slice algorithm loaded\n"); + } else { + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to UL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->ul_slice_id); + flexran_set_ue_ul_slice_id(mod_id, UE_id, ue_config->ul_slice_id); + } + } + return 0; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index ef2a7e40a9..9db5d61a11 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -103,23 +103,11 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name); /*** Functions for handling a slice config ***/ -/* allocate memory for a Protocol__FlexSliceConfig structure with n_dl DL slice - * configs and m_ul UL slice configs */ -Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul); - -/* read the general slice parameters via RAN into the given - * Protocol__FlexSliceConfig struct */ -void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s); - -/* reads content of slice over the sc_update structure, so that it can be - * applied later by performing a diff between slice_config and sc_update */ -void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice); - -/* inserts a new ue_config into the structure keeping ue to slice association - * updates and marks so it can be applied */ -void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); +/* Prepare the application of a slicing config */ +void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice); +void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice); /* apply a new association between a UE and a slice (both DL and UL) */ -int apply_ue_slice_assoc_update(mid_t mod_id); +int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); #endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/ diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index e5d01ebdc0..2f2267b628 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -61,6 +61,31 @@ enum flex_qam { // // Slice config related structures and enums // +enum flex_slice_algorithm { + None = 0; + Static = 1; + NVS = 2; +} + +message flex_slice_static { + optional uint32 posLow = 1; + optional uint32 posHigh = 2; +} + +message flex_slice { + optional uint32 id = 1; + optional string label = 2; + optional string scheduler = 3; + oneof params { + flex_slice_static static = 10; + } +} + +message flex_slice_dl_ul_config { + optional flex_slice_algorithm algorithm = 1; + repeated flex_slice slices = 2; + optional string scheduler = 3; // if no slicing +} // // UE config related structures and enums diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 1a66a4f20f..1a69deec71 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -49,6 +49,8 @@ message flex_cell_config { } message flex_slice_config { + optional flex_slice_dl_ul_config dl = 6; + optional flex_slice_dl_ul_config ul = 7; } message flex_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 3dd9f5b957..7569ca1ac1 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -306,6 +306,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc) free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc); + /* si_config is shared between MAC and RRC, free here */ if (reply->cell_config[i]->si_config) { for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) { free(reply->cell_config[i]->si_config->si_message[j]); @@ -316,8 +317,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { } if (reply->cell_config[i]->slice_config) { - /* TODO */ - free(reply->cell_config[i]->slice_config); + flexran_agent_destroy_mac_slice_config(reply->cell_config[i]); } free(reply->cell_config[i]); @@ -880,7 +880,7 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (enb_config->n_cell_config > 0) { if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { - prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); + prepare_update_slice_config(mod_id, &enb_config->cell_config[0]->slice_config); } if (enb_config->cell_config[0]->has_eutra_band && enb_config->cell_config[0]->has_dl_freq @@ -921,7 +921,11 @@ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Proto Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg; for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++) - prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]); + prepare_ue_slice_assoc_update(mod_id, &ue_config_reply->ue_config[i]); + /* prepare_ue_slice_assoc_update takes ownership of the individual + * FlexUeConfig messages. Therefore, mark zero messages to not accidentally + * free them twice */ + ue_config_reply->n_ue_config = 0; *msg = NULL; return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index cd8b0b8f67..79c992a4d7 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -30,6 +30,7 @@ #include "flexran_agent_ran_api.h" #include "s1ap_eNB_ue_context.h" #include "s1ap_eNB_management_procedures.h" +#include "openair2/LAYER2/MAC/slicing/slicing.h" static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) { return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id]; @@ -3013,66 +3014,294 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti) } /**************************** SLICING ****************************/ +Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id) { + if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + + switch (RC.mac[mod_id]->pre_processor_dl.algorithm) { + case STATIC_SLICING: + return PROTOCOL__FLEX_SLICE_ALGORITHM__Static; + default: + return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + } +} + +int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return 0; + eNB_MAC_INST *mac = RC.mac[mod_id]; + const int cc_id = 0; + + pp_impl_param_t dl = mac->pre_processor_dl; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + mac->pre_processor_dl = static_dl_init(mod_id, cc_id); + break; + default: + mac->pre_processor_dl.algorithm = 0; + mac->pre_processor_dl.dl = dlsch_scheduler_pre_processor; + mac->pre_processor_dl.dl_algo.data = mac->pre_processor_dl.dl_algo.setup(); + mac->pre_processor_dl.slices = NULL; + break; + } + if (dl.slices) + dl.destroy(&dl.slices); + if (dl.dl_algo.data) + dl.dl_algo.unset(&dl.dl_algo.data); + return 1; +} + +Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id) { + if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + + switch (RC.mac[mod_id]->pre_processor_ul.algorithm) { + case STATIC_SLICING: + return PROTOCOL__FLEX_SLICE_ALGORITHM__Static; + default: + return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + } +} + +int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return 0; + eNB_MAC_INST *mac = RC.mac[mod_id]; + const int cc_id = 0; + + pp_impl_param_t ul = mac->pre_processor_ul; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + mac->pre_processor_ul = static_ul_init(mod_id, cc_id); + break; + default: + mac->pre_processor_ul.algorithm = 0; + mac->pre_processor_ul.ul = ulsch_scheduler_pre_processor; + mac->pre_processor_ul.ul_algo.data = mac->pre_processor_ul.ul_algo.setup(); + mac->pre_processor_ul.slices = NULL; + break; + } + if (ul.slices) + ul.destroy(&ul.slices); + if (ul.ul_algo.data) + ul.ul_algo.unset(&ul.ul_algo.data); + return 1; +} + int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - return 0; + slice_info_t *slices = RC.mac[mod_id]->pre_processor_dl.slices; + if (!slices) return -1; + const int idx = slices->UE_assoc_slice[ue_id]; + return slices->s[idx]->id; +} + +void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { + if (!mac_is_present(mod_id)) return; + int idx = flexran_find_dl_slice(mod_id, slice_id); + if (idx < 0) return; + pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; + dl->move_UE(dl->slices, ue_id, idx); } int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - return 0; + slice_info_t *slices = RC.mac[mod_id]->pre_processor_ul.slices; + if (!slices) return -1; + const int idx = slices->UE_assoc_slice[ue_id]; + return slices->s[idx]->id; } -/* TODO */ -int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return -1; - return -1; +void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { + if (!mac_is_present(mod_id)) return; + int idx = flexran_find_ul_slice(mod_id, slice_id); + if (idx < 0) return; + pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; + ul->move_UE(ul->slices, ue_id, idx); } -/* TODO */ -int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; +int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return 0; + void *params = NULL; + switch (s->params_case) { + case PROTOCOL__FLEX_SLICE__PARAMS_STATIC: + params = malloc(sizeof(static_slice_param_t)); + if (!params) return 0; + ((static_slice_param_t *)params)->posLow = s->static_->poslow; + ((static_slice_param_t *)params)->posHigh = s->static_->poshigh; + break; + default: + break; + } + pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; + char *l = s->label ? strdup(s->label) : NULL; + void *algo = &dl->dl_algo; // default scheduler + if (s->scheduler) { + algo = dlsym(NULL, s->scheduler); + if (!algo) { + free(params); + LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); + return -15; + } + } + return dl->addmod_slice(dl->slices, s->id, l, algo, params); +} + +int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return 0; + const int idx = flexran_find_dl_slice(mod_id, s->id); + if (idx < 0) return 0; + pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; + return dl->remove_slice(dl->slices, idx); } int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; + slice_info_t *si = RC.mac[mod_id]->pre_processor_dl.slices; + for (int i = 0; i < si->num; ++i) + if (si->s[i]->id == slice_id) + return i; return -1; } -//int flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { -//} +void flexran_get_dl_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return; + slice_t *s_ = RC.mac[mod_id]->pre_processor_dl.slices->s[slice_idx]; + slice->has_id = 1; + slice->id = s_->id; + slice->label = s_->label; + slice->scheduler = s_->dl_algo.name; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic)); + if (!slice->static_) return; + protocol__flex_slice_static__init(slice->static_); + slice->static_->has_poslow = 1; + slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow; + slice->static_->has_poshigh = 1; + slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC; + break; + default: + break; + } +} int flexran_get_num_dl_slices(mid_t mod_id) { - if (!mac_is_present(mod_id)) return -1; - return 0; + if (!mac_is_present(mod_id)) return 0; + if (!RC.mac[mod_id]->pre_processor_dl.slices) return 0; + return RC.mac[mod_id]->pre_processor_dl.slices->num; } -/* TODO */ -void flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; - return; +int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return -1; + void *params = NULL; + switch (s->params_case) { + case PROTOCOL__FLEX_SLICE__PARAMS_STATIC: + params = malloc(sizeof(static_slice_param_t)); + if (!params) return 0; + ((static_slice_param_t *)params)->posLow = s->static_->poslow; + ((static_slice_param_t *)params)->posHigh = s->static_->poshigh; + break; + default: + break; + } + pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; + char *l = s->label ? strdup(s->label) : NULL; + void *algo = &ul->ul_algo; // default scheduler + if (s->scheduler) { + algo = dlsym(NULL, s->scheduler); + if (!algo) { + free(params); + LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); + return -15; + } + } + return ul->addmod_slice(ul->slices, s->id, l, algo, params); } -/* TODO */ -int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; +int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return 0; + const int idx = flexran_find_ul_slice(mod_id, s->id); + if (idx < 0) return 0; + pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; + return ul->remove_slice(ul->slices, idx); } int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; + slice_info_t *si = RC.mac[mod_id]->pre_processor_ul.slices; + for (int i = 0; i < si->num; ++i) + if (si->s[i]->id == slice_id) + return i; return -1; } -//int flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { -//} +void flexran_get_ul_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return; + slice_t *s_ = RC.mac[mod_id]->pre_processor_ul.slices->s[slice_idx]; + slice->has_id = 1; + slice->id = s_->id; + slice->label = s_->label; + slice->scheduler = s_->ul_algo.name; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic)); + if (!slice->static_) return; + protocol__flex_slice_static__init(slice->static_); + slice->static_->has_poslow = 1; + slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow; + slice->static_->has_poshigh = 1; + slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC; + break; + default: + break; + } + +} int flexran_get_num_ul_slices(mid_t mod_id) { + if (!mac_is_present(mod_id)) return 0; + if (!RC.mac[mod_id]->pre_processor_ul.slices) return 0; + return RC.mac[mod_id]->pre_processor_ul.slices->num; +} + +char *flexran_get_dl_scheduler_name(mid_t mod_id) { + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->pre_processor_dl.dl_algo.name; +} + +int flexran_set_dl_scheduler(mid_t mod_id, char *sched) { if (!mac_is_present(mod_id)) return -1; + void *d = dlsym(NULL, sched); + if (!d) return -2; + pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl; + dl_pp->dl_algo.unset(&dl_pp->dl_algo.data); + dl_pp->dl_algo = *(default_sched_dl_algo_t *) d; + dl_pp->dl_algo.data = dl_pp->dl_algo.setup(); return 0; } +char *flexran_get_ul_scheduler_name(mid_t mod_id) { + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->pre_processor_ul.ul_algo.name; +} + +int flexran_set_ul_scheduler(mid_t mod_id, char *sched) { + if (!mac_is_present(mod_id)) return -1; + void *d = dlsym(NULL, sched); + if (!d) return -2; + pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul; + ul_pp->ul_algo.unset(&ul_pp->ul_algo.data); + ul_pp->ul_algo = *(default_sched_ul_algo_t *) d; + ul_pp->ul_algo.data = ul_pp->ul_algo.setup(); + return 0; +} /************************** S1AP **************************/ int flexran_get_s1ap_mme_pending(mid_t mod_id){ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index c29ba53c11..2d8a86f7d0 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -656,41 +656,66 @@ int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index); uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti); /************************** Slice configuration **************************/ +/* Get the currently active DL slicing algorithm */ +Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id); +/* Set the active DL slicing algorithm */ +int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo); + +/* Get the currently active UL slicing algorithm */ +Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id); +/* Set the active UL slicing algorithm */ +int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo); /* Get the DL slice ID for a UE */ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id); -/* Set the DL slice index(!) for a UE */ -//void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +/* Set the DL slice for a UE */ +void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); /* Get the UL slice ID for a UE */ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id); -/* Set the UL slice index(!) for a UE */ -//void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +/* Set the UL slice for a UE */ +void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); /* Create slice in DL, returns the new slice index */ -//int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); +int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Remove slice in DL, returns new number of slices or -1 on error */ -//int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); +int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Finds slice in DL with given slice_id and returns slice index */ int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); /* Return the parameters of slice at index slice_idx */ -//void flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); +void flexran_get_dl_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo); /* Get the number of slices in DL */ int flexran_get_num_dl_slices(mid_t mod_id); /* Create slice in UL, returns the new slice index */ -//int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); +int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Remove slice in UL */ -//int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); +int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Finds slice in DL with given slice_id and returns slice index */ int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); /* Return the parameters of slice at index slice_idx */ -//void flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); +void flexran_get_ul_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo); /* Get the number of slices in UL */ int flexran_get_num_ul_slices(mid_t mod_id); +/* Get the name of/Set the DL scheduling algorithm. If slicing is active, this + * corresponds to the default algorithm for slices, otherwise the currently + * used one. */ +char *flexran_get_dl_scheduler_name(mid_t mod_id); +int flexran_set_dl_scheduler(mid_t mod_id, char *sched); + +/* Get the name of/Set the UL scheduler algorithm. Same applies as for the DL + * case */ +char *flexran_get_ul_scheduler_name(mid_t mod_id); +int flexran_set_ul_scheduler(mid_t mod_id, char *sched); /************************** S1AP **************************/ /* Get the number of MMEs to be connected */ diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 24038e60d5..af6d1a7ac3 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -100,6 +100,7 @@ void mac_top_init_eNB(void) mac[i]->if_inst = IF_Module_init(i); + mac[i]->pre_processor_dl.algorithm = 0; mac[i]->pre_processor_dl.dl = dlsch_scheduler_pre_processor; char *s = "round_robin_dl"; void *d = dlsym(NULL, s); @@ -107,6 +108,7 @@ void mac_top_init_eNB(void) mac[i]->pre_processor_dl.dl_algo = *(default_sched_dl_algo_t *) d; mac[i]->pre_processor_dl.dl_algo.data = mac[i]->pre_processor_dl.dl_algo.setup(); + mac[i]->pre_processor_ul.algorithm = 0; mac[i]->pre_processor_ul.ul = ulsch_scheduler_pre_processor; s = "round_robin_ul"; d = dlsym(NULL, s); diff --git a/openair2/LAYER2/MAC/slicing/slicing.c b/openair2/LAYER2/MAC/slicing/slicing.c index a1de326df0..9c88f6cffb 100644 --- a/openair2/LAYER2/MAC/slicing/slicing.c +++ b/openair2/LAYER2/MAC/slicing/slicing.c @@ -258,13 +258,26 @@ int addmod_static_slice_ul(slice_info_t *si, return si->num - 1; } -int remove_static_slice(slice_info_t *si, uint8_t slice_idx) { +int remove_static_slice_dl(slice_info_t *si, uint8_t slice_idx) { if (slice_idx == 0) return 0; slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx); if (!sr) return 0; free(sr->algo_data); + sr->dl_algo.unset(&sr->dl_algo.data); + free(sr); + return 1; +} + +int remove_static_slice_ul(slice_info_t *si, uint8_t slice_idx) { + if (slice_idx == 0) + return 0; + slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx); + if (!sr) + return 0; + free(sr->algo_data); + sr->ul_algo.unset(&sr->ul_algo.data); free(sr); return 1; } @@ -528,6 +541,7 @@ pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) { dlp->posLow = 0; dlp->posHigh = to_rbg(RC.mac[mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - 1; default_sched_dl_algo_t *algo = &RC.mac[mod_id]->pre_processor_dl.dl_algo; + algo->data = NULL; DevAssert(0 == addmod_static_slice_dl(si, 0, strdup("default"), algo, dlp)); const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) @@ -539,7 +553,7 @@ pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) { sttc.remove_UE = slicing_remove_UE; sttc.move_UE = slicing_move_UE; sttc.addmod_slice = addmod_static_slice_dl; - sttc.remove_slice = remove_static_slice; + sttc.remove_slice = remove_static_slice_dl; sttc.dl = static_dl; // current DL algo becomes default scheduler sttc.dl_algo = *algo; @@ -564,6 +578,7 @@ pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) { ulp->posLow = 0; ulp->posHigh = to_prb(RC.mac[mod_id]->common_channels[CC_id].ul_Bandwidth) - 1; default_sched_ul_algo_t *algo = &RC.mac[mod_id]->pre_processor_ul.ul_algo; + algo->data = NULL; DevAssert(0 == addmod_static_slice_ul(si, 0, strdup("default"), algo, ulp)); const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) @@ -575,7 +590,7 @@ pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) { sttc.remove_UE = slicing_remove_UE; sttc.move_UE = slicing_move_UE; sttc.addmod_slice = addmod_static_slice_ul; - sttc.remove_slice = remove_static_slice; + sttc.remove_slice = remove_static_slice_ul; sttc.ul = static_ul; // current DL algo becomes default scheduler sttc.ul_algo = *algo; From 05c10662daf0ee11dee115e473cf7681000a2fc1 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jun 2020 13:25:28 +0200 Subject: [PATCH 047/171] FlexRAN Bugfix: Free Ringbuffer on exit --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index e5d1c94c95..4c5f3e5609 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1619,6 +1619,11 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) LOG_E(FLEXRAN_AGENT, "MAC agent CM for eNB %d is not registered\n", mod_id); return -1; } + + lfds700_ringbuffer_cleanup(&ringbuffer_state[mod_id], NULL ); + free(dl_mac_config_array[mod_id]); + lfds700_misc_library_cleanup(); + AGENT_MAC_xface *xface = agent_mac_xface[mod_id]; xface->flexran_agent_send_sr_info = NULL; xface->flexran_agent_send_sf_trigger = NULL; From dcd43c1526104567d052e6138f9fd799ee3befa6 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jun 2020 13:50:59 +0200 Subject: [PATCH 048/171] FlexRAN: use lock-free ringbuffers for slice conf Use LFDS 7.0.0 Ringbuffer implementation to handle * Slice Configuration * UE slice association which is then uploaded through MAC scheduling thread --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 100 ++++++++++++++++-- 1 file changed, 92 insertions(+), 8 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 4c5f3e5609..f1daacbb65 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -49,6 +49,14 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; +/* Ringbuffer-related to slice configuration */ +struct lfds700_ringbuffer_element *slice_config_array[NUM_MAX_ENB]; +struct lfds700_ringbuffer_state slice_config_ringbuffer_state[NUM_MAX_ENB]; + +/* Ringbuffer-related to slice configuration */ +struct lfds700_ringbuffer_element *ue_assoc_array[NUM_MAX_ENB]; +struct lfds700_ringbuffer_state ue_assoc_ringbuffer_state[NUM_MAX_ENB]; + int flexran_agent_mac_stats_reply_ue(mid_t mod_id, Protocol__FlexUeStatsReport **ue_report, int n_ue, @@ -1341,6 +1349,33 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { AssertFatal(i == 0, "posix_memalign(): could not allocate aligned memory for lfds library\n"); lfds700_ringbuffer_init_valid_on_current_logical_core(&ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL); + + struct lfds700_misc_prng_state scrng; + i = posix_memalign((void **) &slice_config_array[mod_id], + LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, + sizeof(struct lfds700_ringbuffer_element) * num_elements); + AssertFatal(i == 0, + "posix_memalign(): could not allocate aligned memory\n"); + lfds700_ringbuffer_init_valid_on_current_logical_core( + &slice_config_ringbuffer_state[mod_id], + slice_config_array[mod_id], + num_elements, + &scrng, + NULL); + + struct lfds700_misc_prng_state uarng; + i = posix_memalign((void **) &ue_assoc_array[mod_id], + LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, + sizeof(struct lfds700_ringbuffer_element) * num_elements); + AssertFatal(i == 0, + "posix_memalign(): could not allocate aligned memory\n"); + lfds700_ringbuffer_init_valid_on_current_logical_core( + &ue_assoc_ringbuffer_state[mod_id], + ue_assoc_array[mod_id], + num_elements, + &uarng, + NULL); + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { for (j = 0; j < 8; j++) { if (RC.mac && RC.mac[mod_id]) @@ -1622,6 +1657,10 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) lfds700_ringbuffer_cleanup(&ringbuffer_state[mod_id], NULL ); free(dl_mac_config_array[mod_id]); + lfds700_ringbuffer_cleanup(&slice_config_ringbuffer_state[mod_id], NULL ); + free(slice_config_array[mod_id]); + lfds700_ringbuffer_cleanup(&ue_assoc_ringbuffer_state[mod_id], NULL ); + free(ue_assoc_array[mod_id]); lfds700_misc_library_cleanup(); AGENT_MAC_xface *xface = agent_mac_xface[mod_id]; @@ -1661,23 +1700,68 @@ void helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) { void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) { if (!*slice_config) return; + /* just use the memory and set to NULL in original */ Protocol__FlexSliceConfig *sc = *slice_config; *slice_config = NULL; - /* TODO handle using lock-free queue */ - apply_update_dl_slice_config(mod_id, sc->dl); - apply_update_ul_slice_config(mod_id, sc->ul); + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + enum lfds700_misc_flag overwrite_occurred_flag; - helper_destroy_mac_slice_config(*slice_config); + Protocol__FlexSliceConfig *overwritten_sc; + lfds700_ringbuffer_write(&slice_config_ringbuffer_state[mod_id], + NULL, + (void *)sc, + &overwrite_occurred_flag, + NULL, + (void **)&overwritten_sc, + &ls); + + if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) { + helper_destroy_mac_slice_config(overwritten_sc); + LOG_E(FLEXRAN_AGENT, "lost slice config: too many reconfigurations at once\n"); + } } void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config) { - /* TODO handle using lock-free queue */ - apply_ue_slice_assoc_update(mod_id, *ue_config); + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + enum lfds700_misc_flag overwrite_occurred_flag; - free(*ue_config); - *ue_config = NULL; + Protocol__FlexUeConfig *overwritten_ue_config; + lfds700_ringbuffer_write(&ue_assoc_ringbuffer_state[mod_id], + NULL, + (void *) *ue_config, + &overwrite_occurred_flag, + NULL, + (void **)&overwritten_ue_config, + &ls); + + if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) { + free(overwritten_ue_config); + LOG_E(FLEXRAN_AGENT, "lost UE-slice association: too many UE-slice associations at once\n"); + } } void flexran_agent_slice_update(mid_t mod_id) { + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + + Protocol__FlexSliceConfig *sc = NULL; + struct lfds700_ringbuffer_state *state = &slice_config_ringbuffer_state[mod_id]; + if (lfds700_ringbuffer_read(state, NULL, (void **) &sc, &ls) != 0) { + apply_update_dl_slice_config(mod_id, sc->dl); + apply_update_ul_slice_config(mod_id, sc->ul); + helper_destroy_mac_slice_config(sc); + } + + Protocol__FlexUeConfig *ue_config = NULL; + state = &ue_assoc_ringbuffer_state[mod_id]; + if (lfds700_ringbuffer_read(state, NULL, (void **) &ue_config, &ls) != 0) { + apply_ue_slice_assoc_update(mod_id, ue_config); + free(ue_config); + } } From 79a655d47e8a3c8bd35d64e5bcfb553d3df58310 Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 15 Jun 2020 16:26:42 +0200 Subject: [PATCH 049/171] Use MCS 9 for Msg2 to avoid issues with the LDPC decoder - LDPC decoder does not support lower MCS, therefore MCS 9 has been selected for the Msg2 configuration. - This is done only in do-ra mode, in order to prevent any fallout on the current the configuration used for the operation with the commercial UE --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index 6ce72059fd..30b3456add 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -590,7 +590,11 @@ void nr_generate_Msg2(module_id_t module_idP, LOG_D(MAC, "[RAPROC] Scheduling common search space DCI type 1 dlBWP BW %d\n", dci10_bw); - mcsIndex = 0; // Qm>2 not allowed for RAR + // Qm>2 not allowed for RAR + if (get_softmodem_params()->do_ra) + mcsIndex = 9; + else + mcsIndex = 0; pdsch_pdu_rel15->pduBitmap = 0; pdsch_pdu_rel15->rnti = RA_rnti; From 8e271ce945a99d6b2c6b27733764d8b9c15ee211 Mon Sep 17 00:00:00 2001 From: cig Date: Mon, 15 Jun 2020 16:40:57 +0200 Subject: [PATCH 050/171] Fixes for reception of Msg2: - ceiling computation num of segments (cod/dec) - fixes demodulation - initialisation CW for PDSCH RA - memcpy dl_ch_estimates to pdsch_vars_ra (hotfix) - correct N_RB for DCI 1_0 and RNTI_RA --- openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c | 2 +- .../PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 2 +- .../NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 49 ++++++++++++------- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 5 +- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c index 3aa87d656e..881ebbd5dc 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_coding.c @@ -150,7 +150,7 @@ NR_gNB_DLSCH_t *new_gNB_dlsch(NR_DL_FRAME_PARMS *frame_parms, if (N_RB != 273) { a_segments = a_segments*N_RB; - a_segments = a_segments/273; + a_segments = (a_segments + 272) / 273; } uint16_t dlsch_bytes = a_segments*1056; // allocated bytes per segment diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 8214bdca99..cae70d3c9e 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -406,7 +406,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, if (nb_rb != 273) { a_segments = a_segments*nb_rb; - a_segments = a_segments/273; + a_segments = (a_segments + 272) / 273; } if (harq_process->C > a_segments) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index 7f941e5567..b0f2b99ee6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -134,7 +134,7 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, int avgs = 0;// rb; NR_DL_UE_HARQ_t *dlsch0_harq, *dlsch1_harq = NULL; - uint8_t beamforming_mode; + uint8_t beamforming_mode = 0; int32_t **rxdataF_comp_ptr; int32_t **dl_ch_mag_ptr; @@ -162,24 +162,34 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, pdsch_vars = ue->pdsch_vars_SI; dlsch = &ue->dlsch_SI[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - beamforming_mode = 0; + break; case RA_PDSCH: pdsch_vars = ue->pdsch_vars_ra; dlsch = &ue->dlsch_ra[eNB_id]; dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - beamforming_mode = 0; + + // WIP TBR Hotfix + memcpy((void*)&pdsch_vars[eNB_id]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], (void*)&ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]][0]->dl_ch_estimates[0][ue->frame_parms.ofdm_symbol_size*2], ue->frame_parms.ofdm_symbol_size*sizeof(int32_t)); break; case PDSCH: pdsch_vars = ue->pdsch_vars[ue->current_thread_id[nr_tti_rx]]; dlsch = ue->dlsch[ue->current_thread_id[nr_tti_rx]][eNB_id]; - beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id]; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; dlsch1_harq = dlsch[1]->harq_processes[harq_pid]; + beamforming_mode = ue->transmission_mode[eNB_id] < 7 ? 0 :ue->transmission_mode[eNB_id]; + break; + + default: + AssertFatal(1 == 0, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type); + return(-1); + break; + } + + if (dlsch1_harq){ //printf("status TB0 = %d, status TB1 = %d \n", dlsch[0]->harq_processes[harq_pid]->status, dlsch[1]->harq_processes[harq_pid]->status); LOG_D(PHY,"AbsSubframe %d.%d / Sym %d harq_pid %d, harq status %d.%d \n", frame, nr_tti_rx, symbol, harq_pid, dlsch0_harq->status, dlsch1_harq->status); @@ -191,27 +201,25 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid]; #ifdef DEBUG_HARQ - printf("[DEMOD] I am assuming both TBs are active\n"); + printf("[DEMOD] I am assuming both TBs are active, in cw0 %d and cw1 %d \n", codeword_TB0, codeword_TB1); #endif } else if ((dlsch0_harq->status == ACTIVE) && (dlsch1_harq->status != ACTIVE) ) { codeword_TB0 = dlsch0_harq->codeword; - codeword_TB1 = -1; - dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; + dlsch0_harq = dlsch[codeword_TB0]->harq_processes[harq_pid]; dlsch1_harq = NULL; #ifdef DEBUG_HARQ - printf("[DEMOD] I am assuming only TB0 is active\n"); + printf("[DEMOD] I am assuming only TB0 is active, in cw %d \n", codeword_TB0); #endif } else if ((dlsch0_harq->status != ACTIVE) && (dlsch1_harq->status == ACTIVE)){ - codeword_TB0 = -1; codeword_TB1 = dlsch1_harq->codeword; dlsch0_harq = NULL; - dlsch1_harq = dlsch[1]->harq_processes[codeword_TB1]; + dlsch1_harq = dlsch[codeword_TB1]->harq_processes[harq_pid]; #ifdef DEBUG_HARQ - printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", dlsch1_harq->codeword); + printf("[DEMOD] I am assuming only TB1 is active, it is in cw %d\n", codeword_TB1); #endif AssertFatal(1 == 0, "[UE][FATAL] DLSCH: TB0 not active and TB1 active case is not supported\n"); @@ -220,14 +228,17 @@ int nr_rx_pdsch(PHY_VARS_NR_UE *ue, LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx); return(-1); } + } else if (dlsch0_harq) { + if (dlsch0_harq->status == ACTIVE) + codeword_TB0 = dlsch0_harq->codeword; + dlsch0_harq = dlsch[0]->harq_processes[harq_pid]; - break; - - default: - AssertFatal(1 == 0, "[UE][FATAL] nr_tti_rx %d: Unknown PDSCH format %d\n", nr_tti_rx, type); - return(-1); - break; - + #ifdef DEBUG_HARQ + printf("[DEMOD] I am assuming only TB0 is active\n"); + #endif + } else { + LOG_E(PHY,"[UE][FATAL] nr_tti_rx %d: no active DLSCH\n", nr_tti_rx); + return (-1); } if (dlsch0_harq == NULL) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 0da02bd7d1..7adc58f626 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2312,7 +2312,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr AssertFatal(mac->DLbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n"); AssertFatal(mac->ULbwp[0]!=NULL,"DLbwp[0] should not be zero here!\n"); - const uint16_t n_RB_DLBWP = NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); + const uint16_t n_RB_DLBWP = (mac->ra_state == WAIT_RAR) ? NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275) : NRRIV2BW(mac->DLbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); const uint16_t n_RB_ULBWP = NRRIV2BW(mac->ULbwp[0]->bwp_Common->genericParameters.locationAndBandwidth,275); LOG_D(MAC,"nr_ue_process_dci at MAC layer with dci_format=%d (DL BWP %d, UL BWP %d)\n",dci_format,n_RB_DLBWP,n_RB_ULBWP); @@ -2767,7 +2767,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr /* HARQ_PROCESS_NUMBER (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ dlsch_config_pdu_1_0->harq_process_nbr = dci->harq_process_number; /* DAI (only if CRC scrambled by C-RNTI or CS-RNTI or new-RNTI or TC-RNTI)*/ - dlsch_config_pdu_1_0->dai = dci ->dai; + dlsch_config_pdu_1_0->dai = dci->dai; /* TB_SCALING (only if CRC scrambled by P-RNTI or RA-RNTI) */ // according to TS 38.214 Table 5.1.3.2-3 if (dci->tb_scaling == 0) dlsch_config_pdu_1_0->scaling_factor_S = 1; @@ -3129,6 +3129,7 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac, case NR_DL_DCI_FORMAT_1_0: switch(rnti_type) { case NR_RNTI_RA: + N_RB = NRRIV2BW(mac->scc->downlinkConfigCommon->initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); // TBR hotfix // Freq domain assignment fsize = (int)ceil( log2( (N_RB*(N_RB+1))>>1 ) ); pos=fsize; From 6737d273468a297928c5d4a2e2b93f3a007b7220 Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 30 Jun 2020 12:59:08 +0200 Subject: [PATCH 051/171] PUSCH data filling from PHY to MAC: - IP data were fetched and passed to MAC directly at the PHY layer - random data was generated whenever there's no upcoming data. - Therefore these functionalities are now moved to MAC and FAPI interfaces - are used instead. --- openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c | 54 +--- openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 31 ++- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 244 +++++++++++++------ 3 files changed, 192 insertions(+), 137 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c index 9be4a16fb5..1405aae2cb 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_ulsch_ue.c @@ -98,7 +98,7 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, uint8_t thread_id, int gNB_id) { - uint32_t available_bits, TBS; + uint32_t available_bits; uint8_t mod_order, cwd_index, num_of_codewords, l; uint32_t scrambled_output[NR_MAX_NB_CODEWORDS][NR_MAX_PDSCH_ENCODED_LENGTH>>5]; uint32_t ***pusch_dmrs; @@ -111,7 +111,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, int ap, start_symbol, Nid_cell, i; int sample_offsetF, N_RE_prime, N_PRB_oh; uint16_t ul_dmrs_symb_pos; - uint8_t data_existing =0; uint8_t L_ptrs, K_ptrs; // PTRS parameters uint16_t beta_ptrs; // PTRS parameter related to power control uint8_t no_data_in_dmrs = 1; @@ -120,7 +119,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, NR_UL_UE_HARQ_t *harq_process_ul_ue=NULL; NR_DL_FRAME_PARMS *frame_parms = &UE->frame_parms; NR_UE_PUSCH *pusch_ue = UE->pusch_vars[thread_id][gNB_id]; - uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; // ptrs_UplinkConfig_t *ptrs_Uplink_Config = &UE->pusch_config.dmrs_UplinkConfig.ptrs_UplinkConfig; num_of_codewords = 1; // tmp assumption @@ -174,55 +172,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, 0, harq_process_ul_ue->pusch_pdu.nrOfLayers); - - uint8_t access_mode = SCHEDULED_ACCESS; - - //-----------------------------------------------------// - // to be removed later when MAC is ready - - if (harq_process_ul_ue != NULL){ - TBS = harq_process_ul_ue->pusch_pdu.pusch_data.tb_size; - data_existing = 0; - - if (IS_SOFTMODEM_NOS1){ - data_existing = nr_ue_get_sdu(UE->Mod_id, UE->CC_id, frame, - slot, 0, ulsch_input_buffer, TBS/8, &access_mode); - //IP traffic to be transmitted - if(data_existing){ - //harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char)); - memcpy(harq_process_ul_ue->a, ulsch_input_buffer, TBS/8); - } - } - //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity - if (!IS_SOFTMODEM_NOS1 || !data_existing) { - //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid - //and block this traffic from being forwarded to the upper layers at the gNB - LOG_D(PHY, "Random data to be tranmsitted: \n"); - - //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) - //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should - //have a valid LCID (nr_process_mac_pdu function) - harq_process_ul_ue->a[0] = 0x31; - - for (i = 1; i < TBS / 8; i++) { - harq_process_ul_ue->a[i] = (unsigned char) rand(); - //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); - } - } -#ifdef DEBUG_MAC_PDU - LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS/8); - for (i = 0; i < TBS / 8; i++) { - printf("%02x",harq_process_ul_ue->a[i]); - } - printf("\n"); -#endif - } else { - LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n"); - return; - } - - //-----------------------------------------------------// - /////////////////////////ULSCH coding///////////////////////// /////////// @@ -473,7 +422,6 @@ void nr_ue_ulsch_procedures(PHY_VARS_NR_UE *UE, /////////// //////////////////////////////////////////////////////////////////////// - LOG_D(PHY, "Is data existing ?: %d \n", data_existing); } diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index f7e03b7dfe..5537705b20 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -139,12 +139,32 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ // pusch config pdu pusch_config_pdu = &ul_config->ul_config_list[i].pusch_config_pdu; current_harq_pid = pusch_config_pdu->pusch_data.harq_process_id; - nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &ulsch0->harq_processes[current_harq_pid]->pusch_pdu; + NR_UL_UE_HARQ_t *harq_process_ul_ue = ulsch0->harq_processes[current_harq_pid]; - memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t)); + if (harq_process_ul_ue){ + + nfapi_nr_ue_pusch_pdu_t *pusch_pdu = &harq_process_ul_ue->pusch_pdu; + + memcpy(pusch_pdu, pusch_config_pdu, sizeof(nfapi_nr_ue_pusch_pdu_t)); + + ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; + + if (scheduled_response->tx_request){ + fapi_nr_tx_request_body_t *tx_req_body = scheduled_response->tx_request->tx_request_body; + + //harq_process_ul_ue->a = (unsigned char*)calloc(TBS/8, sizeof(unsigned char)); + memcpy(harq_process_ul_ue->a, tx_req_body->pdu, tx_req_body->pdu_length); + + harq_process_ul_ue->status = ACTIVE; + } + + } else { + + LOG_E(PHY, "[phy_procedures_nrUE_TX] harq_process_ul_ue is NULL !!\n"); + return -1; + + } - ulsch0->f_pusch = pusch_config_pdu->absolute_delta_PUSCH; - ulsch0->harq_processes[current_harq_pid]->status = ACTIVE; break; case (FAPI_NR_UL_CONFIG_TYPE_PUCCH): @@ -206,9 +226,6 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ } else { } - if (scheduled_response->tx_request != NULL){ - } else { - } } return 0; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 7adc58f626..5468a85f1c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -755,91 +755,181 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in } */ } - } else if (ul_info && ul_info->slot_tx == 8) { - module_id_t mod_id = ul_info->module_id; - uint32_t gNB_index = ul_info->gNB_index; - int cc_id = ul_info->cc_id; - frame_t rx_frame = ul_info->frame_rx; - slot_t rx_slot = ul_info->slot_rx; - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + } else if (ul_info) { - // program PUSCH. this should actually be done upon reception of an UL DCI - nr_dcireq_t dcireq; - nr_scheduled_response_t scheduled_response; + if (get_softmodem_params()->phy_test && ul_info->slot_tx == 8) { // ULSCH is handled only in phy-test mode (consistently with OAI gNB) - //--------------------------Temporary configuration-----------------------------// - uint16_t rnti = 0x1234; - uint32_t rb_size = 50; - uint32_t rb_start = 0; - uint8_t nr_of_symbols = 12; - uint8_t start_symbol_index = 2; - uint8_t nrOfLayers = 1; - uint8_t mcs_index = 9; - uint8_t mcs_table = 0; - uint8_t harq_process_id = 0; - uint8_t rv_index = 0; - uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1); - uint8_t dmrs_config_type = 0; - uint8_t ptrs_mcs1 = 2; - uint8_t ptrs_mcs2 = 4; - uint8_t ptrs_mcs3 = 10; - uint16_t n_rb0 = 25; - uint16_t n_rb1 = 75; - uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; - uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table); - uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size); - //------------------------------------------------------------------------------// + uint8_t nb_dmrs_re_per_rb; + uint8_t ulsch_input_buffer[MAX_ULSCH_PAYLOAD_BYTES]; + uint8_t data_existing = 0; + uint16_t TBS_bytes; + uint32_t TBS; + int i; - dcireq.module_id = mod_id; - dcireq.gNB_index = gNB_index; - dcireq.cc_id = cc_id; - dcireq.frame = rx_frame; - dcireq.slot = rx_slot; + module_id_t mod_id = ul_info->module_id; + uint32_t gNB_index = ul_info->gNB_index; + int cc_id = ul_info->cc_id; + frame_t rx_frame = ul_info->frame_rx; + slot_t rx_slot = ul_info->slot_rx; + frame_t frame_tx = ul_info->frame_tx; + slot_t slot_tx = ul_info->slot_tx; + NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); + uint8_t access_mode = SCHEDULED_ACCESS; - scheduled_response.dl_config = NULL; - scheduled_response.ul_config = &dcireq.ul_config_req; - scheduled_response.tx_request = NULL; - scheduled_response.module_id = mod_id; - scheduled_response.CC_id = cc_id; - scheduled_response.frame = rx_frame; - scheduled_response.slot = rx_slot; + // program PUSCH. this should actually be done upon reception of an UL DCI + nr_dcireq_t dcireq; + nr_scheduled_response_t scheduled_response; + fapi_nr_tx_request_t tx_req; + fapi_nr_tx_request_body_t tx_req_body; - scheduled_response.ul_config->slot = ul_info->slot_tx; - scheduled_response.ul_config->number_pdus = 1; - scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = l_prime_mask << start_symbol_index; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density; - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t)); - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + //--------------------------Temporary configuration-----------------------------// + uint16_t rnti = 0x1234; + uint32_t rb_size = 50; + uint32_t rb_start = 0; + uint8_t nr_of_symbols = 12; + uint8_t start_symbol_index = 2; + uint8_t nrOfLayers = 1; + uint8_t mcs_index = 9; + uint8_t mcs_table = 0; + uint8_t harq_process_id = 0; + uint8_t rv_index = 0; + uint16_t l_prime_mask = get_l_prime(nr_of_symbols, typeB, pusch_dmrs_pos0, pusch_len1); + uint8_t dmrs_config_type = 0; + uint8_t ptrs_mcs1 = 2; + uint8_t ptrs_mcs2 = 4; + uint8_t ptrs_mcs3 = 10; + uint16_t n_rb0 = 25; + uint16_t n_rb1 = 75; + uint16_t pdu_bit_map = PUSCH_PDU_BITMAP_PUSCH_DATA; + uint8_t ptrs_time_density = get_L_ptrs(ptrs_mcs1, ptrs_mcs2, ptrs_mcs3, mcs_index, mcs_table); + uint8_t ptrs_freq_density = get_K_ptrs(n_rb0, n_rb1, rb_size); + uint8_t no_data_in_dmrs = 1; + uint16_t number_dmrs_symbols = 0; + uint16_t ul_dmrs_symb_pos = l_prime_mask << start_symbol_index; + //------------------------------------------------------------------------------// - if (1 << ptrs_time_density >= nr_of_symbols) { - scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS + for (i = start_symbol_index; i < start_symbol_index + nr_of_symbols; i++) { + if((ul_dmrs_symb_pos >> i) & 0x01) + number_dmrs_symbols += 1; + } + + if(no_data_in_dmrs) + nb_dmrs_re_per_rb = 12; + else + nb_dmrs_re_per_rb = ((dmrs_config_type == pusch_dmrs_type1) ? 6:4); + + TBS = nr_compute_tbs(nr_get_Qm_ul(mcs_index, 0), + nr_get_code_rate_ul(mcs_index, 0), + rb_size, + nr_of_symbols, + nb_dmrs_re_per_rb*number_dmrs_symbols, + 0, + 0, + nrOfLayers); + TBS_bytes = TBS/8; + + if (IS_SOFTMODEM_NOS1){ + // Getting IP traffic to be transmitted + data_existing = nr_ue_get_sdu(mod_id, + cc_id, + frame_tx, + slot_tx, + 0, + ulsch_input_buffer, + TBS_bytes, + &access_mode); + } + + //Random traffic to be transmitted if there is no IP traffic available for this Tx opportunity + if (!IS_SOFTMODEM_NOS1 || !data_existing) { + //Use zeros for the header bytes in noS1 mode, in order to make sure that the LCID is not valid + //and block this traffic from being forwarded to the upper layers at the gNB + LOG_D(PHY, "Random data to be tranmsitted: \n"); + + //Give the first byte a dummy value (a value not corresponding to any valid LCID based on 38.321, Table 6.2.1-2) + //in order to distinguish the PHY random packets at the MAC layer of the gNB receiver from the normal packets that should + //have a valid LCID (nr_process_mac_pdu function) + ulsch_input_buffer[0] = 0x31; + + for (i = 1; i < TBS_bytes; i++) { + ulsch_input_buffer[i] = (unsigned char) rand(); + //printf(" input encoder a[%d]=0x%02x\n",i,harq_process_ul_ue->a[i]); + } + } + +#ifdef DEBUG_MAC_PDU + + LOG_D(PHY, "Is data existing ?: %d \n", data_existing); + LOG_I(PHY, "Printing MAC PDU to be encoded, TBS is: %d \n", TBS_bytes); + for (i = 0; i < TBS_bytes; i++) { + printf("%02x", ulsch_input_buffer[i]); + } + printf("\n"); + +#endif + + dcireq.module_id = mod_id; + dcireq.gNB_index = gNB_index; + dcireq.cc_id = cc_id; + dcireq.frame = rx_frame; + dcireq.slot = rx_slot; + + scheduled_response.dl_config = NULL; + scheduled_response.ul_config = &dcireq.ul_config_req; + // Config UL TX PDU + tx_req.slot = slot_tx; + tx_req.sfn = frame_tx; + // tx_req->tx_config // TbD + tx_req.number_of_pdus = 1; + tx_req_body.pdu_length = TBS_bytes; + tx_req_body.pdu_index = 0; + tx_req_body.pdu = ulsch_input_buffer; + + scheduled_response.tx_request = &tx_req; + scheduled_response.tx_request->tx_request_body = &tx_req_body; + scheduled_response.module_id = mod_id; + scheduled_response.CC_id = cc_id; + scheduled_response.frame = rx_frame; + scheduled_response.slot = rx_slot; + + printf("DEGUG nr_ue_scheduler Scheduling FAPI_NR_UL_CONFIG_TYPE_PUSCH \n"); + + scheduled_response.ul_config->slot = ul_info->slot_tx; + scheduled_response.ul_config->number_pdus = 1; + scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rnti = rnti; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_size = rb_size; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.rb_start = rb_start; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nr_of_symbols = nr_of_symbols; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.start_symbol_index = start_symbol_index; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.ul_dmrs_symb_pos = ul_dmrs_symb_pos; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.dmrs_config_type = dmrs_config_type; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_index = mcs_index; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.mcs_table = mcs_table; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.new_data_indicator = 0; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.rv_index = rv_index; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.nrOfLayers = nrOfLayers; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_data.harq_process_id = harq_process_id; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map = pdu_bit_map; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_time_density = ptrs_time_density; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_freq_density = ptrs_freq_density; + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list = (nfapi_nr_ue_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ue_ptrs_ports_t)); + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; + + if (1 << ptrs_time_density >= nr_of_symbols) { + scheduled_response.ul_config->ul_config_list[0].pusch_config_pdu.pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS + } + + if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ + mac->if_module->scheduled_response(&scheduled_response); + } + + // TODO: expand + // Note: Contention resolution is currently not active + if (mac->RA_contention_resolution_timer_active == 1) + ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx); } - - if(mac->if_module != NULL && mac->if_module->scheduled_response != NULL){ - mac->if_module->scheduled_response(&scheduled_response); - } - - // TODO: expand - // Note: Contention resolution is currently not active - if (mac->RA_contention_resolution_timer_active == 1) - ue_contention_resolution(mod_id, gNB_index, cc_id, ul_info->frame_tx); } - return UE_CONNECTION_OK; } From e054b5e2472e1b40a133b216edc2e21b6da5a34e Mon Sep 17 00:00:00 2001 From: cig Date: Tue, 30 Jun 2020 13:20:07 +0200 Subject: [PATCH 052/171] RA Msg2 reception according to 8.2 of TS 38.213 - Msg2 scheduler used for testing purposes was removed - Now the UE tries to DCI 1_0 scrambled with RA_RNTI in the RA window - If no RAPID is found within the RA window, instructs PHY to TX PRACH --- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 5 - openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 14 +-- .../NR_MAC_UE/nr_ue_dci_configuration.c | 24 ++-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 103 +----------------- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 7 -- 5 files changed, 22 insertions(+), 131 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index a711561747..bc89695620 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -222,11 +222,6 @@ typedef struct { uint32_t RA_tx_frame; /// Random-access variable for window calculation (subframe of last change in window counter) uint8_t RA_tx_subframe; - /// Scheduled RX frame for RA Msg2 - uint16_t msg2_rx_frame; - /// Scheduled RX slot for RA Msg2 - uint16_t msg2_rx_slot; - /// Random-access Group B maximum path-loss /// Random-access variable for backoff (frame of last change in backoff counter) uint32_t RA_backoff_frame; /// Random-access variable for backoff (subframe of last change in backoff counter) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 6a3f4ad902..31fa49f20c 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -363,7 +363,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); - if (UE_mode == PRACH && prach_resources->init_msg1) { + if (UE_mode < PUSCH && prach_resources->init_msg1) { LOG_D(MAC, "nr_ue_get_rach, RA_active value: %d", mac->RA_active); @@ -470,7 +470,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, payload[offset + j] = 0; // mac_pdu[offset + j] = 0; } } - } else { // RACH is active + } else if (mac->RA_window_cnt != -1) { // RACH is active //////////////////////////////////////////////////////////////// /////* Random Access Response reception (5.1.4 TS 38.321) *///// @@ -481,7 +481,6 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // - handle beam failure recovery request // - handle DL assignment on PDCCH for RA-RNTI // - handle backoff and raResponseWindow params - // - disabled contention resolution as OAI NSA is contention-free based // LOG_D(MAC, "[MAC][UE %d][RAPROC] frame %d, subframe %d: RA Active, window cnt %d (RA_tx_frame %d, RA_tx_subframe %d)\n", // mod_id, frame, nr_tti_tx, mac->RA_window_cnt, mac->RA_tx_frame, mac->RA_tx_subframe); @@ -494,12 +493,13 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) { - // mac->ra_state = WAIT_CONTENTION_RESOLUTION; - LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR successfully received \n", mod_id, frame, nr_tti_tx); + mac->ra_state = WAIT_CONTENTION_RESOLUTION; + mac->RA_window_cnt = -1; + LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR successfully received \n", mod_id, frame, nr_tti_tx); } else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) { - LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception failed \n", mod_id, frame, nr_tti_tx); + LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception failed \n", mod_id, frame, nr_tti_tx); mac->ra_state = RA_UE_IDLE; mac->RA_PREAMBLE_TRANSMISSION_COUNTER++; @@ -578,7 +578,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, mac->RA_window_cnt--; - LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: subframe %d: RAR reception not successful, (RA window count %d) \n", + LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR reception not successful, (RA window count %d) \n", mod_id, frame, nr_tti_tx, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index a98a2b1211..e3d76c34c2 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -213,23 +213,23 @@ void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n"); } - if (frame == mac->msg2_rx_frame && slot == mac->msg2_rx_slot){ - sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12; - monitoringSymbolsWithinSlot = (css->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (css->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - rel15->rnti = mac->ra_rnti; - rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); - rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); // NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); - rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; - rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_RA, rel15->BWPSize); - for (int i = 0; i < sps; i++) + sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12; + monitoringSymbolsWithinSlot = (css->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (css->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = mac->ra_rnti; + rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); // NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; + rel15->dci_length = nr_dci_size(rel15->dci_format, NR_RNTI_RA, rel15->BWPSize); + + for (int i = 0; i < sps; i++){ if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) { rel15->coreset.StartSymbolIndex = i; break; } - fill_dci_search_candidates(css, rel15); - } else { - add_dci = 0; } + + fill_dci_search_candidates(css, rel15); + } else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION){ rel15->rnti = mac->t_crnti; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 5468a85f1c..7f3fe9b9bd 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -933,104 +933,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in return UE_CONNECTION_OK; } -// Notes: -// - Type1-PDCCH CSS configuration from ra-SearchSpace. -// - Msg2 is scheduled in the mixed slot or in the last dl slot if they are allowed by the Type 1 Common Search Space configuration -// todo: -// - if Type1-PDCCH CSS is not configured in RRC message (Coreset and SearchSpace), UE searches in Type 0 PDCCH CSS. -void nr_ue_msg2_scheduler(module_id_t mod_id, - uint16_t rach_frame, - uint16_t rach_slot, - uint16_t *msg2_frame, - uint16_t *msg2_slot){ - - uint8_t bwp_id = 1; - NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); - NR_ServingCellConfig_t *scd = mac->scd; - NR_ServingCellConfigCommon_t *scc = mac->scc; - NR_BWP_Downlink_t *bwp = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]; - NR_SearchSpace_t *ss; - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - uint8_t mu = *scc->ssbSubcarrierSpacing; - uint8_t response_window = scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric.ra_ResponseWindow; - uint8_t slot_window, slot_limit, frame_limit; - uint16_t start_next_period, monitoring_slot_period, monitoring_offset; - - // number of mixed slot or of last dl slot if there is no mixed slot - uint16_t last_dl_slot_period = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSlots; - uint16_t nr_dl_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofDownlinkSymbols; - uint16_t nr_ul_symbols = scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSymbols; - - // lenght of tdd period in slots - uint16_t tdd_period_slot = last_dl_slot_period + scc->tdd_UL_DL_ConfigurationCommon->pattern1.nrofUplinkSlots; - - AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH common SearchSpace list has 0 elements\n"); - - LOG_D(MAC, "Frame %d, Slot %d: Scheduling Msg2 reception \n", rach_frame, rach_slot); - - // Common searchspace list - for (int i = 0; i < commonSearchSpaceList->list.count; i++) { - ss = commonSearchSpaceList->list.array[i]; - if(ss->searchSpaceId == *bwp->bwp_Common->pdcch_ConfigCommon->choice.setup->ra_SearchSpace) - // retrieving ra pdcch monitoring period and offset - find_monitoring_periodicity_offset_common(ss, &monitoring_slot_period, &monitoring_offset); - } - - if (nr_dl_symbols == 0) - last_dl_slot_period--; - if ((nr_dl_symbols > 0) || (nr_ul_symbols > 0)) - tdd_period_slot++; - - // computing start of next period - start_next_period = (rach_slot - (rach_slot % tdd_period_slot) + tdd_period_slot) % nr_slots_per_frame[mu]; - *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot - *msg2_frame = (*msg2_slot > rach_slot) ? rach_frame : (rach_frame +1); - - switch(response_window){ - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1: - slot_window = 1; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2: - slot_window = 2; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4: - slot_window = 4; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8: - slot_window = 8; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10: - slot_window = 10; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20: - slot_window = 20; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40: - slot_window = 40; - break; - case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80: - slot_window = 80; - break; - default: - AssertFatal(1==0,"Invalid response window value %d\n",response_window); - } - AssertFatal(slot_window<=nr_slots_per_frame[mu], "Msg2 response window needs to be lower or equal to 10ms"); - - // slot and frame limit to transmit msg2 according to response window - slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu]; - frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1); - - // go to previous slot if the current scheduled slot is beyond the response window - // and if the slot is not among the PDCCH monitored ones (38.213 10.1) - while ((*msg2_slot > slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu] + *msg2_slot - monitoring_offset) % monitoring_slot_period != 0)) { - if((*msg2_slot % tdd_period_slot) > 0) - (*msg2_slot)--; - else - AssertFatal(1 == 0, "No available DL slot to schedule reception of msg2 has been found"); - } - LOG_D(MAC, "Scheduled Msg2 reception in Frame %d, Slot %d: \n", *msg2_frame, *msg2_slot); -} - // This function schedules the PRACH according to prach_ConfigurationIndex and TS 38.211, tables 6.3.3.2.x // It fills the PRACH PDU per each FD occasion. // PRACH formats 9, 10, 11 are corresponding to dual PRACH format configurations A1/B1, A2/B2, A3/B3. @@ -2906,10 +2808,11 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, nr dlsch_config_pdu_1_0->pucch_resource_id, dlsch_config_pdu_1_0->pdsch_to_harq_feedback_time_ind); - if (mac->ra_rnti == rnti) + if (mac->RA_window_cnt >= 0 && rnti == mac->ra_rnti){ dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_RA_DLSCH; - else + } else { dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DLSCH; + } // dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15.N_RB_BWP = n_RB_DLBWP; diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 43f43922a8..f6b65654a9 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -117,13 +117,6 @@ int nr_ue_ul_indication(nr_uplink_indication_t *ul_info){ if (is_nr_UL_slot(mac->scc, ul_info->slot_tx) && get_softmodem_params()->do_ra){ nr_ue_prach_scheduler(module_id, ul_info->frame_tx, ul_info->slot_tx); - if (mac->generate_nr_prach){ - //uint16_t monitoring_slot_period, monitoring_offset; - uint16_t rach_frame = mac->scheduled_response.ul_config->sfn; - uint16_t rx_rach_frame = (rach_frame + mac->RA_offset) % MAX_FRAME_NUMBER; // compensate 2 frames offset delay at gNB side - uint16_t rach_slot = mac->scheduled_response.ul_config->slot; - nr_ue_msg2_scheduler(module_id, rx_rach_frame, rach_slot, &mac->msg2_rx_frame, &mac->msg2_rx_slot); - } } switch(ret){ From 52e49fd8ec02e130a78b1750ba013546611191c5 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 2 Jul 2020 12:43:53 +0200 Subject: [PATCH 053/171] Fixed some warnings + cleanup - replaced nr_slot_t with int as it was barely used in the code (also is defined after an lte struct) - removed use of phy_frame_config_nr from the UE (another file was created in SCHED_NR_UE, still the gNB file is used in some tests file at UE side) --- cmake_targets/CMakeLists.txt | 2 +- executables/nr-ue.c | 4 +- openair1/SCHED_NR/phy_frame_config_nr.c | 73 +------------- openair1/SCHED_NR/phy_frame_config_nr.h | 6 +- openair1/SCHED_NR_UE/phy_frame_config_nr.h | 10 +- openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c | 99 +++++++++++++++++++ openair1/SIMULATION/NR_PHY/ulsim.c | 3 +- openair2/LAYER2/NR_MAC_UE/config_ue.c | 1 - openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 - openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c | 9 +- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 2 - 11 files changed, 122 insertions(+), 89 deletions(-) create mode 100644 openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 525c9eae56..bc912677e0 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1252,7 +1252,7 @@ set(SCHED_SRC_NR_UE ${OPENAIR1_DIR}/SCHED_NR_UE/phy_procedures_nr_ue.c ${OPENAIR1_DIR}/SCHED_NR/phy_procedures_nr_common.c ${OPENAIR1_DIR}/SCHED_NR_UE/fapi_nr_ue_l1.c - ${OPENAIR1_DIR}/SCHED_NR/phy_frame_config_nr.c + ${OPENAIR1_DIR}/SCHED_NR_UE/phy_frame_config_nr_ue.c ${OPENAIR1_DIR}/SCHED_NR_UE/harq_nr.c ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_uci_ue_nr.c ${OPENAIR1_DIR}/SCHED_NR_UE/pucch_power_control_ue_nr.c diff --git a/executables/nr-ue.c b/executables/nr-ue.c index 63c3172917..9482611c4a 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -35,9 +35,7 @@ #include "NR_MAC_UE/mac_proto.h" #include "RRC/NR_UE/rrc_proto.h" -//#ifndef NO_RAT_NR -#include "SCHED_NR/phy_frame_config_nr.h" -//#endif +#include "SCHED_NR_UE/phy_frame_config_nr.h" #include "SCHED_NR_UE/defs.h" #include "PHY/NR_UE_TRANSPORT/nr_transport_proto_ue.h" diff --git a/openair1/SCHED_NR/phy_frame_config_nr.c b/openair1/SCHED_NR/phy_frame_config_nr.c index 0ccb13fc7c..9d34f496b3 100644 --- a/openair1/SCHED_NR/phy_frame_config_nr.c +++ b/openair1/SCHED_NR/phy_frame_config_nr.c @@ -29,11 +29,9 @@ * ************************************************************************/ -#include "SCHED_NR_UE/defs.h" +#include "PHY/defs_nr_common.h" #include "PHY/defs_nr_UE.h" -#include "SCHED_NR_UE/phy_frame_config_nr.h" -#include "PHY/impl_defs_nr.h" -#include "PHY/impl_defs_top.h" +#include "SCHED_NR/phy_frame_config_nr.h" /******************************************************************* * @@ -369,73 +367,6 @@ int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti) } } -/******************************************************************* -* -* NAME : nr_ue_slot_select -* -* DESCRIPTION : function for the UE equivalent to nr_slot_select -* -*********************************************************************/ - -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { - /* for FFD all slot can be considered as an uplink */ - int mu = cfg->ssb_config.scs_common, check_slot = 0; - - if (cfg->cell_config.frame_duplex_type == FDD) { - return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT); - } - - if (nr_frame%2 == 0) { - for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) { - check_slot++; - } - } - - if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { - return (NR_UPLINK_SLOT); - } - - check_slot = 0; - - for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) { - check_slot++; - } - } - - if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { - return (NR_DOWNLINK_SLOT); - } else { - return (NR_MIXED_SLOT); - } - } else { - for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1< /************** DEFINE ********************************************/ #define TDD_CONFIG_NB_FRAMES (2) @@ -77,10 +76,9 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms); * @param frame_parms NR DL Frame parameters * @param nr_frame : frame number * @param nr_tti : slot number - @returns nr_slot_t : downlink or uplink */ + @returns int : downlink, uplink or mixed slot type*/ -nr_slot_t nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti); -int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti); +int nr_slot_select(nfapi_nr_config_request_scf_t *cfg, int nr_frame, int nr_tti); /** \brief This function frees tdd configuration for nr * @param frame_parms NR DL Frame parameters diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr.h b/openair1/SCHED_NR_UE/phy_frame_config_nr.h index a7e78397fe..3669239578 100644 --- a/openair1/SCHED_NR_UE/phy_frame_config_nr.h +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr.h @@ -62,10 +62,18 @@ int set_tdd_configuration_dedicated_nr(NR_DL_FRAME_PARMS *frame_parms); * @param frame_parms NR DL Frame parameters * @param nr_frame : frame number * @param nr_tti : slot number - @returns nr_slot_t : downlink or uplink */ + @returns int : downlink or uplink */ int slot_select_nr(NR_DL_FRAME_PARMS *frame_parms, int nr_frame, int nr_tti); +/** \brief This function checks nr UE slot direction : downlink or uplink + * @param cfg : FAPI Config Request + * @param nr_frame : frame number + * @param nr_tti : slot number + @returns int : downlink, uplink or mixed slot type */ + +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti); + /** \brief This function frees tdd configuration for nr * @param frame_parms NR DL Frame parameters @returns none */ diff --git a/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c new file mode 100644 index 0000000000..640ffb4ac3 --- /dev/null +++ b/openair1/SCHED_NR_UE/phy_frame_config_nr_ue.c @@ -0,0 +1,99 @@ +/* + * 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 + */ + +/*********************************************************************** +* +* FILENAME : phy_frame_configuration_nr_ue.c +* +* DESCRIPTION : functions related to FDD/TDD configuration for NR +* see TS 38.213 11.1 Slot configuration +* and TS 38.331 for RRC configuration +* +************************************************************************/ + +#include "PHY/defs_nr_UE.h" + +/******************************************************************* +* +* NAME : nr_ue_slot_select +* +* DESCRIPTION : function for the UE equivalent to nr_slot_select +* +*********************************************************************/ + +int nr_ue_slot_select(fapi_nr_config_request_t *cfg, int nr_frame, int nr_tti) { + /* for FFD all slot can be considered as an uplink */ + int mu = cfg->ssb_config.scs_common, check_slot = 0; + + if (cfg->cell_config.frame_duplex_type == FDD) { + return (NR_UPLINK_SLOT | NR_DOWNLINK_SLOT); + } + + if (nr_frame%2 == 0) { + for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 1) { + check_slot++; + } + } + + if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { + return (NR_UPLINK_SLOT); + } + + check_slot = 0; + + for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[nr_tti].max_num_of_symbol_per_slot_list[symbol_count].slot_config == 0) { + check_slot++; + } + } + + if(check_slot == NR_NUMBER_OF_SYMBOLS_PER_SLOT) { + return (NR_DOWNLINK_SLOT); + } else { + return (NR_MIXED_SLOT); + } + } else { + for(int symbol_count=0; symbol_counttdd_table.max_tdd_periodicity_list[((1<tdd_table.max_tdd_periodicity_list[((1<tx_request_body = (fapi_nr_tx_request_body_t *) malloc(sizeof(fapi_nr_tx_request_body_t)); ul_config.slot = slot; ul_config.number_pdus = 1; diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index f50c15df50..32af6f895d 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -34,7 +34,6 @@ #include "NR_MAC_UE/mac_proto.h" #include "NR_MAC-CellGroupConfig.h" #include "LAYER2/NR_MAC_COMMON/nr_mac_common.h" -#include "SCHED_NR/phy_frame_config_nr.h" int set_tdd_config_nr_ue(fapi_nr_config_request_t *cfg, int mu, diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 7f3fe9b9bd..3328a79a08 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -892,8 +892,6 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in scheduled_response.frame = rx_frame; scheduled_response.slot = rx_slot; - printf("DEGUG nr_ue_scheduler Scheduling FAPI_NR_UL_CONFIG_TYPE_PUSCH \n"); - scheduled_response.ul_config->slot = ul_info->slot_tx; scheduled_response.ul_config->number_pdus = 1; scheduled_response.ul_config->ul_config_list[0].pdu_type = FAPI_NR_UL_CONFIG_TYPE_PUSCH; diff --git a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c index 31a865f317..8d52db6747 100644 --- a/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c +++ b/openair2/LAYER2/NR_MAC_UE/rar_tools_nrUE.c @@ -107,9 +107,10 @@ uint16_t nr_ue_process_rar(module_id_t mod_id, uint8_t n_subPDUs = 0; // number of RAR payloads uint8_t n_subheaders = 0; // number of MAC RAR subheaders //uint8_t best_rx_rapid = -1; // the closest RAPID receive from all RARs - unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req; - uint16_t ta_command = 0, msg3_f_alloc, bwp_size; - int f_alloc, mask; + //unsigned char freq_hopping, msg3_t_alloc, mcs, tpc_command, csi_req; // WIP + //uint16_t ta_command = 0, msg3_f_alloc, bwp_size; // WIP + uint16_t ta_command = 0; + //int f_alloc, mask; // WIP AssertFatal(CC_id == 0, "RAR reception on secondary CCs is not supported yet\n"); @@ -143,6 +144,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id, // LOG_I(MAC, "[UE %d][RAPROC] Frame %d Received RAR (%02x|%02x.%02x.%02x.%02x.%02x.%02x) for preamble %d/%d\n", // mod_id, frameP, *(uint8_t *) rarh, rar[0], rar[1], rar[2], rar[3], rar[4], rar[5], rarh->RAPID, preamble_index); + #if 0 // TbD WIP Msg3 development ongoing if (ue_mac->RA_RAPID_found) { // TC-RNTI *t_crnti = rar->TCRNTI_2 + (rar->TCRNTI_1 << 8); @@ -200,6 +202,7 @@ uint16_t nr_ue_process_rar(module_id_t mod_id, ue_mac->t_crnti = 0; ta_command = (0xffff); } + #endif // move the selected RAR to the front of the RA_PDSCH buffer memcpy((void *) (selected_rar_buffer + 0), (void *) rarh, 1); diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index f6b65654a9..887725ef33 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -276,8 +276,6 @@ int nr_ue_dcireq(nr_dcireq_t *dcireq) { dl_config->slot=UE_mac->dl_config_request.slot; dl_config->number_pdus=0; - printf(" UE_mac->dl_config_request.slot %d VS dcireq->slot %d \n", UE_mac->dl_config_request.slot, dcireq->slot); - LOG_D(PHY, "Entering UE DCI configuration frame %d slot %d \n", dcireq->frame, dcireq->slot); ue_dci_configuration(UE_mac, dl_config, dcireq->frame, dcireq->slot); From 4761cbdc3d5feafd25e7292d10f2a0bfba0a5d7d Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 6 Jul 2020 10:48:41 +0200 Subject: [PATCH 054/171] Modifications wrt the NR LCIDs used for DTCH --- openair2/LAYER2/NR_MAC_COMMON/nr_mac.h | 4 ++-- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h index d8ba18e4bf..591c2448b8 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac.h @@ -320,8 +320,8 @@ typedef struct { #define UL_SCH_LCID_CCCH 0x00 #define UL_SCH_LCID_SRB1 0x01 #define UL_SCH_LCID_SRB2 0x02 -#define UL_SCH_LCID_DTCH 0x03 -#define UL_SCH_LCID_SRB3 0x04 +#define UL_SCH_LCID_SRB3 0x03 +#define UL_SCH_LCID_DTCH 0x04 #define UL_SCH_LCID_CCCH_MSG3 0x21 #define UL_SCH_LCID_RECOMMENDED_BITRATE_QUERY 0x35 #define UL_SCH_LCID_MULTI_ENTRY_PHR_4_OCT 0x36 diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 12b7f7bfcf..310a567492 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -585,7 +585,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, //at the upper layers if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test == 0){ - lcid = DTCH; + lcid = DL_SCH_LCID_DTCH; //for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { From 8d75cb61bc91c40bebca59e7c5dc8e3894ae54a7 Mon Sep 17 00:00:00 2001 From: hardy Date: Thu, 9 Jul 2020 14:37:18 +0200 Subject: [PATCH 055/171] to support OCP eNB build and test --- ci-scripts/main.py | 43 ++++-- ci-scripts/ran.py | 71 +++++---- .../enb_ocp_usrp210_band7_test_05mhz_tm1.xml | 146 ++++++++++++++++++ .../xml_files/enb_ocp_usrp210_build.xml | 38 +++++ cmake_targets/build_oai | 17 +- 5 files changed, 265 insertions(+), 50 deletions(-) create mode 100644 ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml create mode 100644 ci-scripts/xml_files/enb_ocp_usrp210_build.xml diff --git a/ci-scripts/main.py b/ci-scripts/main.py index ce37b0c8ba..7175be7c87 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3110,11 +3110,15 @@ def GetParametersFromXML(action): RAN.SeteNB_serverId(test.findtext('eNB_serverId')) if (RAN.GeteNB_serverId() is None): RAN.SeteNB_serverId('0') - CiTestObj.air_interface = test.findtext('air_interface') - if (CiTestObj.air_interface is None): - CiTestObj.air_interface = 'lte' - else: - CiTestObj.air_interface = CiTestObj.air_interface.lower() + + #local variable air_interface + air_interface = test.findtext('air_interface') + if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + CiTestObj.air_interface = 'lte-softmodem' + elif (air_interface.lower() in ['nr','lte']): + CiTestObj.air_interface = air_interface.lower() +'-softmodem' + else : + CiTestObj.air_interface = air_interface.lower() +'ocp-enb' RAN.Setair_interface(CiTestObj.air_interface) if action == 'Terminate_eNB': @@ -3124,11 +3128,15 @@ def GetParametersFromXML(action): RAN.SeteNB_serverId(test.findtext('eNB_serverId')) if (RAN.GeteNB_serverId() is None): RAN.SeteNB_serverId('0') - CiTestObj.air_interface = test.findtext('air_interface') - if (CiTestObj.air_interface is None): - CiTestObj.air_interface = 'lte' - else: - CiTestObj.air_interface = CiTestObj.air_interface.lower() + + #local variable air_interface + air_interface = test.findtext('air_interface') + if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + CiTestObj.air_interface = 'lte-softmodem' + elif (air_interface.lower() in ['nr','lte']): + CiTestObj.air_interface = air_interface.lower() +'-softmodem' + else : + CiTestObj.air_interface = air_interface.lower() +'ocp-enb' RAN.Setair_interface(CiTestObj.air_interface) if action == 'Attach_UE': @@ -3158,11 +3166,16 @@ def GetParametersFromXML(action): CiTestObj.UE_instance = test.findtext('UE_instance') if (CiTestObj.UE_instance is None): CiTestObj.UE_instance = '0' - CiTestObj.air_interface = test.findtext('air_interface') - if (CiTestObj.air_interface is None): - CiTestObj.air_interface = 'lte' - else: - CiTestObj.air_interface = CiTestObj.air_interface.lower() + + #local variable air_interface + air_interface = test.findtext('air_interface') + if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + CiTestObj.air_interface = 'lte-softmodem' + elif (air_interface.lower() in ['nr','lte']): + CiTestObj.air_interface = air_interface.lower() +'-softmodem' + else : + CiTestObj.air_interface = air_interface.lower() +'ocp-enb' + RAN.Setair_interface(CiTestObj.air_interface) if action == 'Terminate_OAI_UE': RAN.SeteNB_instance(test.findtext('UE_instance')) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 5f05a2ae4f..93ba859903 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -77,7 +77,7 @@ class RANManagement(): self.backgroundBuildTestId = ['', '', ''] self.Build_eNB_forced_workspace_cleanup = False self.Initialize_eNB_args = '' - self.air_interface = 'lte' + self.air_interface = '' #changed from 'lte' to '' may lead to side effects in main self.eNB_instance = '' self.eNB_serverId = '' self.eNBLogFiles = ['', '', ''] @@ -91,6 +91,8 @@ class RANManagement(): self.htmlObj = None self.epcObj = None + + #----------------------------------------------------------- # Setters and Getters on Public members #----------------------------------------------------------- @@ -254,12 +256,18 @@ class RANManagement(): sys.exit('Insufficient Parameter') mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) - # Check if we build an 5G-NR gNB or an LTE eNB - result = re.search('--gNB', self.Build_eNB_args) + + # Check if we build an 5G-NR gNB or an LTE eNB or an OCP eNB + result = re.search('--eNBocp', self.Build_eNB_args) if result is not None: - self.air_interface = 'nr' - else: - self.air_interface = 'lte' + self.air_interface='ocp-enb' + else: + result = re.search('--gNB', self.Build_eNB_args) + if result is not None: + self.air_interface = 'nr-softmodem' + else: + self.air_interface = 'lte-softmodem' + # Worakround for some servers, we need to erase completely the workspace if self.Build_eNB_forced_workspace_cleanup: mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) @@ -379,20 +387,19 @@ class RANManagement(): def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId): if self.htmlObj is not None: self.htmlObj.SettestCase_id(testcaseId) + mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 3) mySSH.command('ls ran_build/build', '\$', 3) mySSH.command('ls ran_build/build', '\$', 3) - if self.air_interface == 'nr': - nodeB_prefix = 'g' - else: - nodeB_prefix = 'e' - buildStatus = True - result = re.search(self.air_interface + '-softmodem', mySSH.getBefore()) + + #check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem, ocp-enb) + result = re.search(self.air_interface, mySSH.getBefore()) if result is None: - buildStatus = False + buildStatus = False #if not, build failed else: + buildStatus = True # Generating a BUILD INFO file mySSH.command('echo "SRC_BRANCH: ' + self.ranBranch + '" > ../LAST_BUILD_INFO.txt', '\$', 2) mySSH.command('echo "SRC_COMMIT: ' + self.ranCommitID + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) @@ -404,6 +411,8 @@ class RANManagement(): mySSH.command('echo "TGT_BRANCH: ' + self.ranTargetBranch + '" >> ../LAST_BUILD_INFO.txt', '\$', 2) else: mySSH.command('echo "MERGED_W_TGT_BRANCH: NO" >> ../LAST_BUILD_INFO.txt', '\$', 2) + + mySSH.command('mkdir -p build_log_' + testcaseId, '\$', 5) mySSH.command('mv log/* ' + 'build_log_' + testcaseId, '\$', 5) mySSH.command('mv compile_oai_enb.log ' + 'build_log_' + testcaseId, '\$', 5) @@ -426,12 +435,13 @@ class RANManagement(): else: mySSH.close() + #generate logging info depending on buildStatus and air interface if buildStatus: - logging.info('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Pass\u001B[0m') + logging.info('\u001B[1m Building OAI ' + self.air_interface + ' Pass\u001B[0m') if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) - else: - logging.error('\u001B[1m Building OAI ' + nodeB_prefix + 'NB Failed\u001B[0m') + self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) + else + logging.error('\u001B[1m Building OAI ' + self.air_interface + ' Failed\u001B[0m') if self.htmlObj is not None: self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'KO', CONST.ALL_PROCESSES_OK) self.htmlObj.CreateHtmlTabFooter(False) @@ -546,7 +556,7 @@ class RANManagement(): # Launch eNB with the modified config file mySSH.command('source oaienv', '\$', 5) mySSH.command('cd cmake_targets', '\$', 5) - mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) mySSH.command('hostnamectl','\$', 5) @@ -655,8 +665,8 @@ class RANManagement(): lPassWord = self.eNBPassword mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) - mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + '-softmodem | grep -v grep', '\$', 5) - result = re.search(self.air_interface + '-softmodem', mySSH.getBefore()) + mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + ' | grep -v grep', '\$', 5) + result = re.search(self.air_interface, mySSH.getBefore()) if result is None: logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') status_queue.put(CONST.ENB_PROCESS_FAILED) @@ -688,20 +698,20 @@ class RANManagement(): mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - if self.air_interface == 'lte': + if (self.air_interface == 'lte-softmodem') or (self.air_interface == 'ocp-enb'): nodeB_prefix = 'e' else: nodeB_prefix = 'g' - mySSH.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-softmodem', mySSH.getBefore()) + mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5) + result = re.search('(-softmodem|ocp)', mySSH.getBefore()) if result is not None: mySSH.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) - mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem || true', '\$', 5) + mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem .ocp-enb || true', '\$', 5) time.sleep(10) - mySSH.command('stdbuf -o0 ps -aux | grep --color=never softmodem | grep -v grep', '\$', 5) - result = re.search('-softmodem', mySSH.getBefore()) + mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5) + result = re.search('(-softmodem|ocp)', mySSH.getBefore()) if result is not None: - mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem || true', '\$', 5) + mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem .ocp-enb || true', '\$', 5) time.sleep(5) mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.close() @@ -890,8 +900,7 @@ class RANManagement(): if result is not None: rrcSetupComplete += 1 result = re.search('Generate LTE_RRCConnectionRelease|Generate RRCConnectionRelease', str(line)) - if result is not None: - rrcReleaseRequest += 1 + if result is not None: rrcReleaseRequest += 1 result = re.search('Generate LTE_RRCConnectionReconfiguration', str(line)) if result is not None: rrcReconfigRequest += 1 @@ -940,11 +949,11 @@ class RANManagement(): mbmsRequestMsg += 1 enb_log_file.close() logging.debug(' File analysis completed') - if self.air_interface == 'lte': + if (self.air_interface == 'lte-softmodem') or (self.air_interface == 'ocp-enb'): nodeB_prefix = 'e' else: nodeB_prefix = 'g' - if self.air_interface == 'nr': + if self.air_interface == 'nr-softmodem': if ulschReceiveOK > 0: statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml new file mode 100644 index 0000000000..5326973cc2 --- /dev/null +++ b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml @@ -0,0 +1,146 @@ + + + test-05-tm1 + Test-05MHz-TM1 + tasks + + 030201 + 040101 + 030101 040301 040501 040603 040604 040605 040606 040607 040641 040642 040643 040644 040401 040201 030201 + + + + + Initialize_eNB + Initialize eNB (FDD/Band7/5MHz) + -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf + ocp + + + + Terminate_eNB + Terminate eNB + ocp + + + + Initialize_UE + Initialize UE + + + + Terminate_UE + Terminate UE + + + + Attach_UE + Attach UE + + + + Detach_UE + Detach UE + + + + Ping + ping (5MHz - 20 sec) + -c 20 + 5 + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(balanced profile) + -u -b 15M -t 30 -i 1 + 50 + balanced + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(single-ue profile) + -u -b 15M -t 30 -i 1 + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/15Mbps/UDP)(30 sec)(unbalanced profile) + -u -b 15M -t 30 -i 1 + 50 + unbalanced + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm + 50 + single-ue + + + + Iperf + iperf (5MHz - DL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(balanced profile) + -u -b 9M -t 30 -i 1 -R + 50 + balanced + + + + Iperf + iperf (5MHz - UL/9Mbps/UDP)(30 sec)(single-ue profile) + -u -b 9M -t 30 -i 1 -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(single-ue profile) + -t 30 -i 1 -fm -R + 50 + single-ue + + + + Iperf + iperf (5MHz - UL/TCP)(30 sec)(balanced profile) + -t 30 -i 1 -fm -R + 50 + balanced + + + diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml new file mode 100644 index 0000000000..5729846818 --- /dev/null +++ b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml @@ -0,0 +1,38 @@ + + + build-tab + Build + wrench + + 010101 + + + + + Build_eNB + Build eNB OCP (USRP) + -I -w USRP -c --eNBocp --ninja + + + diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 91f33ea625..469c840b4d 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -96,7 +96,9 @@ Options enable cmake debugging messages --eNB Makes the LTE softmodem ---gNB +--eNBocp + Makes the OCP LTE softmodem +-gNB Makes the NR softmodem --nrUE Makes the NR UE softmodem @@ -237,7 +239,11 @@ function main() { eNB=1 echo_info "Will compile eNB" shift;; - --gNB) + --eNBocp) + eNBocp=1 + echo_info "Will compile OCP eNB" + shift;; + --gNB) gNB=1 NR="True" echo_info "Will compile gNB" @@ -443,7 +449,7 @@ function main() { ######################################################## # to be discussed - if [ "$eNB" = "1" -o "$gNB" = "1" ] ; then + if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$gNB" = "1" ] ; then if [ "$HW" = "None" -a "$TP" = "None" ] ; then echo_info "No local radio head and no transport protocol selected" fi @@ -574,7 +580,7 @@ function main() { config_libconfig_shlib=params_libconfig # first generate the CMakefile in the right directory - if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" ] ; then + if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HW" = "EXMIMO" ] ; then # softmodem compilation @@ -606,6 +612,9 @@ function main() { if [ "$eNB" = "1" ] ; then execlist="$execlist lte-softmodem" fi + if [ "$eNBocp" = "1" ] ; then + execlist="$execlist ocp-enb" + fi if [ "$gNB" = "1" ] ; then execlist="$execlist nr-softmodem" fi From 5caf5a4d1c2fad75f5414bafa2e9f0c7e14441f1 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 6 Jul 2020 12:34:14 +0200 Subject: [PATCH 056/171] dlsch ue n_dmrs_cdm_groups --- openair1/PHY/NR_TRANSPORT/nr_transport_proto.h | 3 ++- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 8 +++++++- openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h | 2 ++ openair1/SCHED_NR_UE/fapi_nr_ue_l1.c | 1 + openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 12 +++++++++--- openair1/SIMULATION/NR_PHY/dlschsim.c | 1 + 6 files changed, 22 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h index 0e10f2b678..e33532fa65 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h +++ b/openair1/PHY/NR_TRANSPORT/nr_transport_proto.h @@ -343,8 +343,9 @@ void nr_decode_pucch1(int32_t **rxdataF, uint8_t nr_bit); void nr_decode_pucch0(PHY_VARS_gNB *gNB, - int slot, + int slot, nfapi_nr_uci_pucch_pdu_format_0_1_t* uci_pdu, nfapi_nr_pucch_pdu_t* pucch_pdu); + #endif /*__NR_TRANSPORT__H__*/ diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 1a6006c3ba..3a84ea36cd 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -267,7 +267,13 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, uint8_t dmrs_Type = harq_process->dmrsConfigType; AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type); - uint8_t nb_re_dmrs = (dmrs_Type==1)?6:4; // should be changed based on MAC parameters + uint8_t nb_re_dmrs; + if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups; + } + else { + nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups; + } uint16_t dmrs_length = get_num_dmrs(harq_process->dlDmrsSymbPos); AssertFatal(dmrs_length == 1 || dmrs_length == 2,"Illegal dmrs_length %d\n",dmrs_length); diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h index 6b2d5e7255..6ffb6f21a3 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_transport_ue.h @@ -292,6 +292,8 @@ typedef struct { uint16_t dlDmrsSymbPos; /// DMRS Configuration Type uint8_t dmrsConfigType; + // Number of DMRS CDM groups with no data + uint8_t n_dmrs_cdm_groups; /// Starting Symbol number uint16_t start_symbol; /// Current subband PMI allocation diff --git a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c index f852ae4ae1..bdfa9dd517 100644 --- a/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c +++ b/openair1/SCHED_NR_UE/fapi_nr_ue_l1.c @@ -106,6 +106,7 @@ int8_t nr_ue_scheduled_response(nr_scheduled_response_t *scheduled_response){ dlsch0_harq->start_symbol = dlsch_config_pdu->start_symbol; dlsch0_harq->dlDmrsSymbPos = dlsch_config_pdu->dlDmrsSymbPos; dlsch0_harq->dmrsConfigType = dlsch_config_pdu->dmrsConfigType; + dlsch0_harq->n_dmrs_cdm_groups = dlsch_config_pdu->n_dmrs_cdm_groups; dlsch0_harq->mcs = dlsch_config_pdu->mcs; dlsch0_harq->rvidx = dlsch_config_pdu->rv; dlsch0->g_pucch = dlsch_config_pdu->accumulated_delta_PUCCH; diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index 7de941cfc8..c0390e9b96 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -3291,9 +3291,8 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, NR_UE_PDSCH *pdsch_vars; uint8_t is_cw0_active = 0; uint8_t is_cw1_active = 0; - uint8_t dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType; - uint8_t nb_re_dmrs = (dmrs_type==NFAPI_NR_DMRS_TYPE1)?6:4; // TODO: should changed my mac - uint16_t length_dmrs = 1; //cfg->pdsch_config.dmrs_max_length.value; + uint8_t dmrs_type, nb_re_dmrs; + uint16_t length_dmrs = 1; uint16_t nb_symb_sch = 9; nr_downlink_indication_t dl_indication; fapi_nr_rx_indication_t rx_ind; @@ -3318,6 +3317,13 @@ void nr_ue_dlsch_procedures(PHY_VARS_NR_UE *ue, is_cw0_active = dlsch0->harq_processes[harq_pid]->status; nb_symb_sch = dlsch0->harq_processes[harq_pid]->nb_symbols; start_symbol = dlsch0->harq_processes[harq_pid]->start_symbol; + dmrs_type = dlsch0->harq_processes[harq_pid]->dmrsConfigType; + if (dmrs_type==NFAPI_NR_DMRS_TYPE1) { + nb_re_dmrs = 6*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups; + } + else { + nb_re_dmrs = 4*dlsch0->harq_processes[harq_pid]->n_dmrs_cdm_groups; + } if(dlsch1) is_cw1_active = dlsch1->harq_processes[harq_pid]->status; diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index 9374050e58..f8cf413814 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -480,6 +480,7 @@ int main(int argc, char **argv) harq_process->R = rate; harq_process->dmrsConfigType = 1; harq_process->dlDmrsSymbPos = 4; + harq_process->n_dmrs_cdm_groups = 1; printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch); unsigned char *test_input; test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8); From e736b9410a1a1a78f10b9e7b5e6211216a8adf70 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 13 Jul 2020 11:36:51 +0200 Subject: [PATCH 057/171] Apply rx_offset in rfsimulator, too --- executables/nr-ue.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/executables/nr-ue.c b/executables/nr-ue.c index f867d59b86..cdcd014caa 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -575,12 +575,6 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { int computeSamplesShift(PHY_VARS_NR_UE *UE) { - if (IS_SOFTMODEM_RFSIM) { - LOG_D(PHY,"SET rx_offset %d \n",UE->rx_offset); - //UE->rx_offset_diff=0; - return 0; - } - // compute TO compensation that should be applied for this frame if ( UE->rx_offset < UE->frame_parms.samples_per_frame/2 && UE->rx_offset > 0 ) { From 91480dccce68f740308c54be0ad7ae9c6d1d8b74 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Mon, 13 Jul 2020 15:17:54 +0200 Subject: [PATCH 058/171] support for ocp enb build and test (unit test ok) --- ci-scripts/ran.py | 2 +- .../xml_files/enb_ocp_usrp210_build.xml | 2 +- ci-scripts/xml_files/fr1_multi_node_build.xml | 67 +++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 ci-scripts/xml_files/fr1_multi_node_build.xml diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 93ba859903..e09ce55634 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -440,7 +440,7 @@ class RANManagement(): logging.info('\u001B[1m Building OAI ' + self.air_interface + ' Pass\u001B[0m') if self.htmlObj is not None: self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) - else + else: logging.error('\u001B[1m Building OAI ' + self.air_interface + ' Failed\u001B[0m') if self.htmlObj is not None: self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'KO', CONST.ALL_PROCESSES_OK) diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml index 5729846818..8110c7f1b6 100644 --- a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml +++ b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml @@ -32,7 +32,7 @@ Build_eNB Build eNB OCP (USRP) - -I -w USRP -c --eNBocp --ninja + -w USRP -c --eNBocp diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml new file mode 100644 index 0000000000..b2c0daa74e --- /dev/null +++ b/ci-scripts/xml_files/fr1_multi_node_build.xml @@ -0,0 +1,67 @@ + + + build-tab + Build + wrench + + 010101 010102 + 000101 000102 + + + + + Build_eNB + Build eNB + -w USRP -c --eNB --ninja + 0 + 0 + True + + + + WaitEndBuild_eNB + Wait for end of Build eNB + -w USRP -c --eNB --ninja + 0 + 0 + + + + Build_eNB + Build gNB + -w USRP -c --gNB --ninja + 1 + 1 + True + + + + WaitEndBuild_eNB + Wait for end of Build gNB + -w USRP -c --gNB --ninja + 1 + 1 + + + From 2e5d0db742c53972f462c05fb594272a728b0bd8 Mon Sep 17 00:00:00 2001 From: hardy Date: Mon, 13 Jul 2020 16:45:32 +0200 Subject: [PATCH 059/171] removed getter/setter from RAM class --- ci-scripts/main.py | 276 ++++++++++++++++++++++----------------------- ci-scripts/ran.py | 4 +- 2 files changed, 141 insertions(+), 139 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 22e4c8ad72..f7feeb08d4 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -112,10 +112,10 @@ class OaiCiTest(): SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) result = re.search('--nrUE', self.Build_OAI_UE_args) if result is not None: - RAN.Setair_interface('nr') + RAN.air_interface='nr' ue_prefix = 'NR ' else: - RAN.Setair_interface('lte') + RAN.air_interface='lte' ue_prefix = '' result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) if result is not None: @@ -155,7 +155,7 @@ class OaiCiTest(): mismatch = True if not mismatch: SSH.close() - HTML.CreateHtmlTestRow(RAN.GetBuild_eNB_args(), 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(RAN.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) return SSH.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) @@ -181,7 +181,7 @@ class OaiCiTest(): SSH.command('ls ran_build/build', '\$', 3) SSH.command('ls ran_build/build', '\$', 3) buildStatus = True - result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore()) + result = re.search(RAN.air_interface + '-uesoftmodem', SSH.getBefore()) if result is None: buildStatus = False SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) @@ -215,12 +215,12 @@ class OaiCiTest(): SSH.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5) result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore()) if result is not None: - RAN.SetflexranCtrlInstalled(True) + RAN.flexranCtrlInstalled=True logging.debug('Flexran Controller is installed') SSH.close() def InitializeFlexranCtrl(self): - if RAN.GetflexranCtrlInstalled() == False: + if RAN.flexranCtrlInstalled == False: return if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': HELP.GenericHelp(CONST.Version) @@ -235,7 +235,7 @@ class OaiCiTest(): result = re.search('rt_controller -c ', SSH.getBefore()) if result is not None: logging.debug('\u001B[1m Initialize FlexRan Controller Completed\u001B[0m') - RAN.SetflexranCtrlStarted(True) + RAN.flexranCtrlStarted=True SSH.close() HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) @@ -306,7 +306,7 @@ class OaiCiTest(): if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - if RAN.Getair_interface() == 'lte': + if RAN.air_interface == 'lte': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: check_eNB = True @@ -335,13 +335,13 @@ class OaiCiTest(): # Initialize_OAI_UE_args usually start with -C and followed by the location in repository # in case of NR-UE, we may have rrc_config_path (Temporary?) modifiedUeOptions = str(self.Initialize_OAI_UE_args) - if RAN.Getair_interface() == 'nr': + if RAN.air_interface == 'nr': result = re.search('--rrc_config_path ', modifiedUeOptions) if result is not None: modifiedUeOptions = modifiedUeOptions.replace('rrc_config_path ', 'rrc_config_path ' + self.UESourceCodePath + '/') SSH.command('source oaienv', '\$', 5) SSH.command('cd cmake_targets/ran_build/build', '\$', 5) - if RAN.Getair_interface() == 'lte': + if RAN.air_interface == 'lte': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) # We may have to regenerate the .u* files if result is None: @@ -353,7 +353,7 @@ class OaiCiTest(): SSH.command('sed -e "s#93#92#" -e "s#8baf473f2f8fd09487cccbd7097c6862#fec86ba6eb707ed08905757b1bb44b8f#" -e "s#e734f8734007d6c5ce7a0508809e7e9c#C42449363BBAD02B66D16BC975D77CC1#" ../../../openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf > ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf .u*', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S ../../../targets/bin/conf2uedata -c ../../../openair3/NAS/TOOLS/ci-ue_eurecom_test_sfr.conf -o .', '\$', 5) - SSH.command('echo "ulimit -c unlimited && ./'+ RAN.Getair_interface() +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + SSH.command('echo "ulimit -c unlimited && ./'+ RAN.air_interface +'-uesoftmodem ' + modifiedUeOptions + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) self.UELogFile = 'ue_' + self.testCase_id + '.log' @@ -384,7 +384,7 @@ class OaiCiTest(): doLoop = False continue SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - if RAN.Getair_interface() == 'nr': + if RAN.air_interface == 'nr': result = re.search('Starting sync detection', SSH.getBefore()) else: result = re.search('got sync', SSH.getBefore()) @@ -409,7 +409,7 @@ class OaiCiTest(): # That is the case for LTE # In NR case, it's a positive message that will show if synchronization occurs doLoop = True - if RAN.Getair_interface() == 'nr': + if RAN.air_interface == 'nr': loopCounter = 10 else: # We are now checking if sync w/ eNB DOES NOT OCCUR @@ -418,7 +418,7 @@ class OaiCiTest(): while (doLoop): loopCounter = loopCounter - 1 if (loopCounter == 0): - if RAN.Getair_interface() == 'nr': + if RAN.air_interface == 'nr': # Here we do have great chances that UE did NOT cell-sync w/ gNB doLoop = False fullSyncStatus = False @@ -437,7 +437,7 @@ class OaiCiTest(): fullSyncStatus = True continue SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Frequency"', '\$', 4) - if RAN.Getair_interface() == 'nr': + if RAN.air_interface == 'nr': # Positive messaging --> result = re.search('Measured Carrier Frequency', SSH.getBefore()) if result is not None: @@ -466,12 +466,12 @@ class OaiCiTest(): if fullSyncStatus and gotSyncStatus: doInterfaceCheck = False - if RAN.Getair_interface() == 'lte': + if RAN.air_interface == 'lte': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: doInterfaceCheck = True # For the moment, only in explicit noS1 without kernel module (ie w/ tunnel interface) - if RAN.Getair_interface() == 'nr': + if RAN.air_interface == 'nr': result = re.search('--noS1 --nokrnmod 1', str(self.Initialize_OAI_UE_args)) if result is not None: doInterfaceCheck = True @@ -487,7 +487,7 @@ class OaiCiTest(): logging.debug(SSH.getBefore()) logging.error('\u001B[1m oaitun_ue1 interface is either NOT mounted or NOT configured\u001B[0m') tunnelInterfaceStatus = False - if RAN.GeteNBmbmsEnable(0): + if RAN.eNBmbmsEnables[0]: SSH.command('ifconfig oaitun_uem1', '\$', 4) result = re.search('inet addr', SSH.getBefore()) if result is not None: @@ -511,8 +511,8 @@ class OaiCiTest(): self.UEDevicesStatus = [] self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) else: - if RAN.Getair_interface() == 'lte': - if RAN.GeteNBmbmsEnable(0): + if RAN.air_interface == 'lte': + if RAN.eNBmbmsEnables[0]: HTML.SethtmlUEFailureMsg('oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured') else: HTML.SethtmlUEFailureMsg('oaitun_ue1 interface is either NOT mounted or NOT configured') @@ -887,7 +887,7 @@ class OaiCiTest(): self.UEDevicesStatus[cnt] = CONST.UE_STATUS_ATTACHED cnt += 1 HTML.CreateHtmlTestRowQueue('N/A', 'OK', len(self.UEDevices), html_queue) - result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args())) + result = re.search('T_stdout', str(RAN.Initialize_eNB_args)) if result is not None: logging.debug('Waiting 5 seconds to fill up record file') time.sleep(5) @@ -933,7 +933,7 @@ class OaiCiTest(): for job in multi_jobs: job.join() HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) - result = re.search('T_stdout', str(RAN.GetInitialize_eNB_args())) + result = re.search('T_stdout', str(RAN.Initialize_eNB_args)) if result is not None: logging.debug('Waiting 5 seconds to fill up record file') time.sleep(5) @@ -1199,7 +1199,7 @@ class OaiCiTest(): i += 1 for job in multi_jobs: job.join() - if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted(): + if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) SSH.command('cd /opt/flexran_rtc', '\$', 5) SSH.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5) @@ -1409,7 +1409,7 @@ class OaiCiTest(): return ping_from_eNB = re.search('oaitun_enb1', str(self.ping_args)) if ping_from_eNB is not None: - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '': + if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') else: @@ -1418,8 +1418,8 @@ class OaiCiTest(): sys.exit('Insufficient Parameter') try: if ping_from_eNB is not None: - SSH.open(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword()) - SSH.command('cd ' + RAN.GeteNBSourceCodePath() + '/cmake_targets/', '\$', 5) + SSH.open(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword) + SSH.command('cd ' + RAN.eNBSourceCodePath + '/cmake_targets/', '\$', 5) else: SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/', '\$', 5) @@ -1483,7 +1483,7 @@ class OaiCiTest(): # copying on the EPC server for logCollection if ping_from_eNB is not None: - copyin_res = SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') + copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') else: copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') if (copyin_res == 0): @@ -1492,7 +1492,7 @@ class OaiCiTest(): os.kill(os.getppid(),signal.SIGUSR1) def Ping(self): - result = re.search('noS1', str(RAN.GetInitialize_eNB_args())) + result = re.search('noS1', str(RAN.Initialize_eNB_args)) if result is not None: self.PingNoS1() return @@ -2123,7 +2123,7 @@ class OaiCiTest(): os.kill(os.getppid(),signal.SIGUSR1) def IperfNoS1(self): - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': + if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') check_eNB = True @@ -2135,9 +2135,9 @@ class OaiCiTest(): return server_on_enb = re.search('-R', str(self.iperf_args)) if server_on_enb is not None: - iServerIPAddr = RAN.GeteNBIPAddress() - iServerUser = RAN.GeteNBUserName() - iServerPasswd = RAN.GeteNBPassword() + iServerIPAddr = RAN.eNBIPAddress + iServerUser = RAN.eNBUserName + iServerPasswd = RAN.eNBPassword iClientIPAddr = self.UEIPAddress iClientUser = self.UEUserName iClientPasswd = self.UEPassword @@ -2145,9 +2145,9 @@ class OaiCiTest(): iServerIPAddr = self.UEIPAddress iServerUser = self.UEUserName iServerPasswd = self.UEPassword - iClientIPAddr = RAN.GeteNBIPAddress() - iClientUser = RAN.GeteNBUserName() - iClientPasswd = RAN.GeteNBPassword() + iClientIPAddr = RAN.eNBIPAddress + iClientUser = RAN.eNBUserName + iClientPasswd = RAN.eNBPassword if self.iperf_options != 'sink': # Starting the iperf server SSH.open(iServerIPAddr, iServerUser, iServerPasswd) @@ -2232,7 +2232,7 @@ class OaiCiTest(): self.AutoTerminateUEandeNB() def Iperf(self): - result = re.search('noS1', str(RAN.GetInitialize_eNB_args())) + result = re.search('noS1', str(RAN.Initialize_eNB_args)) if result is not None: self.IperfNoS1() return @@ -2313,7 +2313,7 @@ class OaiCiTest(): status_queue = SimpleQueue() # in noS1 config, no need to check status from EPC # in gNB also currently no need to check - result = re.search('noS1|band78', str(RAN.GetInitialize_eNB_args())) + result = re.search('noS1|band78', str(RAN.Initialize_eNB_args)) if result is None: p = Process(target = EPC.CheckHSSProcess, args = (status_queue,)) p.daemon = True @@ -2352,14 +2352,14 @@ class OaiCiTest(): if (status < 0): result = status if result == CONST.ENB_PROCESS_FAILED: - fileCheck = re.search('enb_', str(RAN.GeteNBLogFile(0))) + fileCheck = re.search('enb_', str(RAN.eNBLogFiles[0])) if fileCheck is not None: - SSH.copyin(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath() + '/cmake_targets/' + RAN.GeteNBLogFile(0), '.') - logStatus = RAN.AnalyzeLogFile_eNB(RAN.GeteNBLogFile[0]) + SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/' + RAN.eNBLogFiles[0], '.') + logStatus = RAN.AnalyzeLogFile_eNB(RAN.eNBLogFiles[0]) if logStatus < 0: result = logStatus - RAN.SeteNBLogFile('', 0) - if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted(): + RAN.eNBLogFiles[0]='' + if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: self.TerminateFlexranCtrl() return result @@ -2394,8 +2394,8 @@ class OaiCiTest(): def CheckOAIUEProcess(self, status_queue): try: SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + RAN.Getair_interface() + '-uesoftmodem | grep -v grep', '\$', 5) - result = re.search(RAN.Getair_interface() + '-uesoftmodem', SSH.getBefore()) + SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + RAN.air_interface + '-uesoftmodem | grep -v grep', '\$', 5) + result = re.search(RAN.air_interface + '-uesoftmodem', SSH.getBefore()) if result is None: logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') status_queue.put(CONST.OAI_UE_PROCESS_FAILED) @@ -2494,7 +2494,7 @@ class OaiCiTest(): result = re.search('No cell synchronization found, abandoning', str(line)) if result is not None: no_cell_sync_found = True - if RAN.GeteNBmbmsEnable(0): + if RAN.eNBmbmsEnables[0]: result = re.search('TRIED TO PUSH MBMS DATA', str(line)) if result is not None: mbms_messages += 1 @@ -2620,7 +2620,7 @@ class OaiCiTest(): statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') - if RAN.GeteNBmbmsEnable(0): + if RAN.eNBmbmsEnables[0]: if mbms_messages > 0: statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') @@ -2660,7 +2660,7 @@ class OaiCiTest(): def TerminateFlexranCtrl(self): - if RAN.GetflexranCtrlInstalled() == False or RAN.GetflexranCtrlStarted() == False: + if RAN.flexranCtrlInstalled == False or RAN.flexranCtrlStarted == False: return if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': HELP.GenericHelp(CONST.Version) @@ -2671,7 +2671,7 @@ class OaiCiTest(): SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) time.sleep(1) SSH.close() - RAN.SetflexranCtrlStarted(False) + RAN.flexranCtrlStarted=False HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) def TerminateUE_common(self, device_id, idx): @@ -2752,7 +2752,7 @@ class OaiCiTest(): logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') HTML.SethtmlUEFailureMsg('' + ueAction + ' Failed\n' + HTML.GethtmlUEFailureMsg()) HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') - if RAN.Getair_interface() == 'lte': + if RAN.air_interface == 'lte': # In case of sniffing on commercial eNBs we have random results # Not an error then if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): @@ -2785,22 +2785,22 @@ class OaiCiTest(): HTML.Setdesc('Automatic Termination of OAI-UE') self.ShowTestID() self.TerminateOAIUE() - if (RAN.GetInitialize_eNB_args() != ''): + if (RAN.Initialize_eNB_args != ''): self.testCase_id = 'AUTO-KILL-eNB' HTML.SettestCase_id(self.testCase_id) self.desc = 'Automatic Termination of eNB' HTML.Setdesc('Automatic Termination of eNB') self.ShowTestID() - RAN.SeteNB_instance('0') + RAN.eNB_instance='0' RAN.TerminateeNB() - if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted(): + if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: self.testCase_id = 'AUTO-KILL-flexran-ctl' HTML.SettestCase_id(self.testCase_id) self.desc = 'Automatic Termination of FlexRan CTL' HTML.Setdesc('Automatic Termination of FlexRan CTL') self.ShowTestID() self.TerminateFlexranCtrl() - RAN.SetprematureExit(True) + RAN.prematureExit=True def IdleSleep(self): time.sleep(self.idle_sleep_time) @@ -2856,7 +2856,7 @@ class OaiCiTest(): logging.debug(msg) fullMessage += msg + '\n' if self.x2_ho_options == 'network': - if RAN.GetflexranCtrlInstalled() and RAN.GetflexranCtrlStarted(): + if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: self.x2ENBBsIds = [] self.x2ENBConnectedUEs = [] self.x2ENBBsIds.append([]) @@ -2917,11 +2917,11 @@ class OaiCiTest(): HTML.CreateHtmlTestRow('Cannot perform requested X2 Handover', 'KO', CONST.ALL_PROCESSES_OK) def LogCollectBuild(self): - if (RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != ''): - IPAddress = RAN.GeteNBIPAddress() - UserName = RAN.GeteNBUserName() - Password = RAN.GeteNBPassword() - SourceCodePath = RAN.GeteNBSourceCodePath() + if (RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != ''): + IPAddress = RAN.eNBIPAddress + UserName = RAN.eNBUserName + Password = RAN.eNBPassword + SourceCodePath = RAN.eNBSourceCodePath elif (self.UEIPAddress != '' and self.UEUserName != '' and self.UEPassword != ''): IPAddress = self.UEIPAddress UserName = self.UEUserName @@ -2963,7 +2963,7 @@ class OaiCiTest(): SSH.close() def RetrieveSystemVersion(self, machine): - if RAN.GeteNBIPAddress() == 'none' or self.UEIPAddress == 'none': + if RAN.eNBIPAddress == 'none' or self.UEIPAddress == 'none': HTML.SetOsVersion('Ubuntu 16.04.5 LTS', 0) HTML.SetKernelVersion('4.15.0-45-generic', 0) HTML.SetUhdVersion('3.13.0.1-0', 0) @@ -2973,10 +2973,10 @@ class OaiCiTest(): HTML.SetCpuMHz('2399.996 MHz', 0) return 0 if machine == 'eNB': - if RAN.GeteNBIPAddress() != '' and RAN.GeteNBUserName() != '' and RAN.GeteNBPassword() != '': - IPAddress = RAN.GeteNBIPAddress() - UserName = RAN.GeteNBUserName() - Password = RAN.GeteNBPassword() + if RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != '': + IPAddress = RAN.eNBIPAddress + UserName = RAN.eNBUserName + Password = RAN.eNBPassword idx = 0 else: return -1 @@ -3070,47 +3070,47 @@ def CheckClassValidity(action,id): def GetParametersFromXML(action): if action == 'Build_eNB': - RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args')) + RAN.Build_eNB_args=test.findtext('Build_eNB_args') forced_workspace_cleanup = test.findtext('forced_workspace_cleanup') if (forced_workspace_cleanup is None): - RAN.SetBuild_eNB_forced_workspace_cleanup(False) + RAN.Build_eNB_forced_workspace_cleanup=False else: if re.match('true', forced_workspace_cleanup, re.IGNORECASE): - RAN.SetBuild_eNB_forced_workspace_cleanup(True) + RAN.Build_eNB_forced_workspace_cleanup=True else: - RAN.SetBuild_eNB_forced_workspace_cleanup(False) - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') + RAN.Build_eNB_forced_workspace_cleanup=False + RAN.eNB_instance=test.findtext('eNB_instance') + if (RAN.eNB_instance is None): + RAN.eNB_instance='0' + RAN.eNB_serverId=test.findtext('eNB_serverId') + if (RAN.eNB_serverId is None): + RAN.eNB_serverId='0' xmlBgBuildField = test.findtext('backgroundBuild') if (xmlBgBuildField is None): - RAN.SetbackgroundBuild(False) + RAN.backgroundBuild=False else: if re.match('true', xmlBgBuildField, re.IGNORECASE): - RAN.SetbackgroundBuild(True) + RAN.backgroundBuild=True else: - RAN.SetbackgroundBuild(False) + RAN.backgroundBuild=False if action == 'WaitEndBuild_eNB': - RAN.SetBuild_eNB_args(test.findtext('Build_eNB_args')) - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') + RAN.Build_eNB_args=test.findtext('Build_eNB_args') + RAN.eNB_instance=test.findtext('eNB_instance') + if (RAN.eNB_instance is None): + RAN.eNB_instance='0' + RAN.eNB_serverId=test.findtext('eNB_serverId') + if (RAN.eNB_serverId is None): + RAN.eNB_serverId='0' if action == 'Initialize_eNB': - RAN.SetInitialize_eNB_args(test.findtext('Initialize_eNB_args')) - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') + RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args') + RAN.eNB_instance=test.findtext('eNB_instance') + if (RAN.eNB_instance is None): + RAN.eNB_instance='0' + RAN.eNB_serverId=test.findtext('eNB_serverId') + if (RAN.eNB_serverId is None): + RAN.eNB_serverId='0' #local variable air_interface air_interface = test.findtext('air_interface') @@ -3120,15 +3120,15 @@ def GetParametersFromXML(action): CiTestObj.air_interface = air_interface.lower() +'-softmodem' else : CiTestObj.air_interface = air_interface.lower() +'ocp-enb' - RAN.Setair_interface(CiTestObj.air_interface) + RAN.air_interface(CiTestObj.air_interface) if action == 'Terminate_eNB': - RAN.SeteNB_instance(test.findtext('eNB_instance')) - if (RAN.GeteNB_instance() is None): - RAN.SeteNB_instance('0') - RAN.SeteNB_serverId(test.findtext('eNB_serverId')) - if (RAN.GeteNB_serverId() is None): - RAN.SeteNB_serverId('0') + RAN.eNB_instance=test.findtext('eNB_instance') + if (RAN.eNB_instance is None): + RAN.eNB_instance='0' + RAN.eNB_serverId=test.findtext('eNB_serverId') + if (RAN.eNB_serverId is None): + RAN.eNB_serverId='0' #local variable air_interface air_interface = test.findtext('air_interface') @@ -3138,7 +3138,7 @@ def GetParametersFromXML(action): CiTestObj.air_interface = air_interface.lower() +'-softmodem' else : CiTestObj.air_interface = air_interface.lower() +'ocp-enb' - RAN.Setair_interface(CiTestObj.air_interface) + RAN.air_interface=CiTestObj.air_interface if action == 'Attach_UE': nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach') @@ -3176,10 +3176,10 @@ def GetParametersFromXML(action): CiTestObj.air_interface = air_interface.lower() +'-softmodem' else : CiTestObj.air_interface = air_interface.lower() +'ocp-enb' - RAN.Setair_interface(CiTestObj.air_interface) + RAN.air_interface=CiTestObj.air_interface if action == 'Terminate_OAI_UE': - RAN.SeteNB_instance(test.findtext('UE_instance')) + RAN.eNB_instance=test.findtext('UE_instance') if (CiTestObj.UE_instance is None): CiTestObj.UE_instance = '0' @@ -3268,8 +3268,8 @@ RAN = ran.RANManagement() HTML = html.HTMLManagement() EPC.SetHtmlObj(HTML) -RAN.SetHtmlObj(HTML) -RAN.SetEpcObj(EPC) +RAN.HtmlObj=HTML +RAN.EpcObj=EPC import cls_physim #class PhySim for physical simulators build and test ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build @@ -3293,7 +3293,7 @@ while len(argvs) > 1: else: matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) CiTestObj.ranRepository = matchReg.group(1) - RAN.SetranRepository(matchReg.group(1)) + RAN.ranRepository=matchReg.group(1) HTML.SetranRepository(matchReg.group(1)) ldpc.ranRepository=matchReg.group(1) elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): @@ -3305,7 +3305,7 @@ while len(argvs) > 1: ldpc.ranAllowMerge=matchReg.group(1) if ((doMerge == 'true') or (doMerge == 'True')): CiTestObj.ranAllowMerge = True - RAN.SetranAllowMerge(True) + RAN.ranAllowMerge=True HTML.SetranAllowMerge(True) elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): @@ -3313,7 +3313,7 @@ while len(argvs) > 1: else: matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) CiTestObj.ranBranch = matchReg.group(1) - RAN.SetranBranch(matchReg.group(1)) + RAN.ranBranch=matchReg.group(1) HTML.SetranBranch(matchReg.group(1)) ldpc.ranBranch=matchReg.group(1) elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): @@ -3322,7 +3322,7 @@ while len(argvs) > 1: else: matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) CiTestObj.ranCommitID = matchReg.group(1) - RAN.SetranCommitID(matchReg.group(1)) + RAN.ranCommitID=matchReg.group(1) HTML.SetranCommitID(matchReg.group(1)) ldpc.ranCommitID=matchReg.group(1) elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): @@ -3331,53 +3331,53 @@ while len(argvs) > 1: else: matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) CiTestObj.ranTargetBranch = matchReg.group(1) - RAN.SetranTargetBranch(matchReg.group(1)) + RAN.ranTargetBranch=matchReg.group(1) HTML.SetranTargetBranch(matchReg.group(1)) ldpc.ranTargetBranch=matchReg.group(1) elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBIPAddress(matchReg.group(1)) + RAN.eNBIPAddress=matchReg.group(1) ldpc.eNBIpAddr=matchReg.group(1) elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1IPAddress(matchReg.group(1)) + RAN.eNB1IPAddress=matchReg.group(1) elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2IPAddress(matchReg.group(1)) + RAN.eNB2IPAddress=matchReg.group(1) elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBUserName(matchReg.group(1)) + RAN.eNBUserName=matchReg.group(1) ldpc.eNBUserName=matchReg.group(1) elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1UserName(matchReg.group(1)) + RAN.eNB1UserName=matchReg.group(1) elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2UserName(matchReg.group(1)) + RAN.eNB2UserName=matchReg.group(1) elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBPassword(matchReg.group(1)) + RAN.eNBPassword=matchReg.group(1) ldpc.eNBPassWord=matchReg.group(1) elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1Password(matchReg.group(1)) + RAN.eNB1Password=matchReg.group(1) elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2Password(matchReg.group(1)) + RAN.eNB2Password=matchReg.group(1) elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNBSourceCodePath(matchReg.group(1)) + RAN.eNBSourceCodePath=matchReg.group(1) ldpc.eNBSourceCodePath=matchReg.group(1) elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB1SourceCodePath(matchReg.group(1)) + RAN.eNB1SourceCodePath=matchReg.group(1) elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.SeteNB2SourceCodePath(matchReg.group(1)) + RAN.eNB2SourceCodePath=matchReg.group(1) elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) EPC.SetIPAddress(matchReg.group(1)) @@ -3444,12 +3444,12 @@ while len(argvs) > 1: sys.exit('Invalid Parameter: ' + myArgv) if re.match('^TerminateeNB$', mode, re.IGNORECASE): - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '': + if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - RAN.SeteNB_serverId('0') - RAN.SeteNB_instance('0') - RAN.SeteNBSourceCodePath('/tmp/') + RAN.eNB_serverId='0' + RAN.eNB_instance='0' + RAN.eNBSourceCodePath='/tmp/' RAN.TerminateeNB() elif re.match('^TerminateUE$', mode, re.IGNORECASE): if (CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == ''): @@ -3479,12 +3479,12 @@ elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') EPC.TerminateSPGW() elif re.match('^LogCollectBuild$', mode, re.IGNORECASE): - if (RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''): + if (RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '') and (CiTestObj.UEIPAddress == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == ''): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') CiTestObj.LogCollectBuild() elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '': + if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') RAN.LogCollecteNB() @@ -3559,14 +3559,14 @@ elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): HTML.CreateHtmlFooter(CiTestObj.finalStatus) elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re.IGNORECASE): if re.match('^TesteNB$', mode, re.IGNORECASE): - if RAN.GeteNBIPAddress() == '' or RAN.GetranRepository() == '' or RAN.GetranBranch() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '' or EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': + if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '' or EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': HELP.GenericHelp(CONST.Version) if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or EPC.GetType() == '': HELP.EPCSrvHelp(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath(), EPC.GetType()) - if RAN.GetranRepository() == '': - HELP.GitSrvHelp(RAN.GetranRepository(), RAN.GetranBranch(), RAN.GetranCommitID(), RAN.GetranAllowMerge(), RAN.GetranTargetBranch()) - if RAN.GeteNBIPAddress() == '' or RAN.GeteNBUserName() == '' or RAN.GeteNBPassword() == '' or RAN.GeteNBSourceCodePath() == '': - HELP.eNBSrvHelp(RAN.GeteNBIPAddress(), RAN.GeteNBUserName(), RAN.GeteNBPassword(), RAN.GeteNBSourceCodePath()) + if RAN.ranRepository == '': + HELP.GitSrvHelp(RAN.ranRepository, RAN.ranBranch, RAN.ranCommitID, RAN.ranAllowMerge, RAN.ranTargetBranch) + if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '': + HELP.eNBSrvHelp(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath) sys.exit('Insufficient Parameter') if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'): @@ -3644,18 +3644,18 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re HTML.CreateHtmlTabHeader() CiTestObj.FailReportCnt = 0 - RAN.SetprematureExit(True) + RAN.prematureExit=True HTML.SetstartTime(int(round(time.time() * 1000))) - while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.GetprematureExit(): - RAN.SetprematureExit(False) + while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.prematureExit: + RAN.prematureExit=False # At every iteratin of the retry loop, a separator will be added # pass CiTestObj.FailReportCnt as parameter of HTML.CreateHtmlRetrySeparator HTML.CreateHtmlRetrySeparator(CiTestObj.FailReportCnt) for test_case_id in todo_tests: - if RAN.GetprematureExit(): + if RAN.prematureExit: break for test in all_tests: - if RAN.GetprematureExit(): + if RAN.prematureExit: break id = test.get('id') if test_case_id != id: @@ -3681,7 +3681,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re elif action == 'Initialize_eNB': check_eNB = False check_OAI_UE = False - RAN.SetpStatus(CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE)) + RAN.pStatus=CiTestObj.CheckProcessExist(check_eNB, check_OAI_UE) RAN.InitializeeNB() elif action == 'Terminate_eNB': @@ -3750,7 +3750,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re else: sys.exit('Invalid action') CiTestObj.FailReportCnt += 1 - if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.GetprematureExit(): + if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.prematureExit: logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)') HTML.CreateHtmlTabFooter(False) sys.exit('Failed Scenario') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index e09ce55634..32f21fe2f7 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -92,7 +92,7 @@ class RANManagement(): self.epcObj = None - +""" #----------------------------------------------------------- # Setters and Getters on Public members #----------------------------------------------------------- @@ -228,6 +228,8 @@ class RANManagement(): def GetprematureExit(self): return self.prematureExit +""" + #----------------------------------------------------------- # RAN management functions #----------------------------------------------------------- From 68391d72439e5bb72ecfde082bbe60a99183a430 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 16 Jul 2020 17:55:52 +0200 Subject: [PATCH 060/171] Bugfix in RA window computation --- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 07ebb5e373..89e3f7cc18 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -62,9 +62,8 @@ #include "NR_MAC_COMMON/nr_mac.h" #include "LAYER2/NR_MAC_UE/mac_proto.h" -extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9]; extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; -extern const uint16_t nr_slots_per_frame[5]; +extern const uint8_t nr_slots_per_frame[5]; //extern uint8_t nfapi_mode; @@ -616,28 +615,28 @@ void nr_get_RA_window(NR_UE_MAC_INST_t *mac){ mac->RA_window_cnt = mac->RA_offset*nr_slots_per_frame[mu]; // taking into account the 2 frames gap introduced by OAI gNB switch (ra_ResponseWindow) { - case 0: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl1: mac->RA_window_cnt += 1; break; - case 1: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl2: mac->RA_window_cnt += 2; break; - case 2: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl4: mac->RA_window_cnt += 4; break; - case 3: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl8: mac->RA_window_cnt += 8; break; - case 4: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl10: mac->RA_window_cnt += 10; break; - case 5: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl20: mac->RA_window_cnt += 20; break; - case 6: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl40: mac->RA_window_cnt += 40; break; - case 7: + case NR_RACH_ConfigGeneric__ra_ResponseWindow_sl80: mac->RA_window_cnt += 80; break; } From fe724b555dbbb01baa46f1746243e8217f2daf52 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 16 Jul 2020 18:03:22 +0200 Subject: [PATCH 061/171] Cleanup RA procedure --- openair1/PHY/NR_TRANSPORT/nr_prach.c | 1 - openair1/PHY/NR_UE_TRANSPORT/nr_prach.c | 33 ++++++++----------- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c | 17 +++++----- 3 files changed, 21 insertions(+), 30 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 2640a86240..7333905ee4 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -37,7 +37,6 @@ extern uint16_t prach_root_sequence_map_0_3[838]; extern uint16_t prach_root_sequence_map_abc[138]; extern uint16_t nr_du[838]; -extern int16_t nr_ru[2*839]; extern const char *prachfmt[9]; void init_prach_list(PHY_VARS_gNB *gNB) { diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c index 79c542cd61..e4cab0b9a6 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_prach.c @@ -44,18 +44,8 @@ //#define NR_PRACH_DEBUG 1 -extern uint16_t NCS_unrestricted_delta_f_RA_125[16]; -extern uint16_t NCS_restricted_TypeA_delta_f_RA_125[15]; -extern uint16_t NCS_restricted_TypeB_delta_f_RA_125[13]; -extern uint16_t NCS_unrestricted_delta_f_RA_5[16]; -extern uint16_t NCS_restricted_TypeA_delta_f_RA_5[16]; -extern uint16_t NCS_restricted_TypeB_delta_f_RA_5[14]; -extern uint16_t NCS_unrestricted_delta_f_RA_15[16]; extern uint16_t prach_root_sequence_map_0_3[838]; extern uint16_t prach_root_sequence_map_abc[138]; -extern int64_t table_6_3_3_2_2_prachConfig_Index [256][9]; -extern int64_t table_6_3_3_2_3_prachConfig_Index [256][9]; -extern int64_t table_6_3_3_2_4_prachConfig_Index [256][10]; extern uint16_t nr_du[838]; extern int16_t nr_ru[2*839]; extern const char *prachfmt[9]; @@ -118,7 +108,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ else samp_count = (slot%(fp->slots_per_subframe/2)) ? fp->samples_per_slotN0 : fp->samples_per_slot0; - #if defined (OAI_USRP) + #ifdef OAI_USRP prach_start = (ue->rx_offset + slot*samp_count - ue->hw_timing_advance - ue->N_TA_offset); #else //normal case (simulation) prach_start = slot*samp_count - ue->N_TA_offset; @@ -208,14 +198,17 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ // now generate PRACH signal #ifdef NR_PRACH_DEBUG if (NCS>0) - LOG_I(PHY, "PRACH [UE %d] generate PRACH for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d\n", Mod_id, - rootSequenceIndex, - preamble_index, - prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id], + LOG_I(PHY, "PRACH [UE %d] generate PRACH in slot %d for RootSeqIndex %d, Preamble Index %d, PRACH Format %s, NCS %d (N_ZC %d): Preamble_offset %d, Preamble_shift %d msg1 frequency start %d\n", + Mod_id, + slot, + rootSequenceIndex, + preamble_index, + prach_sequence_length == 0 ? prachfmt03[prach_fmt_id] : prachfmt[prach_fmt_id], NCS, N_ZC, preamble_offset, - preamble_shift); + preamble_shift, + n_ra_prb); #endif // nsymb = (frame_parms->Ncp==0) ? 14:12; @@ -383,8 +376,6 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ } else { - //LOG_D(PHY, "PRACH [UE %d] in slot %d, format %d, msg1 frequency start %d startSymbol %d \n", Mod_id, slot, prachfmt[prach_fmt_id], n_ra_prb, prachStartSymbol); - switch (prach_fmt_id) { case 0: //A1 Ncp = 288/(1<N_RB_UL <= 100) AssertFatal(1==0,"N_RB_UL %d not supported for NR PRACH yet\n",fp->N_RB_UL); @@ -844,7 +837,7 @@ int32_t generate_nr_prach(PHY_VARS_NR_UE *ue, uint8_t gNB_id, uint8_t slot){ //} //printf(" \n"); - #if defined(PRACH_WRITE_OUTPUT_DEBUG) + #ifdef PRACH_WRITE_OUTPUT_DEBUG LOG_M("prach_tx0.m", "prachtx0", prach+(Ncp<<1), prach_len-Ncp, 1, 1); LOG_M("Prach_txsig.m","txs",(int16_t*)(&ue->common_vars.txdata[0][prach_start]), 2*(prach_start+prach_len), 1, 1) #endif diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c index c48c13a810..e9f3f678ec 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_RA.c @@ -42,8 +42,7 @@ #include "SIMULATION/TOOLS/sim.h" // for taus extern RAN_CONTEXT_t RC; - -const uint8_t nr_slots_per_frame_mac[5] = {10, 20, 40, 80, 160}; +extern const uint8_t nr_slots_per_frame[5]; uint8_t DELTA[4]= {2,3,4,6}; @@ -185,7 +184,7 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, tdd_period_slot++; // computing start of next period - uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame_mac[mu]; + uint8_t start_next_period = (rach_slot-(rach_slot%tdd_period_slot)+tdd_period_slot)%nr_slots_per_frame[mu]; *msg2_slot = start_next_period + last_dl_slot_period; // initializing scheduling of slot to next mixed (or last dl) slot *msg2_frame = (*msg2_slot>(rach_slot))? rach_frame : (rach_frame +1); @@ -217,16 +216,16 @@ void nr_schedule_msg2(uint16_t rach_frame, uint16_t rach_slot, default: AssertFatal(1==0,"Invalid response window value %d\n",response_window); } - AssertFatal(slot_window<=nr_slots_per_frame_mac[mu],"Msg2 response window needs to be lower or equal to 10ms"); + AssertFatal(slot_window<=nr_slots_per_frame[mu],"Msg2 response window needs to be lower or equal to 10ms"); // slot and frame limit to transmit msg2 according to response window - uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame_mac[mu]; + uint8_t slot_limit = (rach_slot + slot_window)%nr_slots_per_frame[mu]; //uint8_t frame_limit = (slot_limit>(rach_slot))? rach_frame : (rach_frame +1); // go to previous slot if the current scheduled slot is beyond the response window // and if the slot is not among the PDCCH monitored ones (38.213 10.1) - while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame_mac[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) { + while ((*msg2_slot>slot_limit) || ((*msg2_frame*nr_slots_per_frame[mu]+*msg2_slot-monitoring_offset)%monitoring_slot_period !=0)) { if((*msg2_slot%tdd_period_slot) > 0) (*msg2_slot)--; else @@ -397,11 +396,11 @@ void nr_get_Msg3alloc(NR_ServingCellConfigCommon_t *scc, uint8_t k2 = *ubwp->bwp_Common->pusch_ConfigCommon->choice.setup->pusch_TimeDomainAllocationList->list.array[ra->Msg3_tda_id]->k2; temp_slot = current_slot + k2 + DELTA[mu]; // msg3 slot according to 8.3 in 38.213 - ra->Msg3_slot = temp_slot%nr_slots_per_frame_mac[mu]; - if (nr_slots_per_frame_mac[mu]>temp_slot) + ra->Msg3_slot = temp_slot%nr_slots_per_frame[mu]; + if (nr_slots_per_frame[mu]>temp_slot) ra->Msg3_frame = current_frame; else - ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame_mac[mu]); + ra->Msg3_frame = current_frame + (temp_slot/nr_slots_per_frame[mu]); ra->msg3_nb_rb = 18; ra->msg3_first_rb = 0; From d273ae84f3c9dc9adaf1c432a78cab0cc459ffb9 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Fri, 17 Jul 2020 15:28:34 +0200 Subject: [PATCH 062/171] added a class function to check adb returned values from a list --- ci-scripts/sshconnection.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ci-scripts/sshconnection.py b/ci-scripts/sshconnection.py index ba0f900f29..ed0cf5379a 100644 --- a/ci-scripts/sshconnection.py +++ b/ci-scripts/sshconnection.py @@ -101,6 +101,18 @@ class SSHConnection(): else: sys.exit('SSH Connection Failed') + + + + def cde_check_value(self, commandline, expected, timeout): + logging.debug(commandline) + self.ssh.timeout = timeout + self.ssh.sendline(commandline) + expected.append(pexpect.EOF) + expected.append(pexpect.TIMEOUT) + self.sshresponse = self.ssh.expect(expected) + return self.sshresponse + def command(self, commandline, expectedline, timeout): logging.debug(commandline) self.ssh.timeout = timeout From 8b4498cd119b848216c3f9d1f150cab935b0ca81 Mon Sep 17 00:00:00 2001 From: frtabu Date: Fri, 17 Jul 2020 15:59:38 +0200 Subject: [PATCH 063/171] nr scope as a dynamically loaded shared lib --- cmake_targets/CMakeLists.txt | 4 ++-- executables/nr-softmodem.c | 14 ++++++++------ executables/nr-softmodem.h | 9 --------- executables/nr-uesoftmodem.c | 9 ++++++--- executables/nr-uesoftmodem.h | 8 -------- openair1/PHY/TOOLS/nr_phy_scope.c | 4 ++-- openair1/PHY/TOOLS/nr_phy_scope.h | 2 -- openair1/PHY/TOOLS/phy_scope_interface.c | 4 ++-- openair1/PHY/TOOLS/phy_scope_interface.h | 2 +- targets/RT/USER/lte-softmodem.c | 2 +- targets/RT/USER/lte-uesoftmodem.c | 2 +- 11 files changed, 23 insertions(+), 37 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 7e59f38e8d..d5b90d3454 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2730,7 +2730,7 @@ add_executable(nr-softmodem ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c ${GTPU_need_ITTI} - ${XFORMS_SOURCE_NR} + ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} @@ -2772,7 +2772,7 @@ add_executable(nr-uesoftmodem ${OPENAIR_DIR}/common/utils/utils.c ${OPENAIR_DIR}/common/utils/system.c ${OPENAIR_DIR}/common/utils/nr/nr_common.c - ${XFORMS_SOURCE_NR} + ${XFORMSINTERFACE_SOURCE} ${T_SOURCE} ${UTIL_SRC} ${CONFIG_SOURCES} diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index bf77125975..8f68485d29 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -75,7 +75,7 @@ unsigned short config_frames[4] = {2,9,11,13}; #include "system.h" #include - +#include "PHY/TOOLS/phy_scope_interface.h" #include "PHY/TOOLS/nr_phy_scope.h" #include "stats.h" #include "nr-softmodem.h" @@ -156,7 +156,6 @@ char channels[128] = "0"; int rx_input_level_dBm; -uint32_t do_forms=0; int otg_enabled; //int number_of_cards = 1; @@ -454,7 +453,11 @@ static void get_options(void) { paramdef_t cmdline_params[] = CMDLINE_PARAMS_DESC_GNB ; + CONFIG_SETRTFLAG(CONFIG_NOEXITONHELP); + get_common_options(SOFTMODEM_GNB_BIT ); config_process_cmdline( cmdline_params,sizeof(cmdline_params)/sizeof(paramdef_t),NULL); + CONFIG_CLEARRTFLAG(CONFIG_NOEXITONHELP); + @@ -817,7 +820,6 @@ int main( int argc, char **argv ) configure_linux(); printf("Reading in command-line options\n"); get_options (); - get_common_options(SOFTMODEM_GNB_BIT ); if (CONFIG_ISFLAGSET(CONFIG_ABORT) ) { fprintf(stderr,"Getting configuration failed\n"); @@ -959,14 +961,14 @@ if(!IS_SOFTMODEM_NOS1) printf("RC.nb_RU:%d\n", RC.nb_RU); // once all RUs are ready initialize the rest of the gNBs ((dependence on final RU parameters after configuration) printf("ALL RUs ready - init gNBs\n"); - - if (do_forms==1) { + if(IS_SOFTMODEM_DOFORMS) { + scopeParms_t p; p.argc=&argc; p.argv=argv; p.gNB=RC.gNB[0]; p.ru=RC.ru[0]; - gNBinitScope(&p); + load_softscope("gnb",&p); } if (nfapi_mode != 1 && nfapi_mode != 2) { diff --git a/executables/nr-softmodem.h b/executables/nr-softmodem.h index d113ae45aa..d6cfe6b906 100644 --- a/executables/nr-softmodem.h +++ b/executables/nr-softmodem.h @@ -19,21 +19,12 @@ /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ #define CMDLINE_PARAMS_DESC_GNB { \ {"mmapped-dma", CONFIG_HLP_DMAMAP, PARAMFLAG_BOOL, uptr:&mmapped_dma, defintval:0, TYPE_INT, 0}, \ - {"wait-for-sync", NULL, PARAMFLAG_BOOL, iptr:&wait_for_sync, defintval:0, TYPE_INT, 0}, \ {"single-thread-disable", CONFIG_HLP_NOSNGLT, PARAMFLAG_BOOL, iptr:&single_thread_flag, defintval:1, TYPE_INT, 0}, \ {"A" , CONFIG_HLP_TADV, 0, uptr:&timing_advance, defintval:0, TYPE_UINT, 0}, \ - {"C" , CONFIG_HLP_DLF, 0, u64ptr:&(downlink_frequency[0][0]), defuintval:DEFAULT_DLF, TYPE_UINT64, 0}, \ - {"a" , CONFIG_HLP_CHOFF, 0, iptr:&chain_offset, defintval:0, TYPE_INT, 0}, \ - {"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, uptr:(uint32_t *)&do_forms, defintval:0, TYPE_INT8, 0}, \ {"E" , CONFIG_HLP_TQFS, PARAMFLAG_BOOL, i8ptr:&threequarter_fs, defintval:0, TYPE_INT8, 0}, \ {"K" , CONFIG_HLP_ITTIL, PARAMFLAG_NOFREE, strptr:&itti_dump_file, defstrval:"/tmp/itti.dump", TYPE_STRING, 0}, \ {"m" , CONFIG_HLP_DLMCS, 0, uptr:&target_dl_mcs, defintval:0, TYPE_UINT, 0}, \ {"t" , CONFIG_HLP_ULMCS, 0, uptr:&target_ul_mcs, defintval:0, TYPE_UINT, 0}, \ - {"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, iptr:&opp_enabled, defintval:0, TYPE_INT, 0}, \ - {"numerology" , CONFIG_HLP_NUMEROLOGY, PARAMFLAG_BOOL, iptr:&numerology, defintval:0, TYPE_INT, 0}, \ - {"emulate-rf" , CONFIG_HLP_EMULATE_RF, PARAMFLAG_BOOL, iptr:&emulate_rf, defintval:0, TYPE_INT, 0}, \ - {"parallel-config", CONFIG_HLP_PARALLEL_CMD,0, strptr:(char **)¶llel_config, defstrval:NULL, TYPE_STRING, 0}, \ - {"worker-config", CONFIG_HLP_WORKER_CMD, 0, strptr:(char **)&worker_config, defstrval:NULL, TYPE_STRING, 0}, \ {"usrp-tx-thread-config", CONFIG_HLP_USRP_THREAD, 0, iptr:&usrp_tx_thread, defstrval:0, TYPE_INT, 0}, \ {"s" , CONFIG_HLP_SNR, 0, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0}, \ } diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 6d3bbc9038..b36a041a70 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -78,6 +78,7 @@ unsigned short config_frames[4] = {2,9,11,13}; //#include "stats.h" // current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) +#include "PHY/TOOLS/phy_scope_interface.h" #include "PHY/TOOLS/nr_phy_scope.h" // at eNB 0, an UL scope for every UE //FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; @@ -158,7 +159,7 @@ int rx_input_level_dBm; //static int online_log_messages=0; -uint32_t do_forms=0; + int otg_enabled; //int number_of_cards = 1; @@ -761,8 +762,10 @@ int main( int argc, char **argv ) { memset (&UE_PF_PO[0][0], 0, sizeof(UE_PF_PO_t)*NUMBER_OF_UE_MAX*MAX_NUM_CCs); configure_linux(); mlockall(MCL_CURRENT | MCL_FUTURE); - if (do_forms) - nrUEinitScope(PHY_vars_UE_g[0][0]); + + if(IS_SOFTMODEM_DOFORMS) { + load_softscope("gnb",PHY_vars_UE_g[0][0]); + } number_of_cards = 1; for(int CC_id=0; CC_id Date: Sun, 19 Jul 2020 17:56:00 +0200 Subject: [PATCH 064/171] removed all Getters and Setters from EPC, HTML classes (as all attributes are public) --- ci-scripts/epc.py | 56 ++++---- ci-scripts/html.py | 116 ++++++++--------- ci-scripts/main.py | 316 ++++++++++++++++++++++----------------------- ci-scripts/ran.py | 262 ++++++++++++++++++------------------- 4 files changed, 373 insertions(+), 377 deletions(-) diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 09d500f203..14bbcd0540 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -70,34 +70,34 @@ class EPCManagement(): # Setter and Getters on Public Members #----------------------------------------------------------- - def SetIPAddress(self, ipaddress): - self.IPAddress = ipaddress - def GetIPAddress(self): - return self.IPAddress - def SetUserName(self, username): - self.UserName = username - def GetUserName(self): - return self.UserName - def SetPassword(self, password): - self.Password = password - def GetPassword(self): - return self.Password - def SetSourceCodePath(self, sourcecodepath): - self.SourceCodePath = sourcecodepath - def GetSourceCodePath(self): - return self.SourceCodePath - def SetType(self, kind): - self.Type = kind - def GetType(self): - return self.Type - def SetHtmlObj(self, obj): - self.htmlObj = obj - def SetTestCase_id(self, idx): - self.testCase_id = idx - def GetMmeIPAddress(self): - return self.MmeIPAddress - def SetContainerPrefix(self, prefix): - self.containerPrefix = prefix +# def SetIPAddress(self, ipaddress): +# self.IPAddress = ipaddress +# def GetIPAddress(self): +# return self.IPAddress +# def SetUserName(self, username): +# self.UserName = username +# def GetUserName(self): +# return self.UserName +# def SetPassword(self, password): +# self.Password = password +# def GetPassword(self): +# return self.Password +# def SetSourceCodePath(self, sourcecodepath): +# self.SourceCodePath = sourcecodepath +# def GetSourceCodePath(self): +# return self.SourceCodePath +# def SetType(self, kind): +# self.Type = kind +# def GetType(self): +# return self.Type +# def SetHtmlObj(self, obj): +# self.htmlObj = obj +# def SetTestCase_id(self, idx): +# self.testCase_id = idx +# def GetMmeIPAddress(self): +# return self.MmeIPAddress +# def SetContainerPrefix(self, prefix): +# self.containerPrefix = prefix #----------------------------------------------------------- # EPC management functions diff --git a/ci-scripts/html.py b/ci-scripts/html.py index 8fa99fa61b..b7b3c31fad 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -82,73 +82,69 @@ class HTMLManagement(): #----------------------------------------------------------- # Setters and Getters #----------------------------------------------------------- - def SethtmlUEFailureMsg(self,huefa): - self.htmlUEFailureMsg = huefa - def GethtmlUEFailureMsg(self): - return self.htmlUEFailureMsg - def SetHmleNBFailureMsg(self, msg): - self.htmleNBFailureMsg = msg - - def Setdesc(self, dsc): - self.desc = dsc - - def SetstartTime(self, sttime): - self.startTime = sttime - - def SettestCase_id(self, tcid): - self.testCase_id = tcid - def GettestCase_id(self): - return self.testCase_id - - def SetranRepository(self, repository): - self.ranRepository = repository - def SetranAllowMerge(self, merge): - self.ranAllowMerge = merge - def SetranBranch(self, branch): - self.ranBranch = branch - def SetranCommitID(self, commitid): - self.ranCommitID = commitid - def SetranTargetBranch(self, tbranch): - self.ranTargetBranch = tbranch - + def SethtmlUEConnected(self, nbUEs): if nbUEs > 0: self.htmlUEConnected = nbUEs else: self.htmlUEConnected = 1 - def SethtmlNb_Smartphones(self, nbUEs): - self.htmlNb_Smartphones = nbUEs - def SethtmlNb_CATM_Modules(self, nbUEs): - self.htmlNb_CATM_Modules = nbUEs + - def SetnbTestXMLfiles(self, nb): - self.nbTestXMLfiles = nb - def GetnbTestXMLfiles(self): - return self.nbTestXMLfiles +# def SethtmlUEFailureMsg(self,huefa): +# self.htmlUEFailureMsg = huefa +# def GethtmlUEFailureMsg(self): +# return self.htmlUEFailureMsg +# def SetHmleNBFailureMsg(self, msg): +# self.htmleNBFailureMsg = msg +# def Setdesc(self, dsc): +# self.desc = dsc +# def SetstartTime(self, sttime): +# self.startTime = sttime +# def SettestCase_id(self, tcid): +# self.testCase_id = tcid +# def GettestCase_id(self): +# return self.testCase_id +# def SetranRepository(self, repository): +# self.ranRepository = repository +# def SetranAllowMerge(self, merge): +# self.ranAllowMerge = merge +# def SetranBranch(self, branch): +# self.ranBranch = branch +# def SetranCommitID(self, commitid): +# self.ranCommitID = commitid +# def SetranTargetBranch(self, tbranch): +# self.ranTargetBranch = tbranch +# def SethtmlNb_Smartphones(self, nbUEs): +# self.htmlNb_Smartphones = nbUEs +# def SethtmlNb_CATM_Modules(self, nbUEs): +# self.htmlNb_CATM_Modules = nbUEs +# def SetnbTestXMLfiles(self, nb): +# self.nbTestXMLfiles = nb +# def GetnbTestXMLfiles(self): +# return self.nbTestXMLfiles +# def SettestXMLfiles(self, xmlFile): +# self.testXMLfiles.append(xmlFile) +# def SethtmlTabRefs(self, tabRef): +# self.htmlTabRefs.append(tabRef) +# def SethtmlTabNames(self, tabName): +# self.htmlTabNames.append(tabName) +# def SethtmlTabIcons(self, tabIcon): +# self.htmlTabIcons.append(tabIcon) +# def SetOsVersion(self, version, idx): +# self.OsVersion[idx] = version +# def SetKernelVersion(self, version, idx): +# self.KernelVersion[idx] = version +# def SetUhdVersion(self, version, idx): +# self.UhdVersion[idx] = version +# def SetUsrpBoard(self, version, idx): +# self.UsrpBoard[idx] = version +# def SetCpuNb(self, nb, idx): +# self.CpuNb[idx] = nb +# def SetCpuModel(self, model, idx): +# self.CpuModel[idx] = model +# def SetCpuMHz(self, freq, idx): +# self.CpuMHz[idx] = freq - def SettestXMLfiles(self, xmlFile): - self.testXMLfiles.append(xmlFile) - def SethtmlTabRefs(self, tabRef): - self.htmlTabRefs.append(tabRef) - def SethtmlTabNames(self, tabName): - self.htmlTabNames.append(tabName) - def SethtmlTabIcons(self, tabIcon): - self.htmlTabIcons.append(tabIcon) - - def SetOsVersion(self, version, idx): - self.OsVersion[idx] = version - def SetKernelVersion(self, version, idx): - self.KernelVersion[idx] = version - def SetUhdVersion(self, version, idx): - self.UhdVersion[idx] = version - def SetUsrpBoard(self, version, idx): - self.UsrpBoard[idx] = version - def SetCpuNb(self, nb, idx): - self.CpuNb[idx] = nb - def SetCpuModel(self, model, idx): - self.CpuModel[idx] = model - def SetCpuMHz(self, freq, idx): - self.CpuMHz[idx] = freq #----------------------------------------------------------- # HTML structure creation functions diff --git a/ci-scripts/main.py b/ci-scripts/main.py index f7feeb08d4..7bfe331fc2 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -209,9 +209,9 @@ class OaiCiTest(): sys.exit(1) def CheckFlexranCtrlInstallation(self): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': return - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) SSH.command('ls -ls /opt/flexran_rtc/*/rt_controller', '\$', 5) result = re.search('/opt/flexran_rtc/build/rt_controller', SSH.getBefore()) if result is not None: @@ -222,15 +222,15 @@ class OaiCiTest(): def InitializeFlexranCtrl(self): if RAN.flexranCtrlInstalled == False: return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) SSH.command('cd /opt/flexran_rtc', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S rm -f log/*.log', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S rm -f log/*.log', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S echo "build/rt_controller -c log_config/basic_log" > ./my-flexran-ctl.sh', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S chmod 755 ./my-flexran-ctl.sh', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --unsafe --name=flexran_rtc_daemon --chdir=/opt/flexran_rtc -o /opt/flexran_rtc/log/flexranctl_' + self.testCase_id + '.log ././my-flexran-ctl.sh', '\$', 5) SSH.command('ps -aux | grep --color=never rt_controller', '\$', 5) result = re.search('rt_controller -c ', SSH.getBefore()) if result is not None: @@ -513,12 +513,12 @@ class OaiCiTest(): else: if RAN.air_interface == 'lte': if RAN.eNBmbmsEnables[0]: - HTML.SethtmlUEFailureMsg('oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured') + HTML.htmlUEFailureMsg='oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' else: - HTML.SethtmlUEFailureMsg('oaitun_ue1 interface is either NOT mounted or NOT configured') + HTML.htmlUEFailureMsg='oaitun_ue1 interface is either NOT mounted or NOT configured' HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') else: - HTML.SethtmlUEFailureMsg('nr-uesoftmodem did NOT synced') + HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced' HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') logging.error('\033[91mInitialize OAI UE Failed! \033[0m') self.AutoTerminateUEandeNB() @@ -671,7 +671,7 @@ class OaiCiTest(): self.AutoTerminateUEandeNB() def PingCatM(self): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') check_eNB = True @@ -684,10 +684,10 @@ class OaiCiTest(): try: statusQueue = SimpleQueue() lock = Lock() - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) SSH.command('cd scripts', '\$', 5) - if re.match('OAI', EPC.GetType(), re.IGNORECASE): + if re.match('OAI', EPC.Type, re.IGNORECASE): logging.debug('Using the OAI EPC HSS: not implemented yet') HTML.CreateHtmlTestRow(self.ping_args, 'KO', pStatus) HTML.CreateHtmlTabFooter(False) @@ -1200,7 +1200,7 @@ class OaiCiTest(): for job in multi_jobs: job.join() if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) SSH.command('cd /opt/flexran_rtc', '\$', 5) SSH.command('curl http://localhost:9999/stats | jq \'.\' > log/check_status_' + self.testCase_id + '.log 2>&1', '\$', 5) SSH.command('cat log/check_status_' + self.testCase_id + '.log | jq \'.eNB_config[0].UE\' | grep -c rnti | sed -e "s#^#Nb Connected UE = #"', '\$', 5) @@ -1312,13 +1312,13 @@ class OaiCiTest(): # Launch ping on the EPC side (true for ltebox and old open-air-cn) # But for OAI-Rel14-CUPS, we launch from python executor launchFromEpc = True - if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): launchFromEpc = False ping_time = re.findall("-c (\d+)",str(self.ping_args)) if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) SSH.command('cd scripts', '\$', 5) ping_status = SSH.command('stdbuf -o0 ping ' + self.ping_args + ' ' + UE_IPAddress + ' 2>&1 | stdbuf -o0 tee ping_' + self.testCase_id + '_' + device_id + '.log', '\$', int(ping_time[0])*1.5) else: @@ -1327,9 +1327,9 @@ class OaiCiTest(): logging.debug(cmd) ret = subprocess.run(cmd, shell=True) ping_status = ret.returncode - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cat ' + EPC.SourceCodePath + '/scripts/ping_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) # TIMEOUT CASE if ping_status < 0: message = 'Ping with UE (' + str(UE_IPAddress) + ') crashed due to TIMEOUT!' @@ -1487,7 +1487,7 @@ class OaiCiTest(): else: copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/ping_' + self.testCase_id + '.log', '.') if (copyin_res == 0): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'ping_' + self.testCase_id + '.log', EPC.GetSourceCodePath() + '/scripts') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'ping_' + self.testCase_id + '.log', EPC.SourceCodePath + '/scripts') except: os.kill(os.getppid(),signal.SIGUSR1) @@ -1496,7 +1496,7 @@ class OaiCiTest(): if result is not None: self.PingNoS1() return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') check_eNB = True @@ -1840,7 +1840,7 @@ class OaiCiTest(): # Launch iperf server on EPC side (true for ltebox and old open-air-cn0 # But for OAI-Rel14-CUPS, we launch from python executor and we are using its IP address as iperf client address launchFromEpc = True - if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): launchFromEpc = False cmd = 'hostname -I' ret = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, encoding='utf-8') @@ -1848,13 +1848,13 @@ class OaiCiTest(): EPC_Iperf_UE_IPAddress = ret.stdout.strip() port = 5001 + idx if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) SSH.command('rm -f iperf_server_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) if udpIperf: - SSH.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5) + SSH.command('echo $USER; nohup iperf -u -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.UserName, 5) else: - SSH.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.GetUserName(), 5) + SSH.command('echo $USER; nohup iperf -s -i 1 -p ' + str(port) + ' > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', EPC.UserName, 5) SSH.close() else: if self.ueIperfVersion == self.dummyIperfVersion: @@ -1877,7 +1877,7 @@ class OaiCiTest(): SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets', '\$', 5) else: SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) + SSH.command('cd ' + EPC.SourceCodePath+ '/scripts', '\$', 5) iperf_time = self.Iperf_ComputeTime() time.sleep(0.5) @@ -1911,27 +1911,27 @@ class OaiCiTest(): # Kill iperf server on EPC side if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('killall --signal SIGKILL iperf', EPC.GetUserName(), 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password + SSH.command('killall --signal SIGKILL iperf', EPC.UserName, 5) SSH.close() else: cmd = 'killall --signal SIGKILL iperf' logging.debug(cmd) subprocess.run(cmd, shell=True) time.sleep(1) - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') # in case of failure, retrieve server log if (clientStatus == -1) or (clientStatus == -2): if launchFromEpc: time.sleep(1) if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): os.remove('iperf_server_' + self.testCase_id + '_' + device_id + '.log') - SSH.copyin(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + SSH.copyin(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath+ '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') self.Iperf_analyzeV2Server(lock, UE_IPAddress, device_id, statusQueue, modified_options) # in case of OAI-UE if (device_id == 'OAI-UE'): SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_' + self.testCase_id + '_' + device_id + '.log', '.') - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') def Iperf_common(self, lock, UE_IPAddress, device_id, idx, ue_num, statusQueue): try: @@ -1945,8 +1945,8 @@ class OaiCiTest(): if (device_id != 'OAI-UE'): SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) # if by chance ADB server and EPC are on the same remote host, at least log collection will take care of it - SSH.command('if [ ! -d ' + EPC.GetSourceCodePath() + '/scripts ]; then mkdir -p ' + EPC.GetSourceCodePath() + '/scripts ; fi', '\$', 5) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) + SSH.command('if [ ! -d ' + EPC.SourceCodePath + '/scripts ]; then mkdir -p ' + EPC.SourceCodePath + '/scripts ; fi', '\$', 5) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) # Checking if iperf / iperf3 are installed if self.ADBCentralized: SSH.command('adb -s ' + device_id + ' shell "ls /data/local/tmp"', '\$', 5) @@ -2005,7 +2005,7 @@ class OaiCiTest(): SSH.command('echo $USER; nohup iperf -B ' + UE_IPAddress + ' -u -s -i 1 > iperf_server_' + self.testCase_id + '_' + device_id + '.log &', self.UEUserName, 5) else: SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) if self.ADBCentralized: if (useIperf3): SSH.command('stdbuf -o0 adb -s ' + device_id + ' shell /data/local/tmp/iperf3 -s &', '\$', 5) @@ -2027,11 +2027,11 @@ class OaiCiTest(): # Launch the IPERF client on the EPC side for DL (true for ltebox and old open-air-cn # But for OAI-Rel14-CUPS, we launch from python executor launchFromEpc = True - if re.match('OAI-Rel14-CUPS', EPC.GetType(), re.IGNORECASE): + if re.match('OAI-Rel14-CUPS', EPC.Type, re.IGNORECASE): launchFromEpc = False if launchFromEpc: - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath() + '/scripts', '\$', 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath + '/scripts', '\$', 5) iperf_time = self.Iperf_ComputeTime() time.sleep(0.5) @@ -2066,9 +2066,9 @@ class OaiCiTest(): logging.debug(cmd) ret = subprocess.run(cmd, shell=True) iperf_status = ret.returncode - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cat ' + EPC.GetSourceCodePath() + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cat ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) if iperf_status < 0: if launchFromEpc: SSH.close() @@ -2105,7 +2105,7 @@ class OaiCiTest(): if (device_id == 'OAI-UE'): SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') else: - SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.GetSourceCodePath() + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') + SSH.copyin(self.ADBIPAddress, self.ADBUserName, self.ADBPassword, EPC.SourceCodePath + '/scripts/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') # fromdos has to be called on the python executor not on ADB server cmd = 'fromdos -o iperf_server_' + self.testCase_id + '_' + device_id + '.log' subprocess.run(cmd, shell=True) @@ -2115,10 +2115,10 @@ class OaiCiTest(): if (device_id == 'OAI-UE'): if (os.path.isfile('iperf_server_' + self.testCase_id + '_' + device_id + '.log')): if not launchFromEpc: - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') else: SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/iperf_server_' + self.testCase_id + '_' + device_id + '.log', '.') - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.GetSourceCodePath() + '/scripts') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_' + device_id + '.log', EPC.SourceCodePath + '/scripts') except: os.kill(os.getppid(),signal.SIGUSR1) @@ -2202,10 +2202,10 @@ class OaiCiTest(): if (clientStatus == -1): copyin_res = SSH.copyin(iServerIPAddr, iServerUser, iServerPasswd, '/tmp/tmp_iperf_server_' + self.testCase_id + '.log', 'iperf_server_' + self.testCase_id + '_OAI-UE.log') if (copyin_res == 0): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_server_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts') copyin_res = SSH.copyin(iClientIPAddr, iClientUser, iClientPasswd, '/tmp/tmp_iperf_' + self.testCase_id + '.log', 'iperf_' + self.testCase_id + '_OAI-UE.log') if (copyin_res == 0): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.GetSourceCodePath() + '/scripts') + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, 'iperf_' + self.testCase_id + '_OAI-UE.log', EPC.SourceCodePath + '/scripts') iperf_noperf = False if status_queue.empty(): iperf_status = False @@ -2236,7 +2236,7 @@ class OaiCiTest(): if result is not None: self.IperfNoS1() return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or self.ADBIPAddress == '' or self.ADBUserName == '' or self.ADBPassword == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') check_eNB = True @@ -2432,7 +2432,7 @@ class OaiCiTest(): nrFoundDCI = 0 nrCRCOK = 0 mbms_messages = 0 - HTML.SethtmlUEFailureMsg('') + HTML.htmlUEFailureMsg='' global_status = CONST.ALL_PROCESSES_OK for line in ue_log_file.readlines(): result = re.search('nr_synchro_time', str(line)) @@ -2502,22 +2502,22 @@ class OaiCiTest(): if result is not None and (not mib_found): try: mibMsg = "MIB Information: " + result.group(1) + ', ' + result.group(2) - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug('\033[94m' + mibMsg + '\033[0m') mibMsg = " nidcell = " + result.group('nidcell') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg) + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg logging.debug('\033[94m' + mibMsg + '\033[0m') mibMsg = " n_rb_dl = " + result.group('n_rb_dl') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug('\033[94m' + mibMsg + '\033[0m') mibMsg = " phich_duration = " + result.group('phich_duration') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg) + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg logging.debug('\033[94m' + mibMsg + '\033[0m') mibMsg = " phich_resource = " + result.group('phich_resource') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug('\033[94m' + mibMsg + '\033[0m') mibMsg = " tx_ant = " + result.group('tx_ant') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug('\033[94m' + mibMsg + '\033[0m') mib_found = True except Exception as e: @@ -2526,7 +2526,7 @@ class OaiCiTest(): if result is not None and (not frequency_found): try: mibMsg = "Measured Carrier Frequency = " + result.group('measured_carrier_frequency') + ' Hz' - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug('\033[94m' + mibMsg + '\033[0m') frequency_found = True except Exception as e: @@ -2535,7 +2535,7 @@ class OaiCiTest(): if result is not None and (not plmn_found): try: mibMsg = 'PLMN MCC = ' + result.group('mcc') + ' MNC = ' + result.group('mnc') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug('\033[94m' + mibMsg + '\033[0m') plmn_found = True except Exception as e: @@ -2544,7 +2544,7 @@ class OaiCiTest(): if result is not None: try: mibMsg = "The operator is: " + result.group('operator') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + '\n' logging.debug('\033[94m' + mibMsg + '\033[0m') except Exception as e: logging.error('\033[91m' + "Operator name not found" + '\033[0m') @@ -2552,7 +2552,7 @@ class OaiCiTest(): if result is not None: try: mibMsg = "SIB5 InterFreqCarrierFreq element " + result.group(1) + '/' + result.group(2) - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + mibMsg + ' -> ') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + mibMsg + ' -> ' logging.debug('\033[94m' + mibMsg + '\033[0m') except Exception as e: logging.error('\033[91m' + "SIB5 InterFreqCarrierFreq element not found" + '\033[0m') @@ -2570,7 +2570,7 @@ class OaiCiTest(): if result is not None: try: prb = result.group('allowed_bandwidth') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + ' -- PRB: ' + prb + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + ' -- PRB: ' + prb + '\n' logging.debug('\033[94m' + " AllowedMeasBandwidth: " + prb + '\033[0m') except Exception as e: logging.error('\033[91m' + " AllowedMeasBandwidth not found" + '\033[0m') @@ -2578,48 +2578,48 @@ class OaiCiTest(): if rrcConnectionRecfgComplete > 0: statMsg = 'UE connected to eNB (' + str(rrcConnectionRecfgComplete) + ' RRCConnectionReconfigurationComplete message(s) generated)' logging.debug('\033[94m' + statMsg + '\033[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if nrUEFlag: if nrDecodeMib > 0: statMsg = 'UE showed ' + str(nrDecodeMib) + ' MIB decode message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if nrFoundDCI > 0: statMsg = 'UE showed ' + str(nrFoundDCI) + ' DCI found message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if nrCRCOK > 0: statMsg = 'UE showed ' + str(nrCRCOK) + ' PDSCH decoding message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if not frequency_found: statMsg = 'NR-UE could NOT synch!' logging.error('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if uciStatMsgCount > 0: statMsg = 'UE showed ' + str(uciStatMsgCount) + ' "uci->stat" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if pdcpDataReqFailedCount > 0: statMsg = 'UE showed ' + str(pdcpDataReqFailedCount) + ' "PDCP data request failed" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if badDciCount > 0: statMsg = 'UE showed ' + str(badDciCount) + ' "bad DCI 1(A)" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if f1aRetransmissionCount > 0: statMsg = 'UE showed ' + str(f1aRetransmissionCount) + ' "Format1A Retransmission but TBS are different" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if fatalErrorCount > 0: statMsg = 'UE showed ' + str(fatalErrorCount) + ' "FATAL ERROR:" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if macBsrTimerExpiredCount > 0: statMsg = 'UE showed ' + str(fatalErrorCount) + ' "MAC BSR Triggered ReTxBSR Timer expiry" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if RAN.eNBmbmsEnables[0]: if mbms_messages > 0: statMsg = 'UE showed ' + str(mbms_messages) + ' "TRIED TO PUSH MBMS DATA" message(s)' @@ -2628,7 +2628,7 @@ class OaiCiTest(): statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)' logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m') global_status = OAI_UE_PROCESS_NO_MBMS_MSGS - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + statMsg + '\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if foundSegFault: logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') if not nrUEFlag: @@ -2638,7 +2638,7 @@ class OaiCiTest(): global_status = CONST.OAI_UE_PROCESS_SEG_FAULT if foundAssertion: logging.debug('\u001B[1;30;43m UE showed an assertion! \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE showed an assertion!\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE showed an assertion!\n' if not nrUEFlag: if not mib_found or not frequency_found: global_status = CONST.OAI_UE_PROCESS_ASSERTION @@ -2647,14 +2647,14 @@ class OaiCiTest(): global_status = CONST.OAI_UE_PROCESS_ASSERTION if foundRealTimeIssue: logging.debug('\u001B[1;37;41m UE faced real time issues! \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE faced real time issues!\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE faced real time issues!\n' if nrUEFlag: if not frequency_found: global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC else: if no_cell_sync_found and not mib_found: logging.debug('\u001B[1;37;41m UE could not synchronize ! \u001B[0m') - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'UE could not synchronize!\n') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'UE could not synchronize!\n' global_status = CONST.OAI_UE_PROCESS_COULD_NOT_SYNC return global_status @@ -2662,13 +2662,13 @@ class OaiCiTest(): def TerminateFlexranCtrl(self): if RAN.flexranCtrlInstalled == False or RAN.flexranCtrlStarted == False: return - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('echo ' + EPC.Password + ' | sudo -S daemon --name=flexran_rtc_daemon --stop', '\$', 5) time.sleep(1) - SSH.command('echo ' + EPC.GetPassword() + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) + SSH.command('echo ' + EPC.Password + ' | sudo -S killall --signal SIGKILL rt_controller', '\$', 5) time.sleep(1) SSH.close() RAN.flexranCtrlStarted=False @@ -2737,7 +2737,7 @@ class OaiCiTest(): copyin_res = SSH.copyin(self.UEIPAddress, self.UEUserName, self.UEPassword, self.UESourceCodePath + '/cmake_targets/' + self.UELogFile, '.') if (copyin_res == -1): logging.debug('\u001B[1;37;41m Could not copy UE logfile to analyze it! \u001B[0m') - HTML.SethtmlUEFailureMsg('Could not copy UE logfile to analyze it!') + HTML.htmlUEFailureMsg='Could not copy UE logfile to analyze it!' HTML.CreateHtmlTestRow('N/A', 'KO', CONST.OAI_UE_PROCESS_NOLOGFILE_TO_ANALYZE, 'UE') self.UELogFile = '' return @@ -2750,7 +2750,7 @@ class OaiCiTest(): ueAction = 'Connection' if (logStatus < 0): logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') - HTML.SethtmlUEFailureMsg('' + ueAction + ' Failed\n' + HTML.GethtmlUEFailureMsg()) + HTML.htmlUEFailureMsg='' + ueAction + ' Failed\n' + HTML.htmlUEFailureMsg HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') if RAN.air_interface == 'lte': # In case of sniffing on commercial eNBs we have random results @@ -2764,7 +2764,7 @@ class OaiCiTest(): self.AutoTerminateUEandeNB() else: logging.debug('\u001B[1m' + ueAction + ' Completed \u001B[0m') - HTML.SethtmlUEFailureMsg('' + ueAction + ' Completed\n' + HTML.GethtmlUEFailureMsg()) + HTML.htmlUEFailureMsg='' + ueAction + ' Completed\n' + HTML.htmlUEFailureMsg HTML.CreateHtmlTestRow('N/A', 'OK', CONST.ALL_PROCESSES_OK) self.UELogFile = '' else: @@ -2773,31 +2773,31 @@ class OaiCiTest(): def AutoTerminateUEandeNB(self): if (self.ADBIPAddress != 'none'): self.testCase_id = 'AUTO-KILL-UE' - HTML.SettestCase_id(self.testCase_id) + HTML.testCase_id=self.testCase_id self.desc = 'Automatic Termination of UE' - HTML.Setdesc('Automatic Termination of UE') + HTML.desc='Automatic Termination of UE' self.ShowTestID() self.TerminateUE() if (self.Initialize_OAI_UE_args != ''): self.testCase_id = 'AUTO-KILL-OAI-UE' - HTML.SettestCase_id(self.testCase_id) + HTML.testCase_id=self.testCase_id self.desc = 'Automatic Termination of OAI-UE' - HTML.Setdesc('Automatic Termination of OAI-UE') + HTML.desc='Automatic Termination of OAI-UE' self.ShowTestID() self.TerminateOAIUE() if (RAN.Initialize_eNB_args != ''): self.testCase_id = 'AUTO-KILL-eNB' - HTML.SettestCase_id(self.testCase_id) + HTML.testCase_id=self.testCase_id self.desc = 'Automatic Termination of eNB' - HTML.Setdesc('Automatic Termination of eNB') + HTML.desc='Automatic Termination of eNB' self.ShowTestID() RAN.eNB_instance='0' RAN.TerminateeNB() if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: self.testCase_id = 'AUTO-KILL-flexran-ctl' - HTML.SettestCase_id(self.testCase_id) + HTML.testCase_id=self.testCase_id self.desc = 'Automatic Termination of FlexRan CTL' - HTML.Setdesc('Automatic Termination of FlexRan CTL') + HTML.desc='Automatic Termination of FlexRan CTL' self.ShowTestID() self.TerminateFlexranCtrl() RAN.prematureExit=True @@ -2807,7 +2807,7 @@ class OaiCiTest(): HTML.CreateHtmlTestRow(str(self.idle_sleep_time) + ' sec', 'OK', CONST.ALL_PROCESSES_OK) def X2_Status(self, idx, fileName): - cmd = "curl --silent http://" + EPC.GetIPAddress() + ":9999/stats | jq '.' > " + fileName + cmd = "curl --silent http://" + EPC.IPAddress + ":9999/stats | jq '.' > " + fileName message = cmd + '\n' logging.debug(cmd) subprocess.run(cmd, shell=True) @@ -2871,7 +2871,7 @@ class OaiCiTest(): eNB_cnt = self.x2NbENBs cnt = 0 while cnt < eNB_cnt: - cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1" + cmd = "curl -XPOST http://" + EPC.IPAddress + ":9999/rrc/x2_ho_net_control/enb/" + str(self.x2ENBBsIds[0][cnt]) + "/1" logging.debug(cmd) fullMessage += cmd + '\n' subprocess.run(cmd, shell=True) @@ -2885,7 +2885,7 @@ class OaiCiTest(): while cnt < eNB_cnt: ueIdx = 0 while ueIdx < len(self.x2ENBConnectedUEs[0][cnt]): - cmd = "curl -XPOST http://" + EPC.GetIPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1]) + cmd = "curl -XPOST http://" + EPC.IPAddress() + ":9999/rrc/ho/senb/" + str(self.x2ENBBsIds[0][cnt]) + "/ue/" + str(self.x2ENBConnectedUEs[0][cnt][ueIdx]) + "/tenb/" + str(self.x2ENBBsIds[0][eNB_cnt - cnt - 1]) logging.debug(cmd) fullMessage += cmd + '\n' subprocess.run(cmd, shell=True) @@ -2936,8 +2936,8 @@ class OaiCiTest(): SSH.command('zip build.log.zip build_log_*/*', '\$', 60) SSH.close() def LogCollectPing(self): - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) SSH.command('cd scripts', '\$', 5) SSH.command('rm -f ping.log.zip', '\$', 5) SSH.command('zip ping.log.zip ping*.log', '\$', 60) @@ -2945,8 +2945,8 @@ class OaiCiTest(): SSH.close() def LogCollectIperf(self): - SSH.open(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword()) - SSH.command('cd ' + EPC.GetSourceCodePath(), '\$', 5) + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) + SSH.command('cd ' + EPC.SourceCodePath, '\$', 5) SSH.command('cd scripts', '\$', 5) SSH.command('rm -f iperf.log.zip', '\$', 5) SSH.command('zip iperf.log.zip iperf*.log', '\$', 60) @@ -2964,13 +2964,13 @@ class OaiCiTest(): def RetrieveSystemVersion(self, machine): if RAN.eNBIPAddress == 'none' or self.UEIPAddress == 'none': - HTML.SetOsVersion('Ubuntu 16.04.5 LTS', 0) - HTML.SetKernelVersion('4.15.0-45-generic', 0) - HTML.SetUhdVersion('3.13.0.1-0', 0) - HTML.SetUsrpBoard('B210', 0) - HTML.SetCpuNb('4', 0) - HTML.SetCpuModel('Intel(R) Core(TM) i5-6200U', 0) - HTML.SetCpuMHz('2399.996 MHz', 0) + HTML.OsVersion[0]='Ubuntu 16.04.5 LTS' + HTML.KernelVersion[0]='4.15.0-45-generic' + HTML.UhdVersion[0]='3.13.0.1-0' + HTML.UsrpBoard[0]='B210' + HTML.CpuNb[0]='4' + HTML.CpuModel[0]='Intel(R) Core(TM) i5-6200U' + HTML.CpuMHz[0]='2399.996 MHz' return 0 if machine == 'eNB': if RAN.eNBIPAddress != '' and RAN.eNBUserName != '' and RAN.eNBPassword != '': @@ -2995,7 +2995,7 @@ class OaiCiTest(): if result is not None: OsVersion = result.group('os_type') logging.debug('OS is: ' + OsVersion) - HTML.SetOsVersion(OsVersion, idx) + HTML.OsVersion[idx]=OsVersion else: SSH.command('hostnamectl', '\$', 5) result = re.search('Operating System: (?P[a-zA-Z0-9\-\_\.\ ]+)', SSH.getBefore()) @@ -3007,26 +3007,26 @@ class OaiCiTest(): if result is not None: OsVersion = OsVersion.replace('7 ', result.group('os_version')) logging.debug('OS is: ' + OsVersion) - HTML.SetOsVersion(OsVersion, idx) + HTML.OsVersion[idx]=OsVersion SSH.command('uname -r', '\$', 5) result = re.search('uname -r\\\\r\\\\n(?P[a-zA-Z0-9\-\_\.]+)', SSH.getBefore()) if result is not None: KernelVersion = result.group('kernel_version') logging.debug('Kernel Version is: ' + KernelVersion) - HTML.SetKernelVersion(KernelVersion, idx) + HTML.KernelVersion[idx]=KernelVersion SSH.command('dpkg --list | egrep --color=never libuhd003', '\$', 5) result = re.search('libuhd003:amd64 *(?P[0-9\.]+)', SSH.getBefore()) if result is not None: UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + UhdVersion) - HTML.SetUhdVersion(UhdVersion, idx) + HTML.UhdVersion[idx]=UhdVersion else: SSH.command('uhd_config_info --version', '\$', 5) result = re.search('UHD (?P[a-zA-Z0-9\.\-]+)', SSH.getBefore()) if result is not None: UhdVersion = result.group('uhd_version') logging.debug('UHD Version is: ' + UhdVersion) - HTML.SetUhdVersion(UhdVersion, idx) + HTML.UhdVersion[idx]=UhdVersion SSH.command('echo ' + Password + ' | sudo -S uhd_find_devices', '\$', 60) usrp_boards = re.findall('product: ([0-9A-Za-z]+)\\\\r\\\\n', SSH.getBefore()) count = 0 @@ -3038,19 +3038,19 @@ class OaiCiTest(): count += 1 if count > 0: logging.debug('USRP Board(s) : ' + UsrpBoard) - HTML.SetUsrpBoard(UsrpBoard, idx) + HTML.UsrpBoard[idx]=UsrpBoard SSH.command('lscpu', '\$', 5) result = re.search('CPU\(s\): *(?P[0-9]+).*Model name: *(?P[a-zA-Z0-9\-\_\.\ \(\)]+).*CPU MHz: *(?P[0-9\.]+)', SSH.getBefore()) if result is not None: CpuNb = result.group('nb_cpus') logging.debug('nb_cpus: ' + CpuNb) - HTML.SetCpuNb(CpuNb, idx) + HTML.CpuNb[idx]=CpuNb CpuModel = result.group('model') logging.debug('model: ' + CpuModel) - HTML.SetCpuModel(CpuModel, idx) + HTML.CpuModel[idx]=CpuModel CpuMHz = result.group('cpu_mhz') + ' MHz' logging.debug('cpu_mhz: ' + CpuMHz) - HTML.SetCpuMHz(CpuMHz, idx) + HTML.CpuMHz[idx]=CpuMHz SSH.close() #----------------------------------------------------------- @@ -3267,7 +3267,7 @@ EPC = epc.EPCManagement() RAN = ran.RANManagement() HTML = html.HTMLManagement() -EPC.SetHtmlObj(HTML) +EPC.HtmlObj=HTML RAN.HtmlObj=HTML RAN.EpcObj=EPC @@ -3294,7 +3294,7 @@ while len(argvs) > 1: matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) CiTestObj.ranRepository = matchReg.group(1) RAN.ranRepository=matchReg.group(1) - HTML.SetranRepository(matchReg.group(1)) + HTML.ranRepository=matchReg.group(1) ldpc.ranRepository=matchReg.group(1) elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): @@ -3306,7 +3306,7 @@ while len(argvs) > 1: if ((doMerge == 'true') or (doMerge == 'True')): CiTestObj.ranAllowMerge = True RAN.ranAllowMerge=True - HTML.SetranAllowMerge(True) + HTML.ranAllowMerge=True elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) @@ -3314,7 +3314,7 @@ while len(argvs) > 1: matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) CiTestObj.ranBranch = matchReg.group(1) RAN.ranBranch=matchReg.group(1) - HTML.SetranBranch(matchReg.group(1)) + HTML.ranBranch=matchReg.group(1) ldpc.ranBranch=matchReg.group(1) elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): @@ -3323,7 +3323,7 @@ while len(argvs) > 1: matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) CiTestObj.ranCommitID = matchReg.group(1) RAN.ranCommitID=matchReg.group(1) - HTML.SetranCommitID(matchReg.group(1)) + HTML.ranCommitID=matchReg.group(1) ldpc.ranCommitID=matchReg.group(1) elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): @@ -3332,7 +3332,7 @@ while len(argvs) > 1: matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) CiTestObj.ranTargetBranch = matchReg.group(1) RAN.ranTargetBranch=matchReg.group(1) - HTML.SetranTargetBranch(matchReg.group(1)) + HTML.ranTargetBranch=matchReg.group(1) ldpc.ranTargetBranch=matchReg.group(1) elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): @@ -3380,25 +3380,25 @@ while len(argvs) > 1: RAN.eNB2SourceCodePath=matchReg.group(1) elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) - EPC.SetIPAddress(matchReg.group(1)) + EPC.IPAddress=matchReg.group(1) elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) - EPC.SetUserName(matchReg.group(1)) + EPC.UserName=matchReg.group(1) elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) - EPC.SetPassword(matchReg.group(1)) + EPC.Password=matchReg.group(1) elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - EPC.SetSourceCodePath(matchReg.group(1)) + EPC.SourceCodePath=matchReg.group(1) elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE): - EPC.SetType(matchReg.group(1)) + EPC.Type=matchReg.group(1) else: sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)') elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE) - EPC.SetContainerPrefix(matchReg.group(1)) + EPC.ContainerPrefix=matchReg.group(1) elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) CiTestObj.ADBIPAddress = matchReg.group(1) @@ -3420,8 +3420,8 @@ while len(argvs) > 1: elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) CiTestObj.testXMLfiles.append(matchReg.group(1)) - HTML.SettestXMLfiles(matchReg.group(1)) - HTML.SetnbTestXMLfiles(HTML.GetnbTestXMLfiles()+1) + HTML.testXMLfiles=matchReg.group(1) + HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1 elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) CiTestObj.UEIPAddress = matchReg.group(1) @@ -3464,17 +3464,17 @@ elif re.match('^TerminateOAIUE$', mode, re.IGNORECASE): signal.signal(signal.SIGUSR1, receive_signal) CiTestObj.TerminateOAIUE() elif re.match('^TerminateHSS$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') EPC.TerminateHSS() elif re.match('^TerminateMME$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') EPC.TerminateMME() elif re.match('^TerminateSPGW$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath== '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') EPC.TerminateSPGW() @@ -3489,27 +3489,27 @@ elif re.match('^LogCollecteNB$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') RAN.LogCollecteNB() elif re.match('^LogCollectHSS$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') EPC.LogCollectHSS() elif re.match('^LogCollectMME$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') EPC.LogCollectMME() elif re.match('^LogCollectSPGW$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetType() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') EPC.LogCollectSPGW() elif re.match('^LogCollectPing$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') CiTestObj.LogCollectPing() elif re.match('^LogCollectIperf$', mode, re.IGNORECASE): - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '': + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') CiTestObj.LogCollectIperf() @@ -3533,21 +3533,21 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE): except: print("Error while parsing file: " + xml_test_file) xmlRoot = xmlTree.getroot() - HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) - HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='test-tab-' + str(count))) - HTML.SethtmlTabIcons(xmlRoot.findtext('htmlTabIcon',default='info-sign')) + HTML.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-' + str(count))) + HTML.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='test-tab-' + str(count))) + HTML.htmlTabIcons.append(xmlRoot.findtext('htmlTabIcon',default='info-sign')) foundCount += 1 count += 1 - if foundCount != HTML.GetnbTestXMLfiles(): - HTML.SetnbTestXMLfiles(foundCount) + if foundCount != HTML.nbTestXMLfiles: + HTML.nbTestXMLfiles=foundCount if (CiTestObj.ADBIPAddress != 'none'): terminate_ue_flag = False CiTestObj.GetAllUEDevices(terminate_ue_flag) CiTestObj.GetAllCatMDevices(terminate_ue_flag) HTML.SethtmlUEConnected(len(CiTestObj.UEDevices) + len(CiTestObj.CatMDevices)) - HTML.SethtmlNb_Smartphones(len(CiTestObj.UEDevices)) - HTML.SethtmlNb_CATM_Modules(len(CiTestObj.CatMDevices)) + HTML.htmlNb_Smartphones=len(CiTestObj.UEDevices) + HTML.htmlNb_CATM_Modules=len(CiTestObj.CatMDevices) HTML.CreateHtmlHeader(CiTestObj.ADBIPAddress) elif re.match('^FinalizeHtml$', mode, re.IGNORECASE): logging.debug('\u001B[1m----------------------------------------\u001B[0m') @@ -3561,17 +3561,17 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re if re.match('^TesteNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.ranRepository == '' or RAN.ranBranch == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '' or EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.Type == '' or EPC.SourceCodePath == '' or CiTestObj.ADBIPAddress == '' or CiTestObj.ADBUserName == '' or CiTestObj.ADBPassword == '': HELP.GenericHelp(CONST.Version) - if EPC.GetIPAddress() == '' or EPC.GetUserName() == '' or EPC.GetPassword() == '' or EPC.GetSourceCodePath() == '' or EPC.GetType() == '': - HELP.EPCSrvHelp(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), EPC.GetSourceCodePath(), EPC.GetType()) + if EPC.IPAddress == '' or EPC.UserName == '' or EPC.Password == '' or EPC.SourceCodePath == '' or EPC.Type == '': + HELP.EPCSrvHelp(EPC.IPAddress, EPC.UserName, EPC.Password, EPC.SourceCodePath, EPC.Type) if RAN.ranRepository == '': HELP.GitSrvHelp(RAN.ranRepository, RAN.ranBranch, RAN.ranCommitID, RAN.ranAllowMerge, RAN.ranTargetBranch) if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '' or RAN.eNBSourceCodePath == '': HELP.eNBSrvHelp(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath) sys.exit('Insufficient Parameter') - if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'): - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/tcp_iperf_stats.awk", "/tmp") - SSH.copyout(EPC.GetIPAddress(), EPC.GetUserName(), EPC.GetPassword(), cwd + "/active_net_interfaces.awk", "/tmp") + if (EPC.IPAddress!= '') and (EPC.IPAddress != 'none'): + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, cwd + "/tcp_iperf_stats.awk", "/tmp") + SSH.copyout(EPC.IPAddress, EPC.UserName, EPC.Password, cwd + "/active_net_interfaces.awk", "/tmp") else: if CiTestObj.UEIPAddress == '' or CiTestObj.ranRepository == '' or CiTestObj.ranBranch == '' or CiTestObj.UEUserName == '' or CiTestObj.UEPassword == '' or CiTestObj.UESourceCodePath == '': HELP.GenericHelp(CONST.Version) @@ -3579,7 +3579,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re #read test_case_list.xml file # if no parameters for XML file, use default value - if (HTML.GetnbTestXMLfiles() != 1): + if (HTML.nbTestXMLfiles != 1): xml_test_file = cwd + "/test_case_list.xml" else: xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[0] @@ -3589,9 +3589,9 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re exclusion_tests=xmlRoot.findtext('TestCaseExclusionList',default='') requested_tests=xmlRoot.findtext('TestCaseRequestedList',default='') - if (HTML.GetnbTestXMLfiles() == 1): - HTML.SethtmlTabRefs(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) - HTML.SethtmlTabNames(xmlRoot.findtext('htmlTabName',default='Test-0')) + if (HTML.nbTestXMLfiles == 1): + HTML.htmlTabRefs.append(xmlRoot.findtext('htmlTabRef',default='test-tab-0')) + HTML.htmlTabNames.append(xmlRoot.findtext('htmlTabName',default='Test-0')) repeatCount = xmlRoot.findtext('repeatCount',default='1') CiTestObj.repeatCounts.append(int(repeatCount)) all_tests=xmlRoot.findall('testCase') @@ -3619,7 +3619,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re else: logging.debug('ERROR: requested test is invalidly formatted: ' + test) sys.exit(1) - if (EPC.GetIPAddress() != '') and (EPC.GetIPAddress() != 'none'): + if (EPC.IPAddress != '') and (EPC.IPAddress != 'none'): CiTestObj.CheckFlexranCtrlInstallation() EPC.SetMmeIPAddress() @@ -3645,7 +3645,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re CiTestObj.FailReportCnt = 0 RAN.prematureExit=True - HTML.SetstartTime(int(round(time.time() * 1000))) + HTML.startTime=int(round(time.time() * 1000)) while CiTestObj.FailReportCnt < CiTestObj.repeatCounts[0] and RAN.prematureExit: RAN.prematureExit=False # At every iteratin of the retry loop, a separator will be added @@ -3661,10 +3661,10 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re if test_case_id != id: continue CiTestObj.testCase_id = id - HTML.SettestCase_id(CiTestObj.testCase_id) - EPC.SetTestCase_id(CiTestObj.testCase_id) + HTML.testCase_id=CiTestObj.testCase_id + EPC.testCase_id=CiTestObj.testCase_id CiTestObj.desc = test.findtext('desc') - HTML.Setdesc(CiTestObj.desc) + HTML.desc=CiTestObj.desc action = test.findtext('class') if (CheckClassValidity(action, id) == False): continue diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 32f21fe2f7..5673b4c082 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -92,143 +92,143 @@ class RANManagement(): self.epcObj = None -""" + #----------------------------------------------------------- # Setters and Getters on Public members #----------------------------------------------------------- - def SetHtmlObj(self, obj): - self.htmlObj = obj - def SetEpcObj(self, obj): - self.epcObj = obj +# def SetHtmlObj(self, obj): +# self.htmlObj = obj +# def SetEpcObj(self, obj): +# self.epcObj = obj +# +# def SetflexranCtrlInstalled(self,fxrctin): +# self.flexranCtrlInstalled = fxrctin +# def GetflexranCtrlInstalled(self): +# return self.flexranCtrlInstalled +# def SetflexranCtrlStarted(self,fxrctst): +# self.flexranCtrlStarted = fxrctst +# def GetflexranCtrlStarted(self): +# return self.flexranCtrlStarted +# def SetpStatus(self, pSt): +# self.pStatus = pSt +# def SetranRepository(self, repository): +# self.ranRepository = repository +# def GetranRepository(self): +# return self.ranRepository +# def SetranBranch(self, branch): +# self.ranBranch = branch +# def GetranBranch(self): +# return self.ranBranch +# def SetranCommitID(self, commitid): +# self.ranCommitID = commitid +# def GetranCommitID(self): +# return self.ranCommitID +# def SeteNB_serverId(self, enbsrvid): +# self.eNB_serverId = enbsrvid +# def GeteNB_serverId(self): +# return self.eNB_serverId +# def SeteNBIPAddress(self, enbip): +# self.eNBIPAddress = enbip +# def GeteNBIPAddress(self): +# return self.eNBIPAddress +# def SeteNBUserName(self, enbusr): +# self.eNBUserName = enbusr +# def GeteNBUserName(self): +# return self.eNBUserName +# def SeteNBPassword(self, enbpw): +# self.eNBPassword = enbpw +# def GeteNBPassword(self): +# return self.eNBPassword +# def SeteNBSourceCodePath(self, enbcodepath): +# self.eNBSourceCodePath = enbcodepath +# def GeteNBSourceCodePath(self): +# return self.eNBSourceCodePath +# def SetranAllowMerge(self, merge): +# self.ranAllowMerge = merge +# def GetranAllowMerge(self): +# return self.ranAllowMerge +# def SetranTargetBranch(self, tbranch): +# self.ranTargetBranch = tbranch +# def GetranTargetBranch(self): +# return self.ranTargetBranch +# def SetBuild_eNB_args(self, enbbuildarg): +# self.Build_eNB_args = enbbuildarg +# def GetBuild_eNB_args(self): +# return self.Build_eNB_args +# def SetInitialize_eNB_args(self, initenbarg): +# self.Initialize_eNB_args = initenbarg +# def GetInitialize_eNB_args(self): +# return self.Initialize_eNB_args +# def SetbackgroundBuild(self, bkbuild): +# self.backgroundBuild = bkbuild +# def GetbackgroundBuild(self): +# return self.backgroundBuild +# def SetbackgroundBuildTestId(self, bkbuildid): +# self.backgroundBuildTestId = bkbuildid +# def GetbackgroundBuildTestId(self): +# return self.backgroundBuildTestId +# def SetBuild_eNB_forced_workspace_cleanup(self, fcdwspclean): +# self.Build_eNB_forced_workspace_cleanup = fcdwspclean +# def GetBuild_eNB_forced_workspace_cleanup(self): +# return self.Build_eNB_forced_workspace_cleanup +# def Setair_interface(self, airif): +# self.air_interface = airif +# def Getair_interface(self): +# return self.air_interface +# def SeteNB_instance(self, enbinst): +# self.eNB_instance = enbinst +# def GeteNB_instance(self): +# return self.eNB_instance +# +# def SeteNBLogFile(self, enblog, idx): +# self.eNBLogFiles[idx] = enblog +# def GeteNBLogFile(self, idx): +# return self.eNBLogFiles[idx] +# +# def GeteNBmbmsEnable(self, idx): +# return self.eNBmbmsEnables[idx] +# +# def SeteNB1IPAddress(self,enb1ip): +# self.eNB1IPAddress = enb1ip +# def GeteNB1IPAddress(self): +# return self.eNB1IPAddress +# def SeteNB1UserName(self, enb1usr): +# self.eNB1UserName = enb1usr +# def GeteNB1UserName(self): +# return self.eNB1UserName +# def SeteNB1Password(self, enb1pw): +# self.eNB1Password = enb1pw +# def GeteNB1Password(self): +# return self.eNB1Password +# def SeteNB1SourceCodePath(self, enb1codepath): +# self.eNB1SourceCodePath = enb1codepath +# def GeteNB1SourceCodePath(self): +# return self.eNB1SourceCodePath +# +# def SeteNB2IPAddress(self, enb2ip): +# self.eNB2IPAddress = enb2ip +# def GeteNB2IPAddress(self): +# return self.eNB2IPAddress +# def SeteNB2UserName(self, enb2usr): +# self.eNB2UserName = enb2usr +# def GeteNB2UserName(self): +# return self.eNB2UserName +# def SeteNB2Password(self, enb2pw): +# self.eNB2Password = enb2pw +# def GeteNB2Password(self): +# return self.eNB2Password +# def SeteNB2SourceCodePath(self, enb2codepath): +# self.eNB2SourceCodePath = enb2codepath +# def GeteNB2SourceCodePath(self): +# return self.eNB2SourceCodePath +# +# def SetprematureExit(self, premex): +# self.prematureExit = premex +# def GetprematureExit(self): +# return self.prematureExit - def SetflexranCtrlInstalled(self,fxrctin): - self.flexranCtrlInstalled = fxrctin - def GetflexranCtrlInstalled(self): - return self.flexranCtrlInstalled - def SetflexranCtrlStarted(self,fxrctst): - self.flexranCtrlStarted = fxrctst - def GetflexranCtrlStarted(self): - return self.flexranCtrlStarted - def SetpStatus(self, pSt): - self.pStatus = pSt - def SetranRepository(self, repository): - self.ranRepository = repository - def GetranRepository(self): - return self.ranRepository - def SetranBranch(self, branch): - self.ranBranch = branch - def GetranBranch(self): - return self.ranBranch - def SetranCommitID(self, commitid): - self.ranCommitID = commitid - def GetranCommitID(self): - return self.ranCommitID - def SeteNB_serverId(self, enbsrvid): - self.eNB_serverId = enbsrvid - def GeteNB_serverId(self): - return self.eNB_serverId - def SeteNBIPAddress(self, enbip): - self.eNBIPAddress = enbip - def GeteNBIPAddress(self): - return self.eNBIPAddress - def SeteNBUserName(self, enbusr): - self.eNBUserName = enbusr - def GeteNBUserName(self): - return self.eNBUserName - def SeteNBPassword(self, enbpw): - self.eNBPassword = enbpw - def GeteNBPassword(self): - return self.eNBPassword - def SeteNBSourceCodePath(self, enbcodepath): - self.eNBSourceCodePath = enbcodepath - def GeteNBSourceCodePath(self): - return self.eNBSourceCodePath - def SetranAllowMerge(self, merge): - self.ranAllowMerge = merge - def GetranAllowMerge(self): - return self.ranAllowMerge - def SetranTargetBranch(self, tbranch): - self.ranTargetBranch = tbranch - def GetranTargetBranch(self): - return self.ranTargetBranch - def SetBuild_eNB_args(self, enbbuildarg): - self.Build_eNB_args = enbbuildarg - def GetBuild_eNB_args(self): - return self.Build_eNB_args - def SetInitialize_eNB_args(self, initenbarg): - self.Initialize_eNB_args = initenbarg - def GetInitialize_eNB_args(self): - return self.Initialize_eNB_args - def SetbackgroundBuild(self, bkbuild): - self.backgroundBuild = bkbuild - def GetbackgroundBuild(self): - return self.backgroundBuild - def SetbackgroundBuildTestId(self, bkbuildid): - self.backgroundBuildTestId = bkbuildid - def GetbackgroundBuildTestId(self): - return self.backgroundBuildTestId - def SetBuild_eNB_forced_workspace_cleanup(self, fcdwspclean): - self.Build_eNB_forced_workspace_cleanup = fcdwspclean - def GetBuild_eNB_forced_workspace_cleanup(self): - return self.Build_eNB_forced_workspace_cleanup - def Setair_interface(self, airif): - self.air_interface = airif - def Getair_interface(self): - return self.air_interface - def SeteNB_instance(self, enbinst): - self.eNB_instance = enbinst - def GeteNB_instance(self): - return self.eNB_instance - def SeteNBLogFile(self, enblog, idx): - self.eNBLogFiles[idx] = enblog - def GeteNBLogFile(self, idx): - return self.eNBLogFiles[idx] - - def GeteNBmbmsEnable(self, idx): - return self.eNBmbmsEnables[idx] - - def SeteNB1IPAddress(self,enb1ip): - self.eNB1IPAddress = enb1ip - def GeteNB1IPAddress(self): - return self.eNB1IPAddress - def SeteNB1UserName(self, enb1usr): - self.eNB1UserName = enb1usr - def GeteNB1UserName(self): - return self.eNB1UserName - def SeteNB1Password(self, enb1pw): - self.eNB1Password = enb1pw - def GeteNB1Password(self): - return self.eNB1Password - def SeteNB1SourceCodePath(self, enb1codepath): - self.eNB1SourceCodePath = enb1codepath - def GeteNB1SourceCodePath(self): - return self.eNB1SourceCodePath - - def SeteNB2IPAddress(self, enb2ip): - self.eNB2IPAddress = enb2ip - def GeteNB2IPAddress(self): - return self.eNB2IPAddress - def SeteNB2UserName(self, enb2usr): - self.eNB2UserName = enb2usr - def GeteNB2UserName(self): - return self.eNB2UserName - def SeteNB2Password(self, enb2pw): - self.eNB2Password = enb2pw - def GeteNB2Password(self): - return self.eNB2Password - def SeteNB2SourceCodePath(self, enb2codepath): - self.eNB2SourceCodePath = enb2codepath - def GeteNB2SourceCodePath(self): - return self.eNB2SourceCodePath - - def SetprematureExit(self, premex): - self.prematureExit = premex - def GetprematureExit(self): - return self.prematureExit - -""" #----------------------------------------------------------- # RAN management functions From bbca88ad78906d732fb067875f0a2787752488b4 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 15:42:13 +0200 Subject: [PATCH 065/171] Bugfix FlexRAN: if a UE is in RRC but not S1AP, treat as no bug --- openair2/ENB_APP/flexran_agent_ran_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 32cb8c74e1..abade20846 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3644,7 +3644,7 @@ int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_con RB_FOREACH(ue, s1ap_ue_map, &s1ap->s1ap_ue_head){ if (ue->eNB_ue_s1ap_id == enb_ue_s1ap_id) break; } - if (ue == NULL) return -1; + if (!ue) return 0; // UE does not exist: it might be connected but CN did not answer if (ue->mme_ref->mme_s1_ip.ipv4) ue_conf->mme_s1_ip = (char*) &ue->mme_ref->mme_s1_ip.ipv4_address[0]; From 40fdd53adcaf2dc61c2cc34991bea7074c7a114d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 15 Apr 2020 21:25:42 +0200 Subject: [PATCH 066/171] Correctly decode IMSI also when not integrity protected --- openair2/RRC/LTE/rrc_eNB_S1AP.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB_S1AP.c b/openair2/RRC/LTE/rrc_eNB_S1AP.c index 27a442ed05..9f92be366b 100644 --- a/openair2/RRC/LTE/rrc_eNB_S1AP.c +++ b/openair2/RRC/LTE/rrc_eNB_S1AP.c @@ -96,36 +96,34 @@ void extract_imsi(uint8_t *pdu_buf, uint32_t pdu_len, rrc_eNB_ue_context_t *ue_c && pdu_len > NAS_MESSAGE_SECURITY_HEADER_SIZE)) return; + /* Decode plain NAS message */ + EMM_msg *e_msg = &nas_msg.plain.emm; + emm_msg_header_t *emm_header = &e_msg->header; + if (header->security_header_type != SECURITY_HEADER_TYPE_NOT_PROTECTED) { /* Decode the message authentication code */ DECODE_U32((char *) pdu_buf+size, header->message_authentication_code, size); /* Decode the sequence number */ DECODE_U8((char *) pdu_buf+size, header->sequence_number, size); - } + /* Decode the security header type and the protocol discriminator */ + DECODE_U8(pdu_buf + size, *(uint8_t *)(emm_header), size); - /* Note: the value of the pointer (i.e. the address) is given by value, so we - * can modify it as we want. The callee retains the original address! */ + /* Check that this is the right message */ + if (emm_header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) + return; + } pdu_buf += size; pdu_len -= size; - /* Decode plain NAS message */ - EMM_msg *e_msg = &nas_msg.plain.emm; - emm_msg_header_t *emm_header = &e_msg->header; - /* First decode the EMM message header */ - int e_head_size = 0; /* Check that buffer contains more than only the header */ if (pdu_len <= sizeof(emm_msg_header_t)) return; - /* Decode the security header type and the protocol discriminator */ - DECODE_U8(pdu_buf + e_head_size, *(uint8_t *)(emm_header), e_head_size); + /* First decode the EMM message header */ + int e_head_size = 0; /* Decode the message type */ DECODE_U8(pdu_buf + e_head_size, emm_header->message_type, e_head_size); - /* Check that this is the right message */ - if (emm_header->protocol_discriminator != EPS_MOBILITY_MANAGEMENT_MESSAGE) - return; - pdu_buf += e_head_size; pdu_len -= e_head_size; From 64f0b7e0e53094279ef87f20941fa11513fbf9eb Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 00:20:24 +0200 Subject: [PATCH 067/171] Do not check for register_enb_pending The test seemingly ensures that this code block is hit only once. However, if we enable later activation of MMEs, it will be hit a second (and third, ...) time. The only thing in guards against, though, is an INIT message to the L1L2 thread, when register_enb_pending == 0, which should only be sent once. Therefore, functionality won't be changed if register_enb_pending becomes negative, and the assert can be removed. --- openair2/ENB_APP/enb_app.c | 1 - 1 file changed, 1 deletion(-) diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c index 0e1c7e64bc..7c91e57813 100644 --- a/openair2/ENB_APP/enb_app.c +++ b/openair2/ENB_APP/enb_app.c @@ -273,7 +273,6 @@ void *eNB_app_task(void *args_p) { if (EPC_MODE_ENABLED) { LOG_I(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, ITTI_MSG_NAME (msg_p), S1AP_REGISTER_ENB_CNF(msg_p).nb_mme); - DevAssert(register_enb_pending > 0); register_enb_pending--; /* Check if at least eNB is registered with one MME */ From d47c539ddae4cd28d0a3254f67651b62565e7039 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 00:23:40 +0200 Subject: [PATCH 068/171] S1AP: Only register MME if we do not know it yet --- openair3/S1AP/s1ap_eNB.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c228034245..c703501847 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -220,8 +220,21 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * /* Trying to connect to provided list of MME ip address */ for (index = 0; index < s1ap_register_eNB->nb_mme; index++) { + net_ip_address_t *mme_ip = &s1ap_register_eNB->mme_ip_address[index]; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &new_instance->s1ap_mme_head) { + /* Compare whether IPv4 and IPv6 information is already present, in which + * wase we do not register again */ + if (mme->mme_s1_ip.ipv4 == mme_ip->ipv4 && (!mme_ip->ipv4 + || strncmp(mme->mme_s1_ip.ipv4_address, mme_ip->ipv4_address, 16) == 0) + && mme->mme_s1_ip.ipv6 == mme_ip->ipv6 && (!mme_ip->ipv6 + || strncmp(mme->mme_s1_ip.ipv6_address, mme_ip->ipv6_address, 46) == 0)) + break; + } + if (mme) + continue; s1ap_eNB_register_mme(new_instance, - &s1ap_register_eNB->mme_ip_address[index], + mme_ip, &s1ap_register_eNB->enb_ip_address, s1ap_register_eNB->sctp_in_streams, s1ap_register_eNB->sctp_out_streams, From e4eea33de6928ce5ad0c8fe40dba1f403f61f38d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 10 Apr 2020 23:17:36 +0200 Subject: [PATCH 069/171] FlexRAN: Enable MME adding/removing --- .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.c | 33 +++++++ .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.h | 5 + openair2/ENB_APP/flexran_agent_common.c | 47 +++++----- openair2/ENB_APP/flexran_agent_ran_api.c | 91 +++++++++++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 6 ++ 5 files changed, 160 insertions(+), 22 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c index 04a47406e1..d5fc5627a0 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c @@ -125,6 +125,39 @@ void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply) { } } +void flexran_agent_handle_mme_update(mid_t mod_id, + size_t n_mme, + Protocol__FlexS1apMme **mme) { + if (n_mme == 0 || n_mme > 1) { + LOG_E(FLEXRAN_AGENT, "cannot handle %lu MMEs yet\n", n_mme); + return; + } + + if (!mme[0]->s1_ip) { + LOG_E(FLEXRAN_AGENT, "no S1 IP present, cannot handle request\n"); + return; + } + + if (mme[0]->has_state + && mme[0]->state == PROTOCOL__FLEX_MME_STATE__FLMMES_DISCONNECTED) { + int rc = flexran_remove_s1ap_mme(mod_id, 1, &mme[0]->s1_ip); + if (rc == 0) + LOG_I(FLEXRAN_AGENT, "remove MME at IP %s\n", mme[0]->s1_ip); + else + LOG_W(FLEXRAN_AGENT, + "could not remove MME: flexran_remove_s1ap_mme() returned %d\n", + rc); + } else { + int rc = flexran_add_s1ap_mme(mod_id, 1, &mme[0]->s1_ip); + if (rc == 0) + LOG_I(FLEXRAN_AGENT, "add MME at IP %s\n", mme[0]->s1_ip); + else + LOG_W(FLEXRAN_AGENT, + "could not add MME: flexran_add_s1ap_mme() returned %d\n", + rc); + } +} + int flexran_agent_register_s1ap_xface(mid_t mod_id) { if (agent_s1ap_xface[mod_id]) { LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h index 1cca6ac9c1..54ea2926a8 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h @@ -60,6 +60,11 @@ int flexran_agent_s1ap_stats_reply(mid_t mod_id, /* Free allocated S1AP stats message */ void flexran_agent_s1ap_destroy_stats_reply(Protocol__FlexStatsReply *reply); +/* Add or remove MME updates */ +void flexran_agent_handle_mme_update(mid_t mod_id, + size_t n_mme, + Protocol__FlexS1apMme **mme); + /* Register technology specific interface callbacks */ int flexran_agent_register_s1ap_xface(mid_t mod_id); diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index dc320ef974..ec0b780a3a 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -893,31 +893,34 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot Protocol__FlexranMessage *input = (Protocol__FlexranMessage *)params; Protocol__FlexEnbConfigReply *enb_config = input->enb_config_reply_msg; - if (enb_config->n_cell_config == 0) { - LOG_W(FLEXRAN_AGENT, - "received enb_config_reply message does not contain a cell_config\n"); - *msg = NULL; - return 0; - } - if (enb_config->n_cell_config > 1) LOG_W(FLEXRAN_AGENT, "ignoring slice configs for other cell except cell 0\n"); - if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { - prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); - } else if (enb_config->cell_config[0]->has_eutra_band - && enb_config->cell_config[0]->has_dl_freq - && enb_config->cell_config[0]->has_ul_freq - && enb_config->cell_config[0]->has_dl_bandwidth) { - initiate_soft_restart(mod_id, enb_config->cell_config[0]); - } else if (flexran_agent_get_rrc_xface(mod_id) - && enb_config->cell_config[0]->has_x2_ho_net_control) { - LOG_I(FLEXRAN_AGENT, - "setting X2 HO NetControl to %d\n", - enb_config->cell_config[0]->x2_ho_net_control); - const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control); - if (rc < 0) - LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network"); + if (enb_config->n_cell_config > 0) { + if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { + prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); + } + if (enb_config->cell_config[0]->has_eutra_band + && enb_config->cell_config[0]->has_dl_freq + && enb_config->cell_config[0]->has_ul_freq + && enb_config->cell_config[0]->has_dl_bandwidth) { + initiate_soft_restart(mod_id, enb_config->cell_config[0]); + } + if (flexran_agent_get_rrc_xface(mod_id) + && enb_config->cell_config[0]->has_x2_ho_net_control) { + LOG_I(FLEXRAN_AGENT, + "setting X2 HO NetControl to %d\n", + enb_config->cell_config[0]->x2_ho_net_control); + const int rc = flexran_set_x2_ho_net_control(mod_id, enb_config->cell_config[0]->x2_ho_net_control); + if (rc < 0) + LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network"); + } + } + + if (flexran_agent_get_s1ap_xface(mod_id) && enb_config->s1ap) { + flexran_agent_handle_mme_update(mod_id, + enb_config->s1ap->n_mme, + enb_config->s1ap->mme); } *msg = NULL; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index abade20846..3306dfe61b 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3634,6 +3634,97 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM return 0; } +int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + if (!rrc_is_present(mod_id)) return -2; + + /* Reconstruct S1AP_REGISTER_ENB_REQ */ + MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, S1AP_REGISTER_ENB_REQ); + RCconfig_S1(m, mod_id); + + const int CC_id = 0; + eNB_RRC_INST *rrc = RC.rrc[CC_id]; + RrcConfigurationReq *conf = &rrc->configuration; + S1AP_REGISTER_ENB_REQ(m).num_plmn = conf->num_plmn; + for (int i = 0; i < conf->num_plmn; ++i) { + S1AP_REGISTER_ENB_REQ(m).mcc[i] = conf->mcc[i]; + S1AP_REGISTER_ENB_REQ(m).mnc[i] = conf->mnc[i]; + S1AP_REGISTER_ENB_REQ(m).mnc_digit_length[i] = conf->mnc_digit_length[i]; + } + + /* reconstruct MME list, it might have been updated since initial + * configuration */ + S1AP_REGISTER_ENB_REQ(m).nb_mme = 0; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { + const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = mme->mme_s1_ip.ipv4; + strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme->mme_s1_ip.ipv4_address); + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = mme->mme_s1_ip.ipv6; + strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6_address, mme->mme_s1_ip.ipv6_address); + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = mme->broadcast_plmn_num; + for (int i = 0; i < mme->broadcast_plmn_num; ++i) + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = mme->broadcast_plmn_index[i]; + S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; + } + + if (S1AP_REGISTER_ENB_REQ(m).nb_mme + n_mme > S1AP_MAX_NB_MME_IP_ADDRESS) + return -1; + + for (int i = 0; i < n_mme; ++i) { + const int n = S1AP_REGISTER_ENB_REQ(m).nb_mme; + strcpy(S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4_address, mme_ipv4[0]); + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv4 = 1; + S1AP_REGISTER_ENB_REQ(m).mme_ip_address[n].ipv6 = 0; + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_num[n] = S1AP_REGISTER_ENB_REQ(m).num_plmn; + for (int i = 0; i < S1AP_REGISTER_ENB_REQ(m).num_plmn; ++i) + S1AP_REGISTER_ENB_REQ(m).broadcast_plmn_index[n][i] = i; + S1AP_REGISTER_ENB_REQ(m).nb_mme += 1; + } + + itti_send_msg_to_task (TASK_S1AP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); + + return 0; +} + +int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) return -1; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { + if (mme->mme_s1_ip.ipv4 + && strncmp(mme->mme_s1_ip.ipv4_address, mme_ipv4[0], 16) == 0) + break; + } + if (!mme) + return -2; + + MessageDef *m = itti_alloc_new_message(TASK_FLEXRAN_AGENT, SCTP_CLOSE_ASSOCIATION); + SCTP_CLOSE_ASSOCIATION(m).assoc_id = mme->assoc_id; + itti_send_msg_to_task (TASK_SCTP, ENB_MODULE_ID_TO_INSTANCE(mod_id), m); + + switch (mme->state) { + case S1AP_ENB_STATE_WAITING: + s1ap->s1ap_mme_nb -= 1; + if (s1ap->s1ap_mme_pending_nb > 0) + s1ap->s1ap_mme_pending_nb -= 1; + break; + case S1AP_ENB_STATE_CONNECTED: + case S1AP_ENB_OVERLOAD: /* I am not sure the decrements are right here */ + s1ap->s1ap_mme_nb -= 1; + s1ap->s1ap_mme_associated_nb -= 1; + break; + case S1AP_ENB_STATE_DISCONNECTED: + default: + break; + } + RB_REMOVE(s1ap_mme_map, &s1ap->s1ap_mme_head, mme); + + return 0; +} + + int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){ if (!rrc_is_present(mod_id)) return -1; s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index ce32883852..3c2803d663 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -832,6 +832,12 @@ int flexran_get_s1ap_mme_conf(mid_t mod_id, mid_t mme_index, Protocol__FlexS1apM /* Get the S1AP UE conf */ int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf); +/* Add MMEs and re-issue S1AP Registration Request */ +int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); + +/* Remove MMEs and and cut SCTP to MME */ +int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); + /********************* general information *****************/ /* get an ID for this BS (or part of a BS) */ uint64_t flexran_get_bs_id(mid_t mod_id); From a1f77198f74701c07340f3f51e06cc830c834e60 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sat, 11 Apr 2020 13:40:50 +0200 Subject: [PATCH 070/171] FlexRAN: Manage PLMNs --- .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.c | 24 +++++++ .../CONTROL_MODULES/S1AP/flexran_agent_s1ap.h | 6 ++ openair2/ENB_APP/flexran_agent_common.c | 6 ++ openair2/ENB_APP/flexran_agent_ran_api.c | 71 +++++++++++++++++++ openair2/ENB_APP/flexran_agent_ran_api.h | 3 + 5 files changed, 110 insertions(+) diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c index d5fc5627a0..c2d7cb9e55 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.c @@ -158,6 +158,30 @@ void flexran_agent_handle_mme_update(mid_t mod_id, } } +void flexran_agent_handle_plmn_update(mid_t mod_id, + int CC_id, + size_t n_plmn, + Protocol__FlexPlmn **plmn_id) { + if (n_plmn < 1 || n_plmn > 6) { + LOG_E(FLEXRAN_AGENT, "cannot handle %lu PLMNs\n", n_plmn); + return; + } + + /* We assume the controller has checked all the parameters within each + * plmn_id */ + int rc = flexran_set_new_plmn_id(mod_id, CC_id, n_plmn, plmn_id); + if (rc == 0) { + LOG_I(FLEXRAN_AGENT, "set %lu new PLMNs:\n", n_plmn); + for (int i = 0; i < (int)n_plmn; ++i) + LOG_I(FLEXRAN_AGENT, " MCC %d MNC %d MNC length %d\n", + plmn_id[i]->mcc, plmn_id[i]->mnc, plmn_id[0]->mnc_length); + } else { + LOG_W(FLEXRAN_AGENT, + "could not set new PLMN configuration: flexran_set_new_plmn_id() returned %d\n", + rc); + } +} + int flexran_agent_register_s1ap_xface(mid_t mod_id) { if (agent_s1ap_xface[mod_id]) { LOG_E(FLEXRAN_AGENT, "S1AP agent CM for eNB %d is already registered\n", mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h index 54ea2926a8..006eaa1d3c 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h +++ b/openair2/ENB_APP/CONTROL_MODULES/S1AP/flexran_agent_s1ap.h @@ -65,6 +65,12 @@ void flexran_agent_handle_mme_update(mid_t mod_id, size_t n_mme, Protocol__FlexS1apMme **mme); +/* Set a new PLMN configuration */ +void flexran_agent_handle_plmn_update(mid_t mod_id, + int CC_id, + size_t n_plmn, + Protocol__FlexPlmn **plmn_id); + /* Register technology specific interface callbacks */ int flexran_agent_register_s1ap_xface(mid_t mod_id); diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index ec0b780a3a..e77b2fb386 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -915,6 +915,12 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (rc < 0) LOG_E(FLEXRAN_AGENT, "Error in configuring X2 handover controlled by network"); } + if (flexran_agent_get_rrc_xface(mod_id) && enb_config->cell_config[0]->n_plmn_id > 0) { + flexran_agent_handle_plmn_update(mod_id, + 0, + enb_config->cell_config[0]->n_plmn_id, + enb_config->cell_config[0]->plmn_id); + } } if (flexran_agent_get_s1ap_xface(mod_id) && enb_config->s1ap) { diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 3306dfe61b..0fcc51782e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3724,6 +3724,77 @@ int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4) { return 0; } +int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id) { + if (!rrc_is_present(mod_id)) + return -1; + s1ap_eNB_instance_t *s1ap = s1ap_eNB_get_instance(mod_id); + if (!s1ap) + return -2; + + eNB_RRC_INST *rrc = RC.rrc[CC_id]; + RrcConfigurationReq *conf = &rrc->configuration; + + uint8_t num_plmn_old = conf->num_plmn; + uint16_t mcc[PLMN_LIST_MAX_SIZE]; + uint16_t mnc[PLMN_LIST_MAX_SIZE]; + uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; + for (int i = 0; i < num_plmn_old; ++i) { + mcc[i] = conf->mcc[i]; + mnc[i] = conf->mnc[i]; + mnc_digit_length[i] = conf->mnc_digit_length[i]; + } + + conf->num_plmn = (uint8_t) n_plmn; + for (int i = 0; i < conf->num_plmn; ++i) { + conf->mcc[i] = plmn_id[i]->mcc; + conf->mnc[i] = plmn_id[i]->mnc; + conf->mnc_digit_length[i] = plmn_id[i]->mnc_length; + } + + rrc_eNB_carrier_data_t *carrier = &rrc->carrier[CC_id]; + extern uint8_t do_SIB1(rrc_eNB_carrier_data_t *carrier, + int Mod_id, + int CC_id, + BOOLEAN_t brOption, + RrcConfigurationReq *configuration); + carrier->sizeof_SIB1 = do_SIB1(carrier, mod_id, CC_id, FALSE, conf); + if (carrier->sizeof_SIB1 < 0) + return -1337; /* SIB1 encoding failed, hell will probably break loose */ + + s1ap->num_plmn = (uint8_t) n_plmn; + for (int i = 0; i < conf->num_plmn; ++i) { + s1ap->mcc[i] = plmn_id[i]->mcc; + s1ap->mnc[i] = plmn_id[i]->mnc; + s1ap->mnc_digit_length[i] = plmn_id[i]->mnc_length; + } + + int bpn_failed = 0; + struct s1ap_eNB_mme_data_s *mme = NULL; + RB_FOREACH(mme, s1ap_mme_map, &s1ap->s1ap_mme_head) { + for (int i = 0; i < mme->broadcast_plmn_num; ++i) { + /* search the new index and update. If we don't find, we count this using + * bpn_failed to now how many broadcast_plmns could not be updated */ + int idx = mme->broadcast_plmn_index[i]; + int omcc = mcc[idx]; + int omnc = mnc[idx]; + int omncl = mnc_digit_length[idx]; + int j = 0; + for (j = 0; j < s1ap->num_plmn; ++j) { + if (s1ap->mcc[j] == omcc + && s1ap->mnc[j] == omnc + && s1ap->mnc_digit_length[j] == omncl) { + mme->broadcast_plmn_index[i] = j; + break; + } + } + if (j == s1ap->num_plmn) /* could not find the old PLMN in the new ones */ + bpn_failed++; + } + } + if (bpn_failed > 0) + return -10000 - bpn_failed; + return 0; +} int flexran_get_s1ap_ue(mid_t mod_id, rnti_t rnti, Protocol__FlexS1apUe * ue_conf){ if (!rrc_is_present(mod_id)) return -1; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 3c2803d663..9d1bfb9d3e 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -838,6 +838,9 @@ int flexran_add_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); /* Remove MMEs and and cut SCTP to MME */ int flexran_remove_s1ap_mme(mid_t mod_id, size_t n_mme, char **mme_ipv4); +/* Set a new PLMN configuration */ +int flexran_set_new_plmn_id(mid_t mod_id, int CC_id, size_t n_plmn, Protocol__FlexPlmn **plmn_id); + /********************* general information *****************/ /* get an ID for this BS (or part of a BS) */ uint64_t flexran_get_bs_id(mid_t mod_id); From 332dec605ace8cfec771d3c578b335588563ac9e Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 14 Apr 2020 14:47:27 +0200 Subject: [PATCH 071/171] UE: Print all SIB1 decoded PLMNs --- openair2/RRC/LTE/rrc_UE.c | 65 +++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 4116f5367e..53348f5621 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -2794,44 +2794,43 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, LTE_SystemInformationBlockType1_t *sib1 = UE_rrc_inst[ctxt_pP->module_id].sib1[eNB_index]; VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1, VCD_FUNCTION_IN ); LOG_I( RRC, "[UE %d] : Dumping SIB 1\n", ctxt_pP->module_id ); - LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->plmn_Identity; - int mccdigits = PLMN_identity->mcc->list.count; - int mncdigits = PLMN_identity->mnc.list.count; - int mcc; + const int n = sib1->cellAccessRelatedInfo.plmn_IdentityList.list.count; + for (int i = 0; i < n; ++i) { + LTE_PLMN_Identity_t *PLMN_identity = &sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[i]->plmn_Identity; + int mccdigits = PLMN_identity->mcc->list.count; + int mncdigits = PLMN_identity->mnc.list.count; - if (mccdigits == 2) { - mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; - } else { - mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; + int mcc; + if (mccdigits == 2) { + mcc = *PLMN_identity->mcc->list.array[0]*10 + *PLMN_identity->mcc->list.array[1]; + } else { + mcc = *PLMN_identity->mcc->list.array[0]*100 + *PLMN_identity->mcc->list.array[1]*10 + *PLMN_identity->mcc->list.array[2]; + } + + int mnc; + if (mncdigits == 2) { + mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; + } else { + mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; + } + + LOG_I( RRC, "PLMN %d MCC %0*d, MNC %0*d\n", i + 1, mccdigits, mcc, mncdigits, mnc); + // search internal table for provider name + int plmn_ind = 0; + + while (plmn_data[plmn_ind].mcc > 0) { + if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { + LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); + break; + } + + plmn_ind++; + } } - - int mnc; - - if (mncdigits == 2) { - mnc = *PLMN_identity->mnc.list.array[0]*10 + *PLMN_identity->mnc.list.array[1]; - } else { - mnc = *PLMN_identity->mnc.list.array[0]*100 + *PLMN_identity->mnc.list.array[1]*10 + *PLMN_identity->mnc.list.array[2]; - } - - LOG_I( RRC, "PLMN MCC %0*d, MNC %0*d, TAC 0x%04x\n", mccdigits, mcc, mncdigits, mnc, + LOG_I( RRC, "TAC 0x%04x\n", ((sib1->cellAccessRelatedInfo.trackingAreaCode.size == 2)?((sib1->cellAccessRelatedInfo.trackingAreaCode.buf[0]<<8) + sib1->cellAccessRelatedInfo.trackingAreaCode.buf[1]):0)); LOG_I( RRC, "cellReservedForOperatorUse : raw:%ld decoded:%s\n", sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse, SIBreserved(sib1->cellAccessRelatedInfo.plmn_IdentityList.list.array[0]->cellReservedForOperatorUse) ); - // search internal table for provider name - int plmn_ind = 0; - - while (plmn_data[plmn_ind].mcc > 0) { - if ((plmn_data[plmn_ind].mcc == mcc) && (plmn_data[plmn_ind].mnc == mnc)) { - LOG_I( RRC, "Found %s (name from internal table)\n", plmn_data[plmn_ind].oper_short ); - break; - } - - plmn_ind++; - } - - if (plmn_data[plmn_ind].mcc < 0) { - LOG_I( RRC, "Found Unknown operator (no entry in internal table)\n" ); - } LOG_I( RRC, "cellAccessRelatedInfo.cellIdentity : raw:%"PRIu32" decoded:%02x.%02x.%02x.%02x\n", BIT_STRING_to_uint32( &sib1->cellAccessRelatedInfo.cellIdentity ), From 19c2856bbe0bf3400262085c1e8ef5dc05fbd1b7 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 14 Apr 2020 14:47:59 +0200 Subject: [PATCH 072/171] UE: Set correct selected PLMN Identity --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 4 ++-- openair2/RRC/LTE/MESSAGES/asn1_msg.h | 6 +++++- openair2/RRC/LTE/rrc_UE.c | 26 +++++++++++++++++++++----- openair2/RRC/LTE/rrc_defs.h | 1 + 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 583e10da94..9ede543003 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -2310,7 +2310,7 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_Destin return((enc_rval.encoded+7)/8); } -uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) { +uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, uint8_t sel_plmn_id, const int dedicatedInfoNASLength, const char *dedicatedInfoNAS) { asn_enc_rval_t enc_rval; LTE_UL_DCCH_Message_t ul_dcch_msg; LTE_RRCConnectionSetupComplete_t *rrcConnectionSetupComplete; @@ -2323,7 +2323,7 @@ uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uin rrcConnectionSetupComplete->criticalExtensions.choice.c1.present = LTE_RRCConnectionSetupComplete__criticalExtensions__c1_PR_rrcConnectionSetupComplete_r8; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension=CALLOC(1, sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.nonCriticalExtension)); - rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= 1; + rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.selectedPLMN_Identity= sel_plmn_id; rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME = NULL;//calloc(1,sizeof(*rrcConnectionSetupComplete->criticalExtensions.choice.c1.choice.rrcConnectionSetupComplete_r8.registeredMME)); /* diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.h b/openair2/RRC/LTE/MESSAGES/asn1_msg.h index dda2340610..640d18a61f 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.h +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.h @@ -142,7 +142,11 @@ uint8_t do_SidelinkUEInformation(uint8_t Mod_id, uint8_t *buffer, LTE_SL_Destina /** \brief Generate an RRCConnectionSetupComplete UL-DCCH-Message (UE) @param buffer Pointer to PER-encoded ASN.1 description of UL-DCCH-Message PDU @returns Size of encoded bit stream in bytes*/ -uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, uint8_t *buffer, const uint8_t Transaction_id, const int dedicatedInfoNASLength, +uint8_t do_RRCConnectionSetupComplete(uint8_t Mod_id, + uint8_t *buffer, + const uint8_t Transaction_id, + uint8_t sel_plmn_id, + const int dedicatedInfoNASLength, const char *dedicatedInfoNAS); /** \brief Generate an RRCConnectionReconfigurationComplete UL-DCCH-Message (UE) diff --git a/openair2/RRC/LTE/rrc_UE.c b/openair2/RRC/LTE/rrc_UE.c index 53348f5621..bdf992c76a 100644 --- a/openair2/RRC/LTE/rrc_UE.c +++ b/openair2/RRC/LTE/rrc_UE.c @@ -128,8 +128,13 @@ static int decode_SIB1_MBMS( const protocol_ctxt_t *const ctxt_pP, const uint8_t * \param ctxt_pP Running context * \param eNB_index Index of corresponding eNB/CH * \param Transaction_id Transaction identifier + * \param sel_plmn_id selected PLMN Identity */ -static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ); +static void rrc_ue_generate_RRCConnectionSetupComplete( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t eNB_index, + const uint8_t Transaction_id, + uint8_t sel_plmn_id); /** \brief Generates/Encodes RRCConnectionReconfigurationComplete message at UE * \param ctxt_pP Running context @@ -367,6 +372,7 @@ char openair_rrc_ue_init( const module_id_t ue_mod_idP, const unsigned char eNB_ rrc_set_state (ue_mod_idP, RRC_STATE_INACTIVE); rrc_set_sub_state (ue_mod_idP, RRC_SUB_STATE_INACTIVE); LOG_I(RRC,"[UE %d] INIT State = RRC_IDLE (eNB %d)\n",ctxt.module_id,eNB_index); + UE_rrc_inst[ctxt.module_id].selected_plmn_identity = 1; UE_rrc_inst[ctxt.module_id].Info[eNB_index].State=RRC_IDLE; UE_rrc_inst[ctxt.module_id].Info[eNB_index].T300_active = 0; UE_rrc_inst[ctxt.module_id].Info[eNB_index].T304_active = 0; @@ -490,7 +496,11 @@ rrc_t310_expiration( } //----------------------------------------------------------------------------- -static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, const uint8_t Transaction_id ) { +static void rrc_ue_generate_RRCConnectionSetupComplete( + const protocol_ctxt_t *const ctxt_pP, + const uint8_t eNB_index, + const uint8_t Transaction_id, + uint8_t sel_plmn_id) { uint8_t buffer[100]; uint8_t size; const char *nas_msg; @@ -504,7 +514,7 @@ static void rrc_ue_generate_RRCConnectionSetupComplete( const protocol_ctxt_t *c nas_msg_length = sizeof(nas_attach_req_imsi); } - size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, nas_msg_length, nas_msg); + size = do_RRCConnectionSetupComplete(ctxt_pP->module_id, buffer, Transaction_id, sel_plmn_id, nas_msg_length, nas_msg); LOG_I(RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCConnectionSetupComplete (bytes%d, eNB %d)\n", ctxt_pP->module_id,ctxt_pP->frame, size, eNB_index); LOG_D(RLC, @@ -624,7 +634,8 @@ int rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const SRB_INFO *co rrc_ue_generate_RRCConnectionSetupComplete( ctxt_pP, eNB_index, - dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier); + dl_ccch_msg->message.choice.c1.choice.rrcConnectionSetup.rrc_TransactionIdentifier, + UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); rval = 0; break; @@ -2969,6 +2980,7 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, NAS_CELL_SELECTION_CNF (msg_p).rsrp = rsrp; itti_send_msg_to_task(TASK_NAS_UE, ctxt_pP->instance, msg_p); cell_valid = 1; + UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity = plmn + 1; break; } } @@ -2979,7 +2991,11 @@ int decode_SIB1( const protocol_ctxt_t *const ctxt_pP, const uint8_t eNB_index, MessageDef *msg_p; msg_p = itti_alloc_new_message(TASK_RRC_UE, PHY_FIND_NEXT_CELL_REQ); itti_send_msg_to_task(TASK_PHY_UE, ctxt_pP->instance, msg_p); - LOG_E(RRC, "Synched with a cell, but PLMN doesn't match our SIM, the message PHY_FIND_NEXT_CELL_REQ is sent but lost in current UE implementation! \n"); + LOG_E(RRC, + "Synched with a cell, but PLMN doesn't match our SIM " + "(selected_plmn_identity %d), the message PHY_FIND_NEXT_CELL_REQ " + "is sent but lost in current UE implementation!\n", + UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity); } } diff --git a/openair2/RRC/LTE/rrc_defs.h b/openair2/RRC/LTE/rrc_defs.h index e366061674..3c02c45bc1 100644 --- a/openair2/RRC/LTE/rrc_defs.h +++ b/openair2/RRC/LTE/rrc_defs.h @@ -809,6 +809,7 @@ typedef struct UE_RRC_INST_s { Rrc_Sub_State_t RrcSubState; plmn_t plmnID; Byte_t rat; + uint8_t selected_plmn_identity; as_nas_info_t initialNasMsg; OAI_UECapability_t *UECap; uint8_t *UECapability; From a96c3761cc24101c1708b7bec465afa6dd553fed Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 21 May 2020 21:18:26 +0200 Subject: [PATCH 073/171] Log TBS in every window --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 7621994ab2..2382af3636 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -588,6 +588,7 @@ schedule_ue_spec(module_id_t module_idP, UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id]; eNB_UE_STATS *eNB_UE_stats = &UE_info->eNB_UE_stats[CC_id][UE_id]; + eNB_UE_stats->TBS = 0; const rnti_t rnti = ue_template->rnti; // If TDD @@ -799,6 +800,7 @@ schedule_ue_spec(module_id_t module_idP, eNB_UE_stats->rbs_used_retx = nb_rb; eNB_UE_stats->total_rbs_used_retx += nb_rb; eNB_UE_stats->dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1; + eNB_UE_stats->TBS = TBS; } else { // Now check RLC information to compute number of required RBs // get maximum TBS size for RLC request From d0baab6ed3ca0e618283620059faf28ae97ba832 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 12 Jun 2020 19:25:44 +0200 Subject: [PATCH 074/171] DLSCH: limit LC bytes according to preprocessor --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 2382af3636..c35af34a7f 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -844,13 +844,18 @@ schedule_ue_spec(module_id_t module_idP, if (ue_sched_ctrl->dl_lc_bytes[i] == 0) // no data in this LC! continue; - LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n", + const uint32_t data = + min(ue_sched_ctrl->dl_lc_bytes[i], + TBS - ta_len - header_length_total - sdu_length_total - 3); + LOG_D(MAC, + "[eNB %d] SFN/SF %d.%d, LC%d->DLSCH CC_id %d, Requesting %d " + "bytes from RLC (RRC message)\n", module_idP, frameP, subframeP, lcid, CC_id, - TBS - ta_len - header_length_total - sdu_length_total - 3); + data); sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, @@ -859,7 +864,7 @@ schedule_ue_spec(module_id_t module_idP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid, - TBS - ta_len - header_length_total - sdu_length_total - 3, + data, (char *)&dlsch_buffer[sdu_length_total], 0, 0 From 82194319cfca0ef23c5a838f8d517faf424ed147 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 24 Jun 2020 14:24:02 +0200 Subject: [PATCH 075/171] Bugfix DLSCH: only warn when retx with less RB The preprocessor pre-allocates a CCE. Thus, when arriving at the check for the number of RBs for retransmission, it is too late to skip the UE. Therefore, only print a warning. The default schedulers allocate a correct amount of RBs for retransmissions, therefore it is ok. --- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index c35af34a7f..783d4e8b1a 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -680,15 +680,15 @@ schedule_ue_spec(module_id_t module_idP, const uint32_t rbc = allocate_prbs_sub( nb_rb, N_RB_DL, N_RBG, ue_sched_ctrl->rballoc_sub_UE[CC_id]); - if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id]) { - LOG_D(MAC, - "[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n", + if (nb_rb > ue_sched_ctrl->pre_nb_available_rbs[CC_id]) + LOG_W(MAC, + "[eNB %d] %d.%d CC_id %d : should not schedule UE %d, its " + "retransmission takes more resources than we have\n", module_idP, frameP, + subframeP, CC_id, UE_id); - continue; - } /* CDRX */ ue_sched_ctrl->harq_rtt_timer[CC_id][harq_pid] = 1; // restart HARQ RTT timer From 864fa84ba80c99e831a7d9be5f88968a728a8efc Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 20 May 2020 12:45:35 +0200 Subject: [PATCH 076/171] Default SCHED RR algo: optimize algo and defer RB calc. - Loop only to next UE instead of jumping multiple - mark used RBGs in rbg_mask - Only calculate number of RBs based on CQI when UE is selected, instead of calculating for all UEs which might be unnecessary. - When looping the list of UEs for RB allocation, remove UEs that have no data anymore instead of skipping them. --- openair2/LAYER2/MAC/pre_processor.c | 72 ++++++++++------------------- 1 file changed, 25 insertions(+), 47 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 4f3baf1783..62b9e1c2cc 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -86,9 +86,6 @@ int round_robin_dl(module_id_t Mod_id, int num_ue_req = 0; UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; - int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request - memset(rb_required, 0, sizeof(rb_required)); - int rbg = 0; for (; !rbgalloc_mask[rbg]; rbg++) ; /* fast-forward to first allowed RBG */ @@ -133,6 +130,7 @@ int round_robin_dl(module_id_t Mod_id, if (!rbgalloc_mask[rbg]) continue; ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; nb_rbg--; } LOG_D(MAC, @@ -150,22 +148,8 @@ int round_robin_dl(module_id_t Mod_id, return n_rbg_sched; for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { - const int dlsch_mcs1 = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; - UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = dlsch_mcs1; - rb_required[UE_id] = - find_nb_rb_DL(dlsch_mcs1, - UE_info->UE_template[CC_id][UE_id].dl_buffer_total, - n_rbg_sched * RBGsize, - RBGsize); - if (rb_required[UE_id] > 0) + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) num_ue_req++; - LOG_D(MAC, - "%d/%d UE_id %d rb_required %d n_rbg_sched %d\n", - frame, - subframe, - UE_id, - rb_required[UE_id], - n_rbg_sched); } } @@ -178,12 +162,13 @@ int round_robin_dl(module_id_t Mod_id, g_start_ue_dl = UE_list->head; int UE_id = g_start_ue_dl; UE_list_t UE_sched; - int rb_required_total = 0; + int *cur_UE = &UE_sched.head; + int num_ue_sched = 0; max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); - int *cur_UE = &UE_sched.head; + int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request while (num_ue_sched < max_num_ue) { - while (rb_required[UE_id] == 0) + while (UE_info->UE_template[CC_id][UE_id].dl_buffer_total <= 0) UE_id = next_ue_list_looped(UE_list, UE_id); const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); @@ -195,42 +180,42 @@ int round_robin_dl(module_id_t Mod_id, continue; } UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; + const int mcs = cqi_to_mcs[cqi]; + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; + const uint32_t B = UE_info->UE_template[CC_id][UE_id].dl_buffer_total; + rb_required[UE_id] = find_nb_rb_DL(mcs, B, n_rbg_sched * RBGsize, RBGsize); *cur_UE = UE_id; cur_UE = &UE_sched.next[UE_id]; - rb_required_total += rb_required[UE_id]; num_ue_sched++; UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate } *cur_UE = -1; /* for one UE after the next: allocate resources */ - for (int UE_id = UE_sched.head; UE_id >= 0; - UE_id = next_ue_list_looped(&UE_sched, UE_id)) { - if (rb_required[UE_id] <= 0) - continue; + cur_UE = &UE_sched.head; + while (*cur_UE >= 0) { + const int UE_id = *cur_UE; UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize; ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG; rb_required[UE_id] -= sRBG; - rb_required_total -= sRBG; - if (rb_required_total <= 0) - break; + if (rb_required[UE_id] <= 0) { + *cur_UE = UE_sched.next[*cur_UE]; + if (*cur_UE < 0) + cur_UE = &UE_sched.head; + } else { + cur_UE = UE_sched.next[*cur_UE] < 0 ? &UE_sched.head : &UE_sched.next[*cur_UE]; + } n_rbg_sched--; if (n_rbg_sched <= 0) break; for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - /* if not all UEs could be allocated in this round */ - if (num_ue_req > max_num_ue) { - /* go to the first one we missed */ - for (int i = 0; i < max_num_ue; ++i) - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); - } else { - /* else, just start with the next UE next time */ - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); - } + /* just start with the next UE next time */ + g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); return n_rbg_sched; } @@ -742,15 +727,8 @@ int round_robin_ul(module_id_t Mod_id, } } - /* if not all UEs could be allocated in this round */ - if (num_ue_req > max_num_ue) { - /* go to the first one we missed */ - for (int i = 0; i < max_num_ue; ++i) - g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); - } else { - /* else, just start with the next UE next time */ - g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); - } + /* just start with the next UE next time */ + g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0); } From 8c7d94133f2400c836725484ec70820b9a10b1f0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 24 Jun 2020 14:20:27 +0200 Subject: [PATCH 077/171] Bugfix RR DL: a retx UE might not be allocated again --- openair2/LAYER2/MAC/pre_processor.c | 68 ++++++++++++++--------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 62b9e1c2cc..8324969a9c 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -83,15 +83,22 @@ int round_robin_dl(module_id_t Mod_id, const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); const int RBGsize = get_min_rb_unit(Mod_id, CC_id); const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); - int num_ue_req = 0; UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; int rbg = 0; for (; !rbgalloc_mask[rbg]; rbg++) ; /* fast-forward to first allowed RBG */ - // Calculate the amount of RBs every UE wants to send. - for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + /* just start with the UE after the one we had last time. If it does not + * exist, this will start at the head */ + int g_start_ue_dl = data; + g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); + + int UE_id = g_start_ue_dl; + UE_list_t UE_sched; + int *cur_UE = &UE_sched.head; + // Allocate retransmissions, and mark UEs with new transmissions + do { // check whether there are HARQ retransmissions const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); @@ -100,14 +107,14 @@ int round_robin_dl(module_id_t Mod_id, if (round != 8) { // retransmission: allocate const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; if (nb_rb == 0) - continue; + goto skip_ue; int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; // needs more RBGs than we can allocate if (nb_rbg > n_rbg_sched) { LOG_D(MAC, "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", UE_id, nb_rbg, n_rbg_sched); - continue; + goto skip_ue; } // ensure that the number of RBs can be contained by the RBGs (!), i.e. // if we allocate the last RBG this one should have the full RBGsize @@ -116,12 +123,12 @@ int round_robin_dl(module_id_t Mod_id, LOG_D(MAC, "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); - continue; + goto skip_ue; } const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); if (idx < 0) - continue; // cannot allocate CCE + goto skip_ue; // cannot allocate CCE ue_ctrl->pre_dci_dl_pdu_idx = idx; // retransmissions: directly allocate n_rbg_sched -= nb_rbg; @@ -148,35 +155,32 @@ int round_robin_dl(module_id_t Mod_id, return n_rbg_sched; for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } else { - if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) - num_ue_req++; + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total > 0) { + *cur_UE = UE_id; + cur_UE = &UE_sched.next[UE_id]; + } } - } - if (num_ue_req == 0) +skip_ue: + UE_id = next_ue_list_looped(UE_list, UE_id); + } while (UE_id != g_start_ue_dl); + *cur_UE = -1; // mark end + + if (UE_sched.head < 0) return n_rbg_sched; // no UE has a transmission - // after allocating retransmissions: build list of UE to allocate. - // if start_UE does not exist anymore (detach etc), start at first UE - if (g_start_ue_dl == -1) - g_start_ue_dl = UE_list->head; - int UE_id = g_start_ue_dl; - UE_list_t UE_sched; - int *cur_UE = &UE_sched.head; - - int num_ue_sched = 0; - max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); + // after allocating retransmissions: pre-allocate CCE, compute number of + // requested RBGs + max_num_ue = min(max_num_ue, n_rbg_sched); int rb_required[MAX_MOBILES_PER_ENB]; // how much UEs request - while (num_ue_sched < max_num_ue) { - while (UE_info->UE_template[CC_id][UE_id].dl_buffer_total <= 0) - UE_id = next_ue_list_looped(UE_list, UE_id); + cur_UE = &UE_sched.head; + while (*cur_UE >= 0 && max_num_ue > 0) { + const int UE_id = *cur_UE; + cur_UE = &UE_sched.next[UE_id]; // go to next const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); if (idx < 0) { LOG_D(MAC, "cannot allocate CCE for UE %d, skipping\n", UE_id); - num_ue_req--; - max_num_ue = min(min(max_num_ue, num_ue_req), n_rbg_sched); - UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate continue; } UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; @@ -184,12 +188,9 @@ int round_robin_dl(module_id_t Mod_id, UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; const uint32_t B = UE_info->UE_template[CC_id][UE_id].dl_buffer_total; rb_required[UE_id] = find_nb_rb_DL(mcs, B, n_rbg_sched * RBGsize, RBGsize); - *cur_UE = UE_id; - cur_UE = &UE_sched.next[UE_id]; - num_ue_sched++; - UE_id = next_ue_list_looped(UE_list, UE_id); // next candidate + max_num_ue--; } - *cur_UE = -1; + *cur_UE = -1; // not all UEs might be allocated, mark end /* for one UE after the next: allocate resources */ cur_UE = &UE_sched.head; @@ -214,9 +215,6 @@ int round_robin_dl(module_id_t Mod_id, for (rbg++; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; } - /* just start with the next UE next time */ - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); - return n_rbg_sched; } From 18a6961fcdc609b6f19017c9b9e8bb391aff522a Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 17 Jun 2020 11:05:35 +0200 Subject: [PATCH 078/171] Format to dynamically handle default DL SCHED algo --- openair2/LAYER2/MAC/mac.h | 15 +++++++ openair2/LAYER2/MAC/main.c | 6 ++- openair2/LAYER2/MAC/pre_processor.c | 69 +++++++++++++++++++---------- 3 files changed, 65 insertions(+), 25 deletions(-) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 329e262c82..0264951683 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1274,6 +1274,19 @@ typedef struct { int length; } contig_rbs_t; +/** + * definition of a scheduling algorithm implementation used in the + * default scheduler + */ +typedef struct { + char *name; + void *(*setup)(void); + void (*unset)(void **); + int (*run)( + module_id_t, int, int, int, UE_list_t *, int, int, uint8_t *, void *); + void *data; +} default_sched_dl_algo_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1432,6 +1445,8 @@ typedef struct eNB_MAC_INST_s { UE_free_list_t UE_free_list; /// for scheduling selection SCHEDULER_MODES scheduler_mode; + /// scheduling algorithm used in default scheduler + default_sched_dl_algo_t dl_algo; int32_t puSch10xSnr; int32_t puCch10xSnr; diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 1a88623a1f..39e342cba0 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -128,7 +128,11 @@ void mac_top_init_eNB(void) } mac[i]->if_inst = IF_Module_init(i); - + char *s = "round_robin_dl"; + void *d = dlsym(NULL, s); + AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); + mac[i]->dl_algo = *(default_sched_dl_algo_t *) d; + mac[i]->dl_algo.data = mac[i]->dl_algo.setup(); init_UE_info(&mac[i]->UE_info); init_slice_info(&mac[i]->slice_info); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 8324969a9c..596e45ce2a 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -69,15 +69,26 @@ int get_rbg_size_last(module_id_t Mod_id, int CC_id) { return RBGsize; } -int g_start_ue_dl = -1; -int round_robin_dl(module_id_t Mod_id, - int CC_id, - int frame, - int subframe, - UE_list_t *UE_list, - int max_num_ue, - int n_rbg_sched, - uint8_t *rbgalloc_mask) { +void *rr_dl_setup(void) { + void *data = malloc(sizeof(int)); + *(int *) data = 0; + AssertFatal(data, "could not allocate data in %s()\n", __func__); + return data; +} +void rr_dl_unset(void **data) { + if (*data) + free(*data); + *data = NULL; +} +int rr_dl_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + UE_list_t *UE_list, + int max_num_ue, + int n_rbg_sched, + uint8_t *rbgalloc_mask, + void *data) { DevAssert(UE_list->head >= 0); DevAssert(n_rbg_sched > 0); const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); @@ -91,10 +102,10 @@ int round_robin_dl(module_id_t Mod_id, /* just start with the UE after the one we had last time. If it does not * exist, this will start at the head */ - int g_start_ue_dl = data; - g_start_ue_dl = next_ue_list_looped(UE_list, g_start_ue_dl); + int *start_ue = data; + *start_ue = next_ue_list_looped(UE_list, *start_ue); - int UE_id = g_start_ue_dl; + int UE_id = *start_ue; UE_list_t UE_sched; int *cur_UE = &UE_sched.head; // Allocate retransmissions, and mark UEs with new transmissions @@ -163,7 +174,7 @@ int round_robin_dl(module_id_t Mod_id, skip_ue: UE_id = next_ue_list_looped(UE_list, UE_id); - } while (UE_id != g_start_ue_dl); + } while (UE_id != *start_ue); *cur_UE = -1; // mark end if (UE_sched.head < 0) @@ -217,6 +228,14 @@ skip_ue: return n_rbg_sched; } +default_sched_dl_algo_t round_robin_dl = { + .name = "round_robin_dl", + .setup = rr_dl_setup, + .unset = rr_dl_unset, + .run = rr_dl_run, + .data = NULL +}; + // This function stores the downlink buffer for all the logical channels void @@ -306,8 +325,9 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, int CC_id, frame_t frameP, sub_frame_t subframeP) { - UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; - const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + eNB_MAC_INST *mac = RC.mac[Mod_id]; + UE_info_t *UE_info = &mac->UE_info; + const int N_RBG = to_rbg(mac->common_channels[CC_id].mib->message.dl_Bandwidth); const int RBGsize = get_min_rb_unit(Mod_id, CC_id); store_dlsch_buffer(Mod_id, CC_id, frameP, subframeP); @@ -364,7 +384,7 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, if (UE_to_sched.head < 0) return; - uint8_t *vrb_map = RC.mac[Mod_id]->common_channels[CC_id].vrb_map; + uint8_t *vrb_map = mac->common_channels[CC_id].vrb_map; uint8_t rbgalloc_mask[N_RBG_MAX]; int n_rbg_sched = 0; for (int i = 0; i < N_RBG; i++) { @@ -376,14 +396,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, n_rbg_sched += rbgalloc_mask[i]; } - round_robin_dl(Mod_id, - CC_id, - frameP, - subframeP, - &UE_to_sched, - 4, // max_num_ue - n_rbg_sched, - rbgalloc_mask); + mac->dl_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + &UE_to_sched, + 4, // max_num_ue + n_rbg_sched, + rbgalloc_mask, + mac->dl_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for From 2de57fbc3658223daa0cd0aa21472a728b52a39b Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 28 May 2020 16:17:52 +0200 Subject: [PATCH 079/171] Add Proportional Fair scheduler, wbCqi Selects UE with highest coefficient. Allocates until there are no more RBGs to allocate, or UE has no more data. In the latter case, continues with the next UE (second-highest coefficient). --- openair2/LAYER2/MAC/pre_processor.c | 164 ++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 596e45ce2a..dba6f3750f 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -237,6 +237,170 @@ default_sched_dl_algo_t round_robin_dl = { }; +void *pf_dl_setup(void) { + void *data = calloc(MAX_MOBILES_PER_ENB, sizeof(float)); + for (int i = 0; i < MAX_MOBILES_PER_ENB; i++) + *(float *) data = 0.0f; + AssertFatal(data, "could not allocate data in %s()\n", __func__); + return data; +} +void pf_dl_unset(void **data) { + if (*data) + free(*data); + *data = NULL; +} +int pf_wbcqi_dl_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + UE_list_t *UE_list, + int max_num_ue, + int n_rbg_sched, + uint8_t *rbgalloc_mask, + void *data) { + DevAssert(UE_list->head >= 0); + DevAssert(n_rbg_sched > 0); + const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + const int RBGsize = get_min_rb_unit(Mod_id, CC_id); + const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); + UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; + + int rbg = 0; + for (; !rbgalloc_mask[rbg]; rbg++) + ; /* fast-forward to first allowed RBG */ + + UE_list_t UE_sched; // UEs that could be scheduled + int *uep = &UE_sched.head; + float *thr_ue = data; + float coeff_ue[MAX_MOBILES_PER_ENB]; + + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + const float a = 0.0005f; // corresponds to 200ms window + const uint32_t b = UE_info->eNB_UE_stats[CC_id][UE_id].TBS; + thr_ue[UE_id] = (1 - a) * thr_ue[UE_id] + a * b; + + // check whether there are HARQ retransmissions + const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const uint8_t round = ue_ctrl->round[CC_id][harq_pid]; + if (round != 8) { // retransmission: allocate + const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + if (nb_rb == 0) + continue; + int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; + // needs more RBGs than we can allocate + if (nb_rbg > n_rbg_sched) { + LOG_D(MAC, + "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", + UE_id, nb_rbg, n_rbg_sched); + continue; + } + // ensure that the number of RBs can be contained by the RBGs (!), i.e. + // if we allocate the last RBG this one should have the full RBGsize + if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched + && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { + LOG_D(MAC, + "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", + UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); + continue; + } + const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; // cannot allocate CCE + ue_ctrl->pre_dci_dl_pdu_idx = idx; + // retransmissions: directly allocate + n_rbg_sched -= nb_rbg; + ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; + for (; nb_rbg > 0; rbg++) { + if (!rbgalloc_mask[rbg]) + continue; + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + nb_rbg--; + } + LOG_D(MAC, + "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " + "round %d retx nb_rb %d pre_nb_available_rbs %d\n", + frame, subframe, n_rbg_sched, UE_id, round, + UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], + ue_ctrl->pre_nb_available_rbs[CC_id]); + /* if there are no more RBG to give, return */ + if (n_rbg_sched <= 0) + return 0; + max_num_ue--; + /* if there are no UEs that can be allocated anymore, return */ + if (max_num_ue == 0) + return n_rbg_sched; + for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } else { + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0) + continue; + + const int mcs = cqi_to_mcs[UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]]; + const uint32_t tbs = get_TBS_DL(mcs, RBGsize); + coeff_ue[UE_id] = (float) tbs / thr_ue[UE_id]; + //LOG_I(MAC, " pf UE %d: old TBS %d thr %f MCS %d TBS %d coeff %f\n", + // UE_id, b, thr_ue[UE_id], mcs, tbs, coeff_ue[UE_id]); + *uep = UE_id; + uep = &UE_sched.next[UE_id]; + } + } + *uep = -1; + + while (max_num_ue > 0 && n_rbg_sched > 0 && UE_sched.head >= 0) { + int *max = &UE_sched.head; /* assume head is max */ + int *p = &UE_sched.next[*max]; + while (*p >= 0) { + /* if the current one has larger coeff, save for later */ + if (coeff_ue[*p] > coeff_ue[*max]) + max = p; + p = &UE_sched.next[*p]; + } + /* remove the max one */ + const int UE_id = *max; + p = &UE_sched.next[*max]; + *max = UE_sched.next[*max]; + *p = -1; + + const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; + UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; + + max_num_ue--; + + /* allocate as much as possible */ + const int mcs = cqi_to_mcs[cqi]; + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; + int req = find_nb_rb_DL(mcs, + UE_info->UE_template[CC_id][UE_id].dl_buffer_total, + n_rbg_sched * RBGsize, + RBGsize); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + while (req > 0 && n_rbg_sched > 0) { + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize; + ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG; + req -= sRBG; + n_rbg_sched--; + for (rbg++; n_rbg_sched > 0 && !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } + } + + return n_rbg_sched; +} +default_sched_dl_algo_t proportional_fair_wbcqi_dl = { + .name = "proportional_fair_wbcqi_dl", + .setup = pf_dl_setup, + .unset = pf_dl_unset, + .run = pf_wbcqi_dl_run, + .data = NULL +}; + // This function stores the downlink buffer for all the logical channels void store_dlsch_buffer(module_id_t Mod_id, From fe7236d9c4bfd7f00508123075b367d18a210072 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 22 May 2020 16:43:24 +0200 Subject: [PATCH 080/171] Add Maximum Throughput scheduler, wbCqi Selects the UE with the highest CQI. If two UEs have the same CQI, choses the one with highest number of bytes in RLC queue. Allocates as many RBGs as possible, and potentially continues with the next UE. --- openair2/LAYER2/MAC/pre_processor.c | 150 ++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index dba6f3750f..436ec2435e 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -401,6 +401,156 @@ default_sched_dl_algo_t proportional_fair_wbcqi_dl = { .data = NULL }; +void *mt_dl_setup(void) { + return NULL; +} +void mt_dl_unset(void **data) { + *data = NULL; +} +int mt_wbcqi_dl_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + UE_list_t *UE_list, + int max_num_ue, + int n_rbg_sched, + uint8_t *rbgalloc_mask, + void *data) { + DevAssert(UE_list->head >= 0); + DevAssert(n_rbg_sched > 0); + const int N_RBG = to_rbg(RC.mac[Mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + const int RBGsize = get_min_rb_unit(Mod_id, CC_id); + const int RBGlastsize = get_rbg_size_last(Mod_id, CC_id); + UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; + + int rbg = 0; + for (; !rbgalloc_mask[rbg]; rbg++) + ; /* fast-forward to first allowed RBG */ + + UE_list_t UE_sched; // UEs that could be scheduled + int *uep = &UE_sched.head; + + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) { + // check whether there are HARQ retransmissions + const COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + const uint8_t harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config, frame, subframe); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + const uint8_t round = ue_ctrl->round[CC_id][harq_pid]; + if (round != 8) { // retransmission: allocate + const int nb_rb = UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid]; + if (nb_rb == 0) + continue; + int nb_rbg = (nb_rb + (nb_rb % RBGsize)) / RBGsize; + // needs more RBGs than we can allocate + if (nb_rbg > n_rbg_sched) { + LOG_D(MAC, + "retransmission of UE %d needs more RBGs (%d) than we have (%d)\n", + UE_id, nb_rbg, n_rbg_sched); + continue; + } + // ensure that the number of RBs can be contained by the RBGs (!), i.e. + // if we allocate the last RBG this one should have the full RBGsize + if ((nb_rb % RBGsize) == 0 && nb_rbg == n_rbg_sched + && rbgalloc_mask[N_RBG - 1] && RBGlastsize != RBGsize) { + LOG_D(MAC, + "retransmission of UE %d needs %d RBs, but the last RBG %d is too small (%d, normal %d)\n", + UE_id, nb_rb, N_RBG - 1, RBGlastsize, RBGsize); + continue; + } + const uint8_t cqi = ue_ctrl->dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; // cannot allocate CCE + ue_ctrl->pre_dci_dl_pdu_idx = idx; + // retransmissions: directly allocate + n_rbg_sched -= nb_rbg; + ue_ctrl->pre_nb_available_rbs[CC_id] += nb_rb; + for (; nb_rbg > 0; rbg++) { + if (!rbgalloc_mask[rbg]) + continue; + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + nb_rbg--; + } + LOG_D(MAC, + "%4d.%d n_rbg_sched %d after retransmission reservation for UE %d " + "round %d retx nb_rb %d pre_nb_available_rbs %d\n", + frame, subframe, n_rbg_sched, UE_id, round, + UE_info->UE_template[CC_id][UE_id].nb_rb[harq_pid], + ue_ctrl->pre_nb_available_rbs[CC_id]); + /* if there are no more RBG to give, return */ + if (n_rbg_sched <= 0) + return 0; + max_num_ue--; + /* if there are no UEs that can be allocated anymore, return */ + if (max_num_ue == 0) + return n_rbg_sched; + for (; !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } else { + if (UE_info->UE_template[CC_id][UE_id].dl_buffer_total == 0) + continue; + *uep = UE_id; + uep = &UE_sched.next[UE_id]; + } + } + *uep = -1; + + while (max_num_ue > 0 && n_rbg_sched > 0 && UE_sched.head >= 0) { + int *max = &UE_sched.head; /* assume head is max */ + int *p = &UE_sched.next[*max]; + while (*p >= 0) { + /* if the current one has better CQI, or the same and more data */ + const uint8_t maxCqi = UE_info->UE_sched_ctrl[*max].dl_cqi[CC_id]; + const uint32_t maxB = UE_info->UE_template[CC_id][*max].dl_buffer_total; + const uint8_t pCqi = UE_info->UE_sched_ctrl[*p].dl_cqi[CC_id]; + const uint32_t pB = UE_info->UE_template[CC_id][*p].dl_buffer_total; + if (pCqi > maxCqi || (pCqi == maxCqi && pB > maxB)) + max = p; + p = &UE_sched.next[*p]; + } + /* remove the max one */ + const int UE_id = *max; + p = &UE_sched.next[*max]; + *max = UE_sched.next[*max]; + *p = -1; + + const uint8_t cqi = UE_info->UE_sched_ctrl[UE_id].dl_cqi[CC_id]; + const int idx = CCE_try_allocate_dlsch(Mod_id, CC_id, subframe, UE_id, cqi); + if (idx < 0) + continue; + UE_info->UE_sched_ctrl[UE_id].pre_dci_dl_pdu_idx = idx; + + max_num_ue--; + + /* allocate as much as possible */ + const int mcs = cqi_to_mcs[cqi]; + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = mcs; + int req = find_nb_rb_DL(mcs, + UE_info->UE_template[CC_id][UE_id].dl_buffer_total, + n_rbg_sched * RBGsize, + RBGsize); + UE_sched_ctrl_t *ue_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + while (req > 0 && n_rbg_sched > 0) { + ue_ctrl->rballoc_sub_UE[CC_id][rbg] = 1; + rbgalloc_mask[rbg] = 0; + const int sRBG = rbg == N_RBG - 1 ? RBGlastsize : RBGsize; + ue_ctrl->pre_nb_available_rbs[CC_id] += sRBG; + req -= sRBG; + n_rbg_sched--; + for (rbg++; n_rbg_sched > 0 && !rbgalloc_mask[rbg]; rbg++) /* fast-forward */ ; + } + } + + return n_rbg_sched; +} +default_sched_dl_algo_t maximum_throughput_wbcqi_dl = { + .name = "maximum_throughput_wbcqi_dl", + .setup = mt_dl_setup, + .unset = mt_dl_unset, + .run = mt_wbcqi_dl_run, + .data = NULL +}; + // This function stores the downlink buffer for all the logical channels void store_dlsch_buffer(module_id_t Mod_id, From af89a6b780ce65ccb42f6b01b0a85d16450f0e58 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 17 Jun 2020 18:40:48 +0200 Subject: [PATCH 081/171] Configurable Default Scheduler DL Algo --- openair2/ENB_APP/MACRLC_paramdef.h | 3 +++ openair2/ENB_APP/enb_config.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/openair2/ENB_APP/MACRLC_paramdef.h b/openair2/ENB_APP/MACRLC_paramdef.h index 55ce9d5059..fcee6142f0 100644 --- a/openair2/ENB_APP/MACRLC_paramdef.h +++ b/openair2/ENB_APP/MACRLC_paramdef.h @@ -58,6 +58,7 @@ #define CONFIG_STRING_MACRLC_SCHED_MODE "scheduler_mode" #define CONFIG_MACRLC_PUSCH10xSNR "puSch10xSnr" #define CONFIG_MACRLC_PUCCH10xSNR "puCch10xSnr" +#define CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO "default_sched_dl_algo" /*-------------------------------------------------------------------------------------------------------------------------------------------------------*/ /* MacRLC configuration parameters */ @@ -84,6 +85,7 @@ {CONFIG_STRING_MACRLC_SCHED_MODE, NULL, 0, strptr:NULL, defstrval:"default", TYPE_STRING, 0}, \ {CONFIG_MACRLC_PUSCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ {CONFIG_MACRLC_PUCCH10xSNR, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ +{CONFIG_STRING_MACRLC_DEFAULT_SCHED_DL_ALGO, NULL, 0, strptr:NULL, defstrval:"round_robin_dl", TYPE_STRING, 0}, \ } #define MACRLC_CC_IDX 0 #define MACRLC_TRANSPORT_N_PREFERENCE_IDX 1 @@ -105,6 +107,7 @@ #define MACRLC_SCHED_MODE_IDX 17 #define MACRLC_PUSCH10xSNR_IDX 18 #define MACRLC_PUCCH10xSNR_IDX 19 +#define MACRLC_DEFAULT_SCHED_DL_ALGO_IDX 20 /*---------------------------------------------------------------------------------------------------------------------------------------------------------*/ #endif diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 2200c8f013..0308c2fd79 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -29,6 +29,7 @@ #include #include +#include #include "common/utils/LOG/log.h" #include "assertions.h" @@ -260,6 +261,15 @@ void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) { global_scheduler_mode=SCHED_MODE_DEFAULT; printf("sched mode = default %d [%s]\n",global_scheduler_mode,*(MacRLC_ParamList.paramarray[j][MACRLC_SCHED_MODE_IDX].strptr)); } + + char *s = *MacRLC_ParamList.paramarray[j][MACRLC_DEFAULT_SCHED_DL_ALGO_IDX].strptr; + void *d = dlsym(NULL, s); + AssertFatal(d, "%s(): no default scheduler DL algo '%s' found\n", __func__, s); + // release default, add new + RC.mac[j]->dl_algo.unset(&RC.mac[j]->dl_algo.data); + RC.mac[j]->dl_algo = *(default_sched_dl_algo_t *) d; + RC.mac[j]->dl_algo.data = RC.mac[j]->dl_algo.setup(); + LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", RC.mac[j]->dl_algo.name); }// j=0..num_inst } /*else {// MacRLC_ParamList.numelt > 0 // ignore it From 6fcc4f59709708fc4f6862b9eb87264d1015a7fe Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jun 2020 17:32:01 +0200 Subject: [PATCH 082/171] Format to dynamically handle UL SCHED --- openair2/LAYER2/MAC/mac.h | 16 +++++- openair2/LAYER2/MAC/main.c | 5 ++ openair2/LAYER2/MAC/pre_processor.c | 79 ++++++++++++++++++----------- 3 files changed, 70 insertions(+), 30 deletions(-) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 0264951683..09585fae55 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -1276,7 +1276,7 @@ typedef struct { /** * definition of a scheduling algorithm implementation used in the - * default scheduler + * default DL scheduler */ typedef struct { char *name; @@ -1287,6 +1287,19 @@ typedef struct { void *data; } default_sched_dl_algo_t; +/** + * definition of a scheduling algorithm implementation used in the + * default UL scheduler + */ +typedef struct { + char *name; + void *(*setup)(void); + void (*unset)(void **); + int (*run)( + module_id_t, int, int, int, int, int, UE_list_t *, int, int, contig_rbs_t *, void *); + void *data; +} default_sched_ul_algo_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1447,6 +1460,7 @@ typedef struct eNB_MAC_INST_s { SCHEDULER_MODES scheduler_mode; /// scheduling algorithm used in default scheduler default_sched_dl_algo_t dl_algo; + default_sched_ul_algo_t ul_algo; int32_t puSch10xSnr; int32_t puCch10xSnr; diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 39e342cba0..294eb12159 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -133,6 +133,11 @@ void mac_top_init_eNB(void) AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); mac[i]->dl_algo = *(default_sched_dl_algo_t *) d; mac[i]->dl_algo.data = mac[i]->dl_algo.setup(); + s = "round_robin_ul"; + d = dlsym(NULL, s); + AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); + mac[i]->ul_algo = *(default_sched_ul_algo_t *) d; + mac[i]->ul_algo.data = mac[i]->ul_algo.setup(); init_UE_info(&mac[i]->UE_info); init_slice_info(&mac[i]->slice_info); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 436ec2435e..07bbed22c3 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -830,17 +830,28 @@ int pp_find_rb_table_index(int approximate) { return p + 1; } -int g_start_ue_ul = -1; -int round_robin_ul(module_id_t Mod_id, - int CC_id, - int frame, - int subframe, - int sched_frame, - int sched_subframe, - UE_list_t *UE_list, - int max_num_ue, - int num_contig_rb, - contig_rbs_t *rbs) { +void *rr_ul_setup(void) { + void *data = malloc(sizeof(int)); + *(int *) data = 0; + AssertFatal(data, "could not allocate data in %s()\n", __func__); + return data; +} +void rr_ul_unset(void **data) { + if (*data) + free(*data); + *data = NULL; +} +int rr_ul_run(module_id_t Mod_id, + int CC_id, + int frame, + int subframe, + int sched_frame, + int sched_subframe, + UE_list_t *UE_list, + int max_num_ue, + int num_contig_rb, + contig_rbs_t *rbs, + void *data) { AssertFatal(num_contig_rb <= 2, "cannot handle more than two contiguous RB regions\n"); UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; const int max_rb = num_contig_rb > 1 ? MAX(rbs[0].length, rbs[1].length) : rbs[0].length; @@ -980,9 +991,10 @@ int round_robin_ul(module_id_t Mod_id, end = la > lb ? 2 : -1; } - if (g_start_ue_ul == -1) - g_start_ue_ul = UE_list->head; - int sUE_id = g_start_ue_ul; + int *start_ue = data; + if (*start_ue == -1) + *start_ue = UE_list->head; + int sUE_id = *start_ue; int rb_idx_given[MAX_MOBILES_PER_ENB]; memset(rb_idx_given, 0, sizeof(rb_idx_given)); @@ -1061,10 +1073,17 @@ int round_robin_ul(module_id_t Mod_id, } /* just start with the next UE next time */ - g_start_ue_ul = next_ue_list_looped(UE_list, g_start_ue_ul); + *start_ue = next_ue_list_looped(UE_list, *start_ue); return rbs[0].length + (num_contig_rb > 1 ? rbs[1].length : 0); } +default_sched_ul_algo_t round_robin_ul = { + .name = "round_robin_ul", + .setup = rr_ul_setup, + .unset = rr_ul_unset, + .run = rr_ul_run, + .data = NULL +}; void ulsch_scheduler_pre_processor(module_id_t Mod_id, int CC_id, @@ -1072,9 +1091,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, sub_frame_t subframeP, int sched_frameP, unsigned char sched_subframeP) { - UE_info_t *UE_info = &RC.mac[Mod_id]->UE_info; - const int N_RB_UL = to_prb(RC.mac[Mod_id]->common_channels[CC_id].ul_Bandwidth); - COMMON_channels_t *cc = &RC.mac[Mod_id]->common_channels[CC_id]; + eNB_MAC_INST *mac = RC.mac[Mod_id]; + UE_info_t *UE_info = &mac->UE_info; + const int N_RB_UL = to_prb(mac->common_channels[CC_id].ul_Bandwidth); + COMMON_channels_t *cc = &mac->common_channels[CC_id]; UE_list_t UE_to_sched; UE_to_sched.head = -1; @@ -1131,16 +1151,17 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, } } - round_robin_ul(Mod_id, - CC_id, - frameP, - subframeP, - sched_frameP, - sched_subframeP, - &UE_to_sched, - 4, // max_num_ue - n_contig, - rbs); + mac->ul_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + sched_frameP, + sched_subframeP, + &UE_to_sched, + 4, // max_num_ue + n_contig, + rbs, + mac->ul_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for @@ -1159,7 +1180,7 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, continue; print = 1; - uint8_t harq_pid = subframe2harqpid(&RC.mac[Mod_id]->common_channels[CC_id], + uint8_t harq_pid = subframe2harqpid(&mac->common_channels[CC_id], sched_frameP, sched_subframeP); LOG_D(MAC, "%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s\n", frameP, From da09d63acdc1a4630ef683d2f7eabbb1952e0833 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jun 2020 10:27:45 +0200 Subject: [PATCH 083/171] Default pre-processor: efficiently build UE list --- openair2/LAYER2/MAC/pre_processor.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index 07bbed22c3..d7dfc7816a 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -647,12 +647,10 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, store_dlsch_buffer(Mod_id, CC_id, frameP, subframeP); UE_list_t UE_to_sched; - UE_to_sched.head = -1; for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) UE_to_sched.next[i] = -1; + int *cur = &UE_to_sched.head; - int first = 1; - int last_UE_id = -1; for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; const UE_TEMPLATE *ue_template = &UE_info->UE_template[CC_id][UE_id]; @@ -685,15 +683,10 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, } /* define UEs to schedule */ - if (first) { - first = 0; - UE_to_sched.head = UE_id; - } else { - UE_to_sched.next[last_UE_id] = UE_id; - } - UE_to_sched.next[UE_id] = -1; - last_UE_id = UE_id; + *cur = UE_id; + cur = &UE_to_sched.next[UE_id]; } + *cur = -1; if (UE_to_sched.head < 0) return; @@ -1097,11 +1090,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, COMMON_channels_t *cc = &mac->common_channels[CC_id]; UE_list_t UE_to_sched; - UE_to_sched.head = -1; for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) UE_to_sched.next[i] = -1; + int *cur = &UE_to_sched.head; - int last_UE_id = -1; for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id]; UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; @@ -1124,13 +1116,10 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, continue; /* define UEs to schedule */ - if (UE_to_sched.head < 0) - UE_to_sched.head = UE_id; - else - UE_to_sched.next[last_UE_id] = UE_id; - UE_to_sched.next[UE_id] = -1; - last_UE_id = UE_id; + *cur = UE_id; + cur = &UE_to_sched.next[UE_id]; } + *cur = -1; if (UE_to_sched.head < 0) return; From 714a2df097f9792dc356d7033ed31374b09a289f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 12:00:43 +0200 Subject: [PATCH 084/171] Remove any slice-related information from OAI --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 13 - .../MAC/flexran_agent_mac_internal.c | 28 +- .../flexran_agent_mac_slice_verification.c | 4 +- openair2/ENB_APP/flexran_agent_ran_api.c | 314 ++---------------- openair2/LAYER2/MAC/mac.h | 104 ------ openair2/LAYER2/MAC/mac_proto.h | 2 - openair2/LAYER2/MAC/main.c | 27 -- .../NR_MAC_gNB/gNB_scheduler_primitives.c | 2 - 8 files changed, 39 insertions(+), 455 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 603ff25198..669eb33ea3 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -49,19 +49,6 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; -/* the slice config as kept in the underlying system */ -Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; -/* a structure that keeps updates which will be reflected in slice_config later */ -Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; -/* indicates whether sc_update contains new data */ -int perform_slice_config_update_count = 1; -/* queue of incoming new UE<>slice association commands */ -Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; -int n_ue_slice_assoc_updates = 0; -/* mutex for sc_update: do not receive new config and write it at the same time */ -pthread_mutex_t sc_update_mtx = PTHREAD_MUTEX_INITIALIZER; - - int flexran_agent_mac_stats_reply_ue(mid_t mod_id, Protocol__FlexUeStatsReport **ue_report, int n_ue, diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index a85cbac543..84a28683b7 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -33,14 +33,6 @@ #include "flexran_agent_mac_internal.h" #include "flexran_agent_mac_slice_verification.h" -/* from flexran_agent_mac.c */ -extern Protocol__FlexSliceConfig *slice_config[MAX_NUM_SLICES]; -extern Protocol__FlexSliceConfig *sc_update[MAX_NUM_SLICES]; -extern int perform_slice_config_update_count; -extern Protocol__FlexUeConfig *ue_slice_assoc_update[MAX_NUM_SLICES]; -extern int n_ue_slice_assoc_updates; -extern pthread_mutex_t sc_update_mtx; - Protocol__FlexranMessage * flexran_agent_generate_diff_mac_stats_report(Protocol__FlexranMessage *new_message, Protocol__FlexranMessage *old_message) { @@ -1040,12 +1032,12 @@ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) if (!fsc) return NULL; protocol__flex_slice_config__init(fsc); - /* say there are n_dl slices but reserve memory for up to MAX_NUM_SLICES so + /* say there are n_dl slices but reserve memory for up to 10 so * we don't need to reserve again later */ fsc->n_dl = n_dl; - fsc->dl = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexDlSlice *)); + fsc->dl = calloc(10, sizeof(Protocol__FlexDlSlice *)); if (!fsc->dl) fsc->n_dl = 0; - for (i = 0; i < MAX_NUM_SLICES; i++) { + for (i = 0; i < 10; i++) { fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice)); if (!fsc->dl[i]) continue; protocol__flex_dl_slice__init(fsc->dl[i]); @@ -1053,9 +1045,9 @@ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) /* as above */ fsc->n_ul = m_ul; - fsc->ul = calloc(MAX_NUM_SLICES, sizeof(Protocol__FlexUlSlice *)); + fsc->ul = calloc(10, sizeof(Protocol__FlexUlSlice *)); if (!fsc->ul) fsc->n_ul = 0; - for (i = 0; i < MAX_NUM_SLICES; i++) { + for (i = 0; i < 10; i++) { fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice)); if (!fsc->ul[i]) continue; protocol__flex_ul_slice__init(fsc->ul[i]); @@ -1401,8 +1393,8 @@ Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id) mod_id, id); Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; sc_update[mod_id]->n_dl++; - AssertFatal(sc_update[mod_id]->n_dl <= MAX_NUM_SLICES, - "cannot create more than MAX_NUM_SLICES\n"); + AssertFatal(sc_update[mod_id]->n_dl <= 10, + "cannot create more than 10\n"); to->id = id; return to; } @@ -1468,8 +1460,8 @@ Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id) mod_id, id); Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; sc_update[mod_id]->n_ul++; - AssertFatal(sc_update[mod_id]->n_ul <= MAX_NUM_SLICES, - "cannot create more than MAX_NUM_SLICES\n"); + AssertFatal(sc_update[mod_id]->n_ul <= 10, + "cannot create more than 10\n"); to->id = id; return to; } @@ -1698,7 +1690,7 @@ int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protoco void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) { - if (n_ue_slice_assoc_updates == MAX_NUM_SLICES) { + if (n_ue_slice_assoc_updates == 10) { LOG_E(FLEXRAN_AGENT, "[%d] can not handle flex_ue_config message, buffer is full; try again later\n", mod_id); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c index 67329e91be..f7f60541f5 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -132,7 +132,7 @@ int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existin /* else "only" an update */ } - if (n < 1 || n > MAX_NUM_SLICES) { + if (n < 1 || n > 10) { LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n", mod_id, n_ex, n); return 0; @@ -253,7 +253,7 @@ int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existin /* else "only" an update */ } - if (n < 1 || n > MAX_NUM_SLICES) { + if (n < 1 || n > 10) { LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n", mod_id, n_ex, n); return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 0fcc51782e..291c4dc7d8 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3015,469 +3015,209 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti) /**************************** SLICING ****************************/ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - - int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id]; - - if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl) - return RC.mac[mod_id]->slice_info.dl[slice_idx].id; - return 0; } void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { if (!mac_is_present(mod_id)) return; - - if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; - - if (!flexran_dl_slice_exists(mod_id, slice_idx)) return; - - //RC.mac[mod_id]->UE_info.assoc_dl_slice_idx[ue_id] = slice_idx; } int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - - int slice_idx = 0; //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id]; - - if (slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul) - return RC.mac[mod_id]->slice_info.ul[slice_idx].id; - return 0; } void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { if (!mac_is_present(mod_id)) return; - - if (flexran_get_mac_ue_crnti(mod_id, ue_id) == NOT_A_RNTI) return; - - if (!flexran_ul_slice_exists(mod_id, slice_idx)) return; - - //RC.mac[mod_id]->UE_info.assoc_ul_slice_idx[ue_id] = slice_idx; } int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_dl; + return 0; } int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - int newidx = RC.mac[mod_id]->slice_info.n_dl; - - if (newidx >= MAX_NUM_SLICES) return -1; - - ++RC.mac[mod_id]->slice_info.n_dl; - flexran_set_dl_slice_id(mod_id, newidx, slice_id); - return newidx; + return -1; } int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - int n = sli->n_dl; - - for (int i = 0; i < n; i++) { - if (sli->dl[i].id == slice_id) return i; - } - return -1; } int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - - if (sli->n_dl <= 1) return -1; - - if (sli->dl[slice_idx].sched_name) free(sli->dl[slice_idx].sched_name); - - --sli->n_dl; - - /* move last element to the position of the removed one */ - if (slice_idx != sli->n_dl) - memcpy(&sli->dl[slice_idx], &sli->dl[sli->n_dl], sizeof(sli->dl[sli->n_dl])); - - memset(&sli->dl[sli->n_dl], 0, sizeof(sli->dl[sli->n_dl])); - /* all UEs that have been in the old slice are put into slice index 0 */ - //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_dl_slice_idx; - - //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { - // if (assoc_list[i] == slice_idx) - // assoc_list[i] = 0; - //} - - return 1; + return -1; } int flexran_get_num_dl_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.n_dl; + return 0; } int flexran_get_intraslice_sharing_active(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.intraslice_share_active; + return -1; } void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.intraslice_share_active = intraslice_active; } int flexran_get_interslice_sharing_active(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.interslice_share_active; + return -1; } void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.interslice_share_active = interslice_active; } slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].id; + return -1; } void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].id = slice_id; } int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].pct * 100.0f; + return -1; } void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].pct = percentage / 100.0f; } int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].isol; + return -1; } void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].isol = is_isolated; } int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].prio; + return -1; } void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].prio = priority; } int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low; + return -1; } void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].pos_low = poslow; } int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high; + return -1; } void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].pos_high = poshigh; } int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs; + return -1; } void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.dl[slice_idx].maxmcs = maxmcs; } int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) { if (!mac_is_present(mod_id)) return -1; - - if (!(*sorting_list)) { - *sorting_list = calloc(CR_NUM, sizeof(Protocol__FlexDlSorting)); - - if (!(*sorting_list)) return -1; - } - - uint32_t policy = RC.mac[mod_id]->slice_info.dl[slice_idx].sorting; - - for (int i = 0; i < CR_NUM; i++) { - switch (policy >> 4 * (CR_NUM - 1 - i) & 0xF) { - case CR_ROUND: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; - break; - - case CR_SRB12: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_SRB12; - break; - - case CR_HOL: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_HOL; - break; - - case CR_LC: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LC; - break; - - case CR_CQI: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_CQI; - break; - - case CR_LCP: - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_LCP; - break; - - default: - /* this should not happen, but a "default" */ - (*sorting_list)[i] = PROTOCOL__FLEX_DL_SORTING__CR_ROUND; - break; - } - } - - return CR_NUM; + return -1; } void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) { if (!mac_is_present(mod_id)) return; - - uint32_t policy = 0; - - for (int i = 0; i < n && i < CR_NUM; i++) { - switch (sorting_list[i]) { - case PROTOCOL__FLEX_DL_SORTING__CR_ROUND: - policy = policy << 4 | CR_ROUND; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_SRB12: - policy = policy << 4 | CR_SRB12; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_HOL: - policy = policy << 4 | CR_HOL; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_LC: - policy = policy << 4 | CR_LC; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_CQI: - policy = policy << 4 | CR_CQI; - break; - - case PROTOCOL__FLEX_DL_SORTING__CR_LCP: - policy = policy << 4 | CR_LCP; - break; - - default: /* suppresses warnings */ - policy = policy << 4 | CR_ROUND; - break; - } - } - - /* fill up with 0 == CR_ROUND */ - if (CR_NUM > n) policy = policy << 4 * (CR_NUM - n); - - RC.mac[mod_id]->slice_info.dl[slice_idx].sorting = policy; } Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - - switch (RC.mac[mod_id]->slice_info.dl[slice_idx].accounting) { - case POL_FAIR: - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - - case POL_GREEDY: - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY; - - default: - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - } + return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; } void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) { if (!mac_is_present(mod_id)) return; - - switch (accounting) { - case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR: - RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; - return; - - case PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_GREEDY: - RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_GREEDY; - return; - - default: - RC.mac[mod_id]->slice_info.dl[slice_idx].accounting = POL_FAIR; - return; - } } char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return NULL; - - return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name; + return NULL; } int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { if (!mac_is_present(mod_id)) return 0; - - if (RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name) - free(RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name); - - RC.mac[mod_id]->slice_info.dl[slice_idx].sched_name = strdup(name); - RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb = dlsym(NULL, name); - return RC.mac[mod_id]->slice_info.dl[slice_idx].sched_cb != NULL; + return 0; } int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - int newidx = RC.mac[mod_id]->slice_info.n_ul; - - if (newidx >= MAX_NUM_SLICES) return -1; - - ++RC.mac[mod_id]->slice_info.n_ul; - flexran_set_ul_slice_id(mod_id, newidx, slice_id); - return newidx; + return -1; } int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - int n = sli->n_ul; - - for (int i = 0; i < n; i++) { - if (sli->ul[i].id == slice_id) return i; - } - return -1; } int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - slice_info_t *sli = &RC.mac[mod_id]->slice_info; - - if (sli->n_ul <= 1) return -1; - - if (sli->ul[slice_idx].sched_name) free(sli->ul[slice_idx].sched_name); - - --sli->n_ul; - - /* move last element to the position of the removed one */ - if (slice_idx != sli->n_ul) - memcpy(&sli->ul[slice_idx], &sli->ul[sli->n_ul], sizeof(sli->ul[sli->n_ul])); - - memset(&sli->ul[sli->n_ul], 0, sizeof(sli->ul[sli->n_ul])); - /* all UEs that have been in the old slice are put into slice index 0 */ - //int *assoc_list = RC.mac[mod_id]->UE_info.assoc_ul_slice_idx; - - //for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) { - // if (assoc_list[i] == slice_idx) - // assoc_list[i] = 0; - //} - - return sli->n_ul; + return -1; } int flexran_get_num_ul_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.n_ul; + return 0; } int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return slice_idx >= 0 && slice_idx < RC.mac[mod_id]->slice_info.n_ul; + return 0; } slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].id; + return -1; } void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].id = slice_id; } int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].pct * 100.0f; + return -1; } void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].pct = percentage / 100.0f; } int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb; + return -1; } void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].first_rb = first_rb; } int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs; + return -1; } void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { if (!mac_is_present(mod_id)) return; - - RC.mac[mod_id]->slice_info.ul[slice_idx].maxmcs = maxmcs; } char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return NULL; - - return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name; + return ""; } int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { if (!mac_is_present(mod_id)) return 0; - - if (RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name) - free(RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name); - - RC.mac[mod_id]->slice_info.ul[slice_idx].sched_name = strdup(name); - RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb = dlsym(NULL, name); - return RC.mac[mod_id]->slice_info.ul[slice_idx].sched_cb != NULL; + return 0; } /************************** S1AP **************************/ diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 09585fae55..8349d84d48 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -155,9 +155,6 @@ /*!\brief minimum MAC data needed for transmitting 1 min RLC PDU size + 1 byte MAC subHeader */ #define MIN_MAC_HDR_RLC_SIZE (1 + MIN_RLC_PDU_SIZE) -/*!\brief maximum number of slices / groups */ -#define MAX_NUM_SLICES 10 - #define U_PLANE_INACTIVITY_VALUE 0 /* defined 10ms order (zero means infinity) */ @@ -1150,9 +1147,6 @@ typedef struct { UE_list_t list; int num_UEs; boolean_t active[MAX_MOBILES_PER_ENB]; - - /// Sorting criteria for the UE list in the MAC preprocessor - uint16_t sorting_criteria[MAX_NUM_SLICES][CR_NUM]; } UE_info_t; /*! \brief deleting control information*/ @@ -1171,101 +1165,6 @@ typedef struct { int tail_freelist; ///the tail position of the delete list } UE_free_list_t; -/** - * slice specific scheduler for the DL - */ -typedef void (*slice_scheduler_dl)(module_id_t mod_id, - int slice_idx, - frame_t frame, - sub_frame_t subframe, - int *mbsfn_flag); - -typedef struct { - slice_id_t id; - - /// RB share for each slice - float pct; - - /// whether this slice is isolated from the others - int isol; - - int prio; - - /// Frequency ranges for slice positioning - int pos_low; - int pos_high; - - // max mcs for each slice - int maxmcs; - - /// criteria for sorting policies of the slices - uint32_t sorting; - - /// Accounting policy (just greedy(1) or fair(0) setting for now) - int accounting; - - /// name of available scheduler - char *sched_name; - - /// pointer to the slice specific scheduler in DL - slice_scheduler_dl sched_cb; - -} slice_sched_conf_dl_t; - -typedef void (*slice_scheduler_ul)(module_id_t mod_id, - int slice_idx, - frame_t frame, - sub_frame_t subframe, - unsigned char sched_subframe, - uint16_t *first_rb); - -typedef struct { - slice_id_t id; - - /// RB share for each slice - float pct; - - // MAX MCS for each slice - int maxmcs; - - /// criteria for sorting policies of the slices - uint32_t sorting; - - /// starting RB (RB offset) of UL scheduling - int first_rb; - - /// name of available scheduler - char *sched_name; - - /// pointer to the slice specific scheduler in UL - slice_scheduler_ul sched_cb; - -} slice_sched_conf_ul_t; - - -typedef struct { - /// counter used to indicate when all slices have pre-allocated UEs - //int slice_counter; - - /// indicates whether remaining RBs after first intra-slice allocation will - /// be allocated to UEs of the same slice - int intraslice_share_active; - /// indicates whether remaining RBs after slice allocation will be - /// allocated to UEs of another slice. Isolated slices will be ignored - int interslice_share_active; - - /// number of active DL slices - int n_dl; - slice_sched_conf_dl_t dl[MAX_NUM_SLICES]; - - /// number of active UL slices - int n_ul; - slice_sched_conf_ul_t ul[MAX_NUM_SLICES]; - - /// common rb allocation list between slices - uint8_t rballoc_sub[NFAPI_CC_MAX][N_RBG_MAX]; -} slice_info_t; - /** * describes contiguous RBs */ @@ -1421,9 +1320,6 @@ typedef struct eNB_MAC_INST_s { uint32_t ul_handle; UE_info_t UE_info; - /// slice-related configuration - slice_info_t slice_info; - ///subband bitmap configuration SBMAP_CONF sbmap_conf; /// CCE table used to build DCI scheduling information diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 2cb86c25af..61251ef088 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -187,8 +187,6 @@ void add_msg3(module_id_t module_idP, int CC_id, RA_t *ra, frame_t frameP, void init_UE_info(UE_info_t *UE_info); -void init_slice_info(slice_info_t *sli); - int mac_top_init(int eMBMS_active, char *uecap_xer, uint8_t cba_group_active, uint8_t HO_active); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 294eb12159..35b5136889 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -57,32 +57,6 @@ void init_UE_info(UE_info_t *UE_info) memset(UE_info->active, 0, sizeof(UE_info->active)); } -void init_slice_info(slice_info_t *sli) -{ - sli->intraslice_share_active = 1; - sli->interslice_share_active = 1; - - sli->n_dl = 1; - memset(sli->dl, 0, sizeof(slice_sched_conf_dl_t) * MAX_NUM_SLICES); - sli->dl[0].pct = 1.0; - sli->dl[0].prio = 10; - sli->dl[0].pos_high = N_RBG_MAX; - sli->dl[0].maxmcs = 28; - sli->dl[0].sorting = 0x012345; - sli->dl[0].sched_name = "schedule_ue_spec"; - sli->dl[0].sched_cb = dlsym(NULL, sli->dl[0].sched_name); - AssertFatal(sli->dl[0].sched_cb, "DLSCH scheduler callback is NULL\n"); - - sli->n_ul = 1; - memset(sli->ul, 0, sizeof(slice_sched_conf_ul_t) * MAX_NUM_SLICES); - sli->ul[0].pct = 1.0; - sli->ul[0].maxmcs = 20; - sli->ul[0].sorting = 0x0123; - sli->ul[0].sched_name = "schedule_ulsch_rnti"; - sli->ul[0].sched_cb = dlsym(NULL, sli->ul[0].sched_name); - AssertFatal(sli->ul[0].sched_cb, "ULSCH scheduler callback is NULL\n"); -} - void mac_top_init_eNB(void) { module_id_t i, j; @@ -139,7 +113,6 @@ void mac_top_init_eNB(void) mac[i]->ul_algo = *(default_sched_ul_algo_t *) d; mac[i]->ul_algo.data = mac[i]->ul_algo.setup(); init_UE_info(&mac[i]->UE_info); - init_slice_info(&mac[i]->slice_info); } RC.mac = mac; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index fc2a2e18cf..b73b074c37 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -68,8 +68,6 @@ extern RAN_CONTEXT_t RC; -extern int n_active_slices; - // Note the 2 scs values in the table names represent resp. scs_common and pdcch_scs /// LUT for the number of symbols in the coreset indexed by coreset index (4 MSB rmsi_pdcch_config) uint8_t nr_coreset_nsymb_pdcch_type_0_scs_15_15[15] = {2,2,2,3,3,3,1,1,2,2,3,3,1,2,3}; From a74f4c1238b03a31fafba5d1552f0b08ac184a3d Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 14 Apr 2020 16:17:56 +0200 Subject: [PATCH 085/171] Delete old protobuf slice types flex_slice_{dl,ul} --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 206 +----- .../MAC/flexran_agent_mac_internal.c | 666 +----------------- .../MAC/flexran_agent_mac_internal.h | 20 - .../flexran_agent_mac_slice_verification.c | 343 --------- .../flexran_agent_mac_slice_verification.h | 6 - .../ENB_APP/MESSAGES/V2/config_common.proto | 77 -- .../ENB_APP/MESSAGES/V2/config_messages.proto | 8 - openair2/ENB_APP/flexran_agent_common.c | 20 +- openair2/ENB_APP/flexran_agent_ran_api.c | 178 +---- openair2/ENB_APP/flexran_agent_ran_api.h | 149 +--- 10 files changed, 47 insertions(+), 1626 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 669eb33ea3..4800fccea9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1468,10 +1468,12 @@ void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id, ue_conf->rnti = flexran_get_mac_ue_crnti(mod_id, ue_id); ue_conf->has_rnti = 1; - ue_conf->dl_slice_id = flexran_get_ue_dl_slice_id(mod_id, ue_id); - ue_conf->has_dl_slice_id = 1; - ue_conf->ul_slice_id = flexran_get_ue_ul_slice_id(mod_id, ue_id); - ue_conf->has_ul_slice_id = 1; + int dl_id = flexran_get_ue_dl_slice_id(mod_id, ue_id); + ue_conf->dl_slice_id = dl_id; + ue_conf->has_dl_slice_id = dl_id >= 0; + int ul_id = flexran_get_ue_ul_slice_id(mod_id, ue_id); + ue_conf->ul_slice_id = ul_id; + ue_conf->has_ul_slice_id = ul_id >= 0; ue_conf->ue_aggregated_max_bitrate_ul = flexran_get_ue_aggregated_max_bitrate_ul(mod_id, ue_id); ue_conf->has_ue_aggregated_max_bitrate_ul = 1; @@ -1576,149 +1578,24 @@ void flexran_create_config_structures(mid_t mod_id) sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); if (!slice_config[mod_id] || !sc_update[mod_id]) return; - flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); - flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); + //flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); + //flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); for (i = 0; i < n_dl; i++) { - flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); + //flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); + //flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); } for (i = 0; i < m_ul; i++) { - flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); + //flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); + //flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); } } void flexran_check_and_remove_slices(mid_t mod_id) { - Protocol__FlexDlSlice **dl = sc_update[mod_id]->dl; - Protocol__FlexDlSlice **dlreal = slice_config[mod_id]->dl; - int i = 0; - while (i < sc_update[mod_id]->n_dl) { - /* remove slices whose percentage is zero */ - if (dl[i]->percentage > 0) { - ++i; - continue; - } - if (flexran_remove_dl_slice(mod_id, i) < 1) { - LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", - mod_id, i, dl[i]->id); - ++i; - continue; - } - LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", - mod_id, i, dl[i]->id); - if (dl[i]->n_sorting > 0) free(dl[i]->sorting); - free(dl[i]->scheduler_name); - if (dlreal[i]->n_sorting > 0) { - dlreal[i]->n_sorting = 0; - free(dlreal[i]->sorting); - } - free(dlreal[i]->scheduler_name); - --sc_update[mod_id]->n_dl; - --slice_config[mod_id]->n_dl; - const size_t last = sc_update[mod_id]->n_dl; - /* we need to memcpy the higher slice to the position we just deleted */ - memcpy(dl[i], dl[last], sizeof(*dl[last])); - memset(dl[last], 0, sizeof(*dl[last])); - memcpy(dlreal[i], dlreal[last], sizeof(*dlreal[last])); - memset(dlreal[last], 0, sizeof(*dlreal[last])); - /* dont increase i but recheck the slice which has been copied to here */ - } - Protocol__FlexUlSlice **ul = sc_update[mod_id]->ul; - Protocol__FlexUlSlice **ulreal = slice_config[mod_id]->ul; - i = 0; - while (i < sc_update[mod_id]->n_ul) { - if (ul[i]->percentage > 0) { - ++i; - continue; - } - if (flexran_remove_ul_slice(mod_id, i) < 1) { - LOG_W(FLEXRAN_AGENT, "[%d] can not remove slice index %d ID %d\n", - mod_id, i, ul[i]->id); - ++i; - continue; - } - LOG_I(FLEXRAN_AGENT, "[%d] removed slice index %d ID %d\n", - mod_id, i, ul[i]->id); - free(ul[i]->scheduler_name); - free(ulreal[i]->scheduler_name); - --sc_update[mod_id]->n_ul; - --slice_config[mod_id]->n_ul; - const size_t last = sc_update[mod_id]->n_ul; - /* see DL remarks */ - memcpy(ul[i], ul[last], sizeof(*ul[last])); - memset(ul[last], 0, sizeof(*ul[last])); - memcpy(ulreal[i], ulreal[last], sizeof(*ulreal[last])); - memset(ulreal[last], 0, sizeof(*ulreal[last])); - /* dont increase i but recheck the slice which has been copied to here */ - } } void flexran_agent_slice_update(mid_t mod_id) { - int i; - int changes = 0; - - if (perform_slice_config_update_count <= 0) return; - perform_slice_config_update_count--; - - pthread_mutex_lock(&sc_update_mtx); - - if (!slice_config[mod_id]) { - /* if the configuration does not exist for agent, create from eNB structure - * and exit */ - flexran_create_config_structures(mod_id); - pthread_mutex_unlock(&sc_update_mtx); - return; - } - - /********* read existing config *********/ - /* simply update slice_config all the time and write new config - * (apply_new_slice_dl_config() only updates if changes are necessary) */ - slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); - slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); - for (i = 0; i < slice_config[mod_id]->n_dl; i++) { - flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - } - for (i = 0; i < slice_config[mod_id]->n_ul; i++) { - flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - } - - /********* write new config *********/ - /* check for removal (sc_update[X]->dl[Y].percentage == 0) - * and update sc_update & slice_config accordingly */ - flexran_check_and_remove_slices(mod_id); - - /* create new DL and UL slices if necessary */ - for (i = slice_config[mod_id]->n_dl; i < sc_update[mod_id]->n_dl; i++) { - flexran_create_dl_slice(mod_id, sc_update[mod_id]->dl[i]->id); - } - for (i = slice_config[mod_id]->n_ul; i < sc_update[mod_id]->n_ul; i++) { - flexran_create_ul_slice(mod_id, sc_update[mod_id]->ul[i]->id); - } - slice_config[mod_id]->n_dl = flexran_get_num_dl_slices(mod_id); - slice_config[mod_id]->n_ul = flexran_get_num_ul_slices(mod_id); - changes += apply_new_slice_config(mod_id, slice_config[mod_id], sc_update[mod_id]); - for (i = 0; i < slice_config[mod_id]->n_dl; i++) { - changes += apply_new_slice_dl_config(mod_id, - slice_config[mod_id]->dl[i], - sc_update[mod_id]->dl[i]); - flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - } - for (i = 0; i < slice_config[mod_id]->n_ul; i++) { - changes += apply_new_slice_ul_config(mod_id, - slice_config[mod_id]->ul[i], - sc_update[mod_id]->ul[i]); - flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - } - flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); - if (n_ue_slice_assoc_updates > 0) { - changes += apply_ue_slice_assoc_update(mod_id); - } - if (changes > 0) - LOG_I(FLEXRAN_AGENT, "[%d] slice configuration: applied %d changes\n", mod_id, changes); - - pthread_mutex_unlock(&sc_update_mtx); } Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) @@ -1727,69 +1604,10 @@ Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) Protocol__FlexSliceConfig *config = NULL; pthread_mutex_lock(&sc_update_mtx); - config = flexran_agent_create_slice_config(slice_config[mod_id]->n_dl, - slice_config[mod_id]->n_ul); if (!config) { pthread_mutex_unlock(&sc_update_mtx); return NULL; } - config->has_intraslice_share_active = 1; - config->intraslice_share_active = slice_config[mod_id]->intraslice_share_active; - config->has_interslice_share_active = 1; - config->interslice_share_active = slice_config[mod_id]->interslice_share_active; - for (int i = 0; i < slice_config[mod_id]->n_dl; ++i) { - if (!config->dl[i]) continue; - config->dl[i]->has_id = 1; - config->dl[i]->id = slice_config[mod_id]->dl[i]->id; - config->dl[i]->has_label = 1; - config->dl[i]->label = slice_config[mod_id]->dl[i]->label; - config->dl[i]->has_percentage = 1; - config->dl[i]->percentage = slice_config[mod_id]->dl[i]->percentage; - config->dl[i]->has_isolation = 1; - config->dl[i]->isolation = slice_config[mod_id]->dl[i]->isolation; - config->dl[i]->has_priority = 1; - config->dl[i]->priority = slice_config[mod_id]->dl[i]->priority; - config->dl[i]->has_position_low = 1; - config->dl[i]->position_low = slice_config[mod_id]->dl[i]->position_low; - config->dl[i]->has_position_high = 1; - config->dl[i]->position_high = slice_config[mod_id]->dl[i]->position_high; - config->dl[i]->has_maxmcs = 1; - config->dl[i]->maxmcs = slice_config[mod_id]->dl[i]->maxmcs; - config->dl[i]->n_sorting = slice_config[mod_id]->dl[i]->n_sorting; - config->dl[i]->sorting = calloc(config->dl[i]->n_sorting, sizeof(Protocol__FlexDlSorting)); - if (!config->dl[i]->sorting) config->dl[i]->n_sorting = 0; - for (int j = 0; j < config->dl[i]->n_sorting; ++j) - config->dl[i]->sorting[j] = slice_config[mod_id]->dl[i]->sorting[j]; - config->dl[i]->has_accounting = 1; - config->dl[i]->accounting = slice_config[mod_id]->dl[i]->accounting; - config->dl[i]->scheduler_name = strdup(slice_config[mod_id]->dl[i]->scheduler_name); - } - for (int i = 0; i < slice_config[mod_id]->n_ul; ++i) { - if (!config->ul[i]) continue; - config->ul[i]->has_id = 1; - config->ul[i]->id = slice_config[mod_id]->ul[i]->id; - config->ul[i]->has_label = 1; - config->ul[i]->label = slice_config[mod_id]->ul[i]->label; - config->ul[i]->has_percentage = 1; - config->ul[i]->percentage = slice_config[mod_id]->ul[i]->percentage; - config->ul[i]->has_isolation = 1; - config->ul[i]->isolation = slice_config[mod_id]->ul[i]->isolation; - config->ul[i]->has_priority = 1; - config->ul[i]->priority = slice_config[mod_id]->ul[i]->priority; - config->ul[i]->has_first_rb = 1; - config->ul[i]->first_rb = slice_config[mod_id]->ul[i]->first_rb; - config->ul[i]->has_maxmcs = 1; - config->ul[i]->maxmcs = slice_config[mod_id]->ul[i]->maxmcs; - config->ul[i]->n_sorting = slice_config[mod_id]->ul[i]->n_sorting; - config->ul[i]->sorting = calloc(config->ul[i]->n_sorting, sizeof(Protocol__FlexUlSorting)); - if (!config->ul[i]->sorting) config->ul[i]->n_sorting = 0; - for (int j = 0; j < config->ul[i]->n_sorting; ++j) - config->ul[i]->sorting[j] = slice_config[mod_id]->ul[i]->sorting[j]; - config->ul[i]->has_accounting = 1; - config->ul[i]->accounting = slice_config[mod_id]->ul[i]->accounting; - config->ul[i]->scheduler_name = strdup(slice_config[mod_id]->ul[i]->scheduler_name); - } - pthread_mutex_unlock(&sc_update_mtx); return config; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 84a28683b7..4c80c561ee 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1027,666 +1027,18 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) { - int i; Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig)); if (!fsc) return NULL; protocol__flex_slice_config__init(fsc); - /* say there are n_dl slices but reserve memory for up to 10 so - * we don't need to reserve again later */ - fsc->n_dl = n_dl; - fsc->dl = calloc(10, sizeof(Protocol__FlexDlSlice *)); - if (!fsc->dl) fsc->n_dl = 0; - for (i = 0; i < 10; i++) { - fsc->dl[i] = malloc(sizeof(Protocol__FlexDlSlice)); - if (!fsc->dl[i]) continue; - protocol__flex_dl_slice__init(fsc->dl[i]); - } - - /* as above */ - fsc->n_ul = m_ul; - fsc->ul = calloc(10, sizeof(Protocol__FlexUlSlice *)); - if (!fsc->ul) fsc->n_ul = 0; - for (i = 0; i < 10; i++) { - fsc->ul[i] = malloc(sizeof(Protocol__FlexUlSlice)); - if (!fsc->ul[i]) continue; - protocol__flex_ul_slice__init(fsc->ul[i]); - } + /* TODO */ return fsc; } -void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s) -{ - s->intraslice_share_active = flexran_get_intraslice_sharing_active(mod_id); - s->has_intraslice_share_active = 1; - s->interslice_share_active = flexran_get_interslice_sharing_active(mod_id); - s->has_interslice_share_active = 1; -} - -void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice) -{ - dl_slice->id = flexran_get_dl_slice_id(mod_id, slice_idx); - dl_slice->has_id = 1; - /* read label from corresponding sc_update entry or give default */ - dl_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; - dl_slice->has_label = 1; - for (int i = 0; i < sc_update[mod_id]->n_dl; i++) { - if (sc_update[mod_id]->dl[i]->id == dl_slice->id - && sc_update[mod_id]->dl[i]->has_label) { - dl_slice->label = sc_update[mod_id]->dl[i]->label; - break; - } - } - dl_slice->percentage = flexran_get_dl_slice_percentage(mod_id, slice_idx); - dl_slice->has_percentage = 1; - dl_slice->isolation = flexran_get_dl_slice_isolation(mod_id, slice_idx); - dl_slice->has_isolation = 1; - dl_slice->priority = flexran_get_dl_slice_priority(mod_id, slice_idx); - dl_slice->has_priority = 1; - dl_slice->position_low = flexran_get_dl_slice_position_low(mod_id, slice_idx); - dl_slice->has_position_low = 1; - dl_slice->position_high = flexran_get_dl_slice_position_high(mod_id, slice_idx); - dl_slice->has_position_high = 1; - dl_slice->maxmcs = flexran_get_dl_slice_maxmcs(mod_id, slice_idx); - dl_slice->has_maxmcs = 1; - dl_slice->n_sorting = flexran_get_dl_slice_sorting(mod_id, slice_idx, &dl_slice->sorting); - if (dl_slice->n_sorting < 1) dl_slice->sorting = NULL; - dl_slice->accounting = flexran_get_dl_slice_accounting_policy(mod_id, slice_idx); - dl_slice->has_accounting = 1; - const char *s_name = flexran_get_dl_slice_scheduler(mod_id, slice_idx); - if (!dl_slice->scheduler_name - || strcmp(dl_slice->scheduler_name, s_name) != 0) { - dl_slice->scheduler_name = realloc(dl_slice->scheduler_name, strlen(s_name) + 1); - strcpy(dl_slice->scheduler_name, s_name); - } -} - -void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice) -{ - ul_slice->id = flexran_get_ul_slice_id(mod_id, slice_idx); - ul_slice->has_id = 1; - /* read label from corresponding sc_update entry or give default */ - ul_slice->label = PROTOCOL__FLEX_SLICE_LABEL__xMBB; - ul_slice->has_label = 1; - for (int i = 0; i < sc_update[mod_id]->n_ul; i++) { - if (sc_update[mod_id]->ul[i]->id == ul_slice->id - && sc_update[mod_id]->ul[i]->has_label) { - ul_slice->label = sc_update[mod_id]->ul[i]->label; - break; - } - } - ul_slice->percentage = flexran_get_ul_slice_percentage(mod_id, slice_idx); - ul_slice->has_percentage = 1; - /*ul_slice->isolation = flexran_get_ul_slice_isolation(mod_id, slice_idx);*/ - ul_slice->has_isolation = 0; - /*ul_slice->priority = flexran_get_ul_slice_priority(mod_id, slice_idx);*/ - ul_slice->has_priority = 0; - ul_slice->first_rb = flexran_get_ul_slice_first_rb(mod_id, slice_idx); - ul_slice->has_first_rb = 1; - /*ul_slice-> = flexran_get_ul_slice_length_rb(mod_id, slice_idx); - ul_slice->has_length_rb = 0;*/ - ul_slice->maxmcs = flexran_get_ul_slice_maxmcs(mod_id, slice_idx); - ul_slice->has_maxmcs = 1; - ul_slice->n_sorting = 0; - /*if (ul_slice->sorting) { - free(ul_slice->sorting); - ul_slice->sorting = NULL; - } - ul_slice->n_sorting = flexran_get_ul_slice_sorting(mod_id, slice_idx, &ul_slice->sorting); - if (ul_slice->n_sorting < 1) ul_slice->sorting = NULL;*/ - /*ul_slice->accounting = flexran_get_ul_slice_accounting_policy(mod_id, slice_idx);*/ - ul_slice->has_accounting = 0; - const char *s_name = flexran_get_ul_slice_scheduler(mod_id, slice_idx); - if (!ul_slice->scheduler_name - || strcmp(ul_slice->scheduler_name, s_name) != 0) { - ul_slice->scheduler_name = realloc(ul_slice->scheduler_name, strlen(s_name) + 1); - strcpy(ul_slice->scheduler_name, s_name); - } -} - -int check_dl_sorting_update(Protocol__FlexDlSlice *old, Protocol__FlexDlSlice *new) -{ - /* sorting_update => true when old->n_sorting == 0 or different numbers of - * elements; otherwise will check * element-wise */ - int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); - for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { - sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); - } - return sorting_update; -} - -int check_ul_sorting_update(Protocol__FlexUlSlice *old, Protocol__FlexUlSlice *new) -{ - /* sorting_update => true when old->n_sorting == 0 or different numbers of - * elements; otherwise will check * element-wise */ - int sorting_update = old->n_sorting == 0 || (old->n_sorting != new->n_sorting); - for (int i = 0; i < old->n_sorting && !sorting_update; ++i) { - sorting_update = sorting_update || (new->sorting[i] != old->sorting[i]); - } - return sorting_update; -} - -void overwrite_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *exist, Protocol__FlexSliceConfig *update) -{ - if (update->has_intraslice_share_active - && exist->intraslice_share_active != update->intraslice_share_active) { - LOG_I(FLEXRAN_AGENT, "[%d] update intraslice_share_active: %d -> %d\n", - mod_id, exist->intraslice_share_active, update->intraslice_share_active); - exist->intraslice_share_active = update->intraslice_share_active; - exist->has_intraslice_share_active = 1; - } - if (update->has_interslice_share_active - && exist->interslice_share_active != update->interslice_share_active) { - LOG_I(FLEXRAN_AGENT, "[%d] update interslice_share_active: %d -> %d\n", - mod_id, exist->interslice_share_active, update->interslice_share_active); - exist->interslice_share_active = update->interslice_share_active; - exist->has_interslice_share_active = 1; - } -} - -void overwrite_slice_config_dl(mid_t mod_id, Protocol__FlexDlSlice *exist, Protocol__FlexDlSlice *update) -{ - if (update->label != exist->label) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update label: %d -> %d\n", - mod_id, update->id, exist->label, update->label); - exist->label = update->label; - exist->has_label = 1; - } - if (update->percentage != exist->percentage) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update percentage: %d -> %d\n", - mod_id, update->id, exist->percentage, update->percentage); - exist->percentage = update->percentage; - exist->has_percentage = 1; - } - if (update->isolation != exist->isolation) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update isolation: %d -> %d\n", - mod_id, update->id, exist->isolation, update->isolation); - exist->isolation = update->isolation; - exist->has_isolation = 1; - } - if (update->priority != exist->priority) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update priority: %d -> %d\n", - mod_id, update->id, exist->priority, update->priority); - exist->priority = update->priority; - exist->has_priority = 1; - } - if (update->position_low != exist->position_low) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_low: %d -> %d\n", - mod_id, update->id, exist->position_low, update->position_low); - exist->position_low = update->position_low; - exist->has_position_low = 1; - } - if (update->position_high != exist->position_high) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update position_high: %d -> %d\n", - mod_id, update->id, exist->position_high, update->position_high); - exist->position_high = update->position_high; - exist->has_position_high = 1; - } - if (update->maxmcs != exist->maxmcs) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update maxmcs: %d -> %d\n", - mod_id, update->id, exist->maxmcs, update->maxmcs); - exist->maxmcs = update->maxmcs; - exist->has_maxmcs = 1; - } - if (check_dl_sorting_update(exist, update)) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update sorting array\n", mod_id, update->id); - if (exist->n_sorting != update->n_sorting) { - exist->n_sorting = update->n_sorting; - exist->sorting = realloc(exist->sorting, exist->n_sorting * sizeof(Protocol__FlexDlSorting)); - if (!exist->sorting) exist->n_sorting = 0; - } - for (int i = 0; i < exist->n_sorting; i++) - exist->sorting[i] = update->sorting[i]; - } - if (update->accounting != exist->accounting) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update accounting: %d -> %d\n", - mod_id, update->id, exist->accounting, update->accounting); - exist->accounting = update->accounting; - exist->has_accounting = 1; - } - if (!exist->scheduler_name - || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_I(FLEXRAN_AGENT, "[%d][DL slice %d] update scheduler: %s -> %s\n", - mod_id, update->id, exist->scheduler_name, update->scheduler_name); - if (exist->scheduler_name) free(exist->scheduler_name); - exist->scheduler_name = strdup(update->scheduler_name); - } -} - -void overwrite_slice_config_ul(mid_t mod_id, Protocol__FlexUlSlice *exist, Protocol__FlexUlSlice *update) -{ - if (update->label != exist->label) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update label: %d -> %d\n", - mod_id, update->id, exist->label, update->label); - exist->label = update->label; - exist->has_label = 1; - } - if (update->percentage != exist->percentage) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update percentage: %d -> %d\n", - mod_id, update->id, exist->percentage, update->percentage); - exist->percentage = update->percentage; - exist->has_percentage = 1; - } - if (update->isolation != exist->isolation) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update isolation: %d -> %d\n", - mod_id, update->id, exist->isolation, update->isolation); - exist->isolation = update->isolation; - exist->has_isolation = 1; - } - if (update->priority != exist->priority) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update priority: %d -> %d\n", - mod_id, update->id, exist->priority, update->priority); - exist->priority = update->priority; - exist->has_priority = 1; - } - if (update->first_rb != exist->first_rb) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update first_rb: %d -> %d\n", - mod_id, update->id, exist->first_rb, update->first_rb); - exist->first_rb = update ->first_rb; - exist->has_first_rb = 1; - } - /*if (update->lenght_rb != exist->lenght_rb) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update lenght_rb: %d -> %d\n", - mod_id, update->id, exist->lenght_rb, update->lenght_rb); - exist->lenght_rb = update->lenght_rb; - }*/ - if (update->maxmcs != exist->maxmcs) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update maxmcs: %d -> %d\n", - mod_id, update->id, exist->maxmcs, update->maxmcs); - exist->maxmcs = update->maxmcs; - exist->has_maxmcs = 1; - } - /* TODO - int sorting_update = 0; - int n = min(exist->n_sorting, update->n_sorting); - int i = 0; - while (i < n && !sorting_update) { - sorting_update = sorting_update || (update->sorting[i] != exist->sorting[i]); - i++; - } - if (sorting_update) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update sorting array\n", update->id, mod_id); - if (exist->n_sorting != update->n_sorting) - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] only writing %d elements\n", - mod_id, update->id, n); - for (i = 0; i < n; i++) - exist->sorting[i] = update->sorting[i]; - } - */ - if (update->accounting != exist->accounting) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update accounting: %d -> %d\n", - mod_id, update->id, exist->accounting, update->accounting); - exist->accounting = update->accounting; - exist->has_accounting = 1; - } - if (!exist->scheduler_name - || strcmp(update->scheduler_name, exist->scheduler_name) != 0) { - LOG_I(FLEXRAN_AGENT, "[%d][UL slice %d] update scheduler: %s -> %s\n", - mod_id, update->id, exist->scheduler_name, update->scheduler_name); - if (exist->scheduler_name) free(exist->scheduler_name); - exist->scheduler_name = strdup(update->scheduler_name); - } -} - -void fill_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *s, Protocol__FlexDlSlice *from) -{ - /* function fills slice with information from another slice or with default - * values (currently slice 0) if from is NULL */ - /* TODO fill the slice depending on the chosen label */ - if (!s->has_label) { - s->has_label = 1; - s->label = from ? from->label : sc_update[mod_id]->dl[0]->label; - } - if (!s->has_percentage) { - s->has_percentage = 1; - s->percentage = from ? from->percentage : sc_update[mod_id]->dl[0]->percentage; - } - if (!s->has_isolation) { - s->has_isolation = 1; - s->isolation = from ? from->isolation : sc_update[mod_id]->dl[0]->isolation; - } - if (!s->has_priority) { - s->has_priority = 1; - s->priority = from ? from->priority : sc_update[mod_id]->dl[0]->priority; - } - if (!s->has_position_low) { - s->has_position_low = 1; - s->position_low = from ? from->position_low : sc_update[mod_id]->dl[0]->position_low; - } - if (!s->has_position_high) { - s->has_position_high = 1; - s->position_high = from ? from->position_high : sc_update[mod_id]->dl[0]->position_high; - } - if (!s->has_maxmcs) { - s->has_maxmcs = 1; - s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->dl[0]->maxmcs; - } - if (s->n_sorting == 0) { - s->n_sorting = from ? from->n_sorting : sc_update[mod_id]->dl[0]->n_sorting; - s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexDlSorting)); - if (!s->sorting) s->n_sorting = 0; - for (int i = 0; i < s->n_sorting; ++i) - s->sorting[i] = from ? from->sorting[i] : sc_update[0]->dl[0]->sorting[i]; - } - if (!s->has_accounting) { - s->accounting = from ? from->accounting : sc_update[mod_id]->dl[0]->accounting; - } - if (!s->scheduler_name) { - s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->dl[0]->scheduler_name); - } -} - -Protocol__FlexDlSlice *get_existing_dl_slice(mid_t mod_id, int id) -{ - for (int i = 0; i < sc_update[mod_id]->n_dl; ++i) { - if (id == sc_update[mod_id]->dl[i]->id) { - return sc_update[mod_id]->dl[i]; - } - } - return NULL; -} - -Protocol__FlexDlSlice *create_new_dl_slice(mid_t mod_id, int id) -{ - LOG_I(FLEXRAN_AGENT, - "[%d] Creating DL slice with ID %d, taking default values from DL slice 0\n", - mod_id, id); - Protocol__FlexDlSlice *to = sc_update[mod_id]->dl[sc_update[mod_id]->n_dl]; - sc_update[mod_id]->n_dl++; - AssertFatal(sc_update[mod_id]->n_dl <= 10, - "cannot create more than 10\n"); - to->id = id; - return to; -} - -void fill_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *s, Protocol__FlexUlSlice *from) -{ - /* function fills slice with information from another slice or with default - * values (currently slice 0) if from is NULL */ - /* TODO fill the slice depending on the chosen label */ - if (!s->has_label) { - s->has_label = 1; - s->label = from ? from->label : sc_update[mod_id]->ul[0]->label; - } - if (!s->has_percentage) { - s->has_percentage = 1; - s->percentage = from ? from->percentage : sc_update[mod_id]->ul[0]->percentage; - } - if (!s->has_isolation) { - s->has_isolation = 1; - s->isolation = from ? from->isolation : sc_update[mod_id]->ul[0]->isolation; - } - if (!s->has_priority) { - s->has_priority = 1; - s->priority = from ? from->priority : sc_update[mod_id]->ul[0]->priority; - } - if (!s->has_first_rb) { - s->has_first_rb = 1; - s->first_rb = from ? from->first_rb : sc_update[mod_id]->ul[0]->first_rb; - } - if (!s->has_maxmcs) { - s->has_maxmcs = 1; - s->maxmcs = from ? from->maxmcs : sc_update[mod_id]->ul[0]->maxmcs; - } - if (s->n_sorting == 0) { - s->n_sorting = from ? from->n_sorting : sc_update[0]->ul[0]->n_sorting; - s->sorting = calloc(s->n_sorting, sizeof(Protocol__FlexUlSorting)); - if (!s->sorting) s->n_sorting = 0; - for (int i = 0; i < s->n_sorting; ++i) - s->sorting[i] = from ? from->sorting[i] : sc_update[0]->ul[0]->sorting[i]; - } - if (!s->has_accounting) { - s->accounting = from ? from->accounting : sc_update[0]->ul[0]->accounting; - } - if (!s->scheduler_name) { - s->scheduler_name = strdup(from ? from->scheduler_name : sc_update[mod_id]->ul[0]->scheduler_name); - } -} - -Protocol__FlexUlSlice *get_existing_ul_slice(mid_t mod_id, int id) -{ - for (int i = 0; i < sc_update[mod_id]->n_ul; ++i) { - if (id == sc_update[mod_id]->ul[i]->id) { - return sc_update[mod_id]->ul[i]; - } - } - return NULL; -} - -Protocol__FlexUlSlice *create_new_ul_slice(mid_t mod_id, int id) -{ - LOG_I(FLEXRAN_AGENT, - "[%d] Creating UL slice with ID %d, taking default values from UL slice 0\n", - mod_id, id); - Protocol__FlexUlSlice *to = sc_update[mod_id]->ul[sc_update[mod_id]->n_ul]; - sc_update[mod_id]->n_ul++; - AssertFatal(sc_update[mod_id]->n_ul <= 10, - "cannot create more than 10\n"); - to->id = id; - return to; -} - void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) { - int verified = 1; - if (!sc_update[mod_id]) { - LOG_E(FLEXRAN_AGENT, "Can not update slice policy (no existing slice profile)\n"); - return; - } - - pthread_mutex_lock(&sc_update_mtx); - /* no need for tests in the current state as there are only two protobuf - * bools for intra-/interslice sharing. The function applies new values if - * applicable */ - overwrite_slice_config(mod_id, sc_update[mod_id], sup); - - if (sup->n_dl == 0) { - LOG_I(FLEXRAN_AGENT, "[%d] no DL slice configuration in flex_slice_config message\n", mod_id); - } else { - /* verify slice parameters */ - for (int i = 0; i < sup->n_dl; i++) { - if (!sup->dl[i]->has_id) { - verified = 0; - break; - } - Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); - /* fill up so that the slice is complete. This way, we don't need to - * worry about it later */ - fill_dl_slice(mod_id, sup->dl[i], dls); - verified = verified && flexran_verify_dl_slice(mod_id, sup->dl[i]); - if (!verified) break; - } - - /* verify group-based parameters (e.g. sum percentage should not exceed - * 100%). Can be used to perform admission control */ - verified = verified && flexran_verify_group_dl_slices(mod_id, - sc_update[mod_id]->dl, sc_update[mod_id]->n_dl, sup->dl, sup->n_dl); - - if (verified) { - for (int i = 0; i < sup->n_dl; i++) { - /* if all verifications were successful, get existing slice for ID or - * create new one and overwrite with the update */ - Protocol__FlexDlSlice *dls = get_existing_dl_slice(mod_id, sup->dl[i]->id); - if (!dls) dls = create_new_dl_slice(mod_id, sup->dl[i]->id); - overwrite_slice_config_dl(mod_id, dls, sup->dl[i]); - } - } else { - LOG_E(FLEXRAN_AGENT, "[%d] DL slice verification failed, refusing application\n", mod_id); - } - } - - verified = 1; - if (sup->n_ul == 0) { - LOG_I(FLEXRAN_AGENT, "[%d] no UL slice configuration in flex_slice_config message\n", mod_id); - } else { - /* verify slice parameters */ - for (int i = 0; i < sup->n_ul; i++) { - if (!sup->ul[i]->has_id) { - verified = 0; - break; - } - Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); - /* fill up so that the slice is complete. This way, we don't need to - * worry about it later */ - fill_ul_slice(mod_id, sup->ul[i], uls); - verified = verified && flexran_verify_ul_slice(mod_id, sup->ul[i]); - if (!verified) break; - } - - /* verify group-based parameters (e.g. sum percentage should not exceed - * 100%). Can be used to perform admission control */ - verified = verified && flexran_verify_group_ul_slices(mod_id, - sc_update[mod_id]->ul, sc_update[mod_id]->n_ul, sup->ul, sup->n_ul); - - if (verified) { - for (int i = 0; i < sup->n_ul; i++) { - /* if all verifications were successful, get existing slice for ID or - * create new one and overwrite with the update */ - Protocol__FlexUlSlice *uls = get_existing_ul_slice(mod_id, sup->ul[i]->id); - if (!uls) uls = create_new_ul_slice(mod_id, sup->ul[i]->id); - overwrite_slice_config_ul(mod_id, uls, sup->ul[i]); - } - } else { - LOG_E(FLEXRAN_AGENT, "[%d] UL slice verification failed, refusing application\n", mod_id); - } - } - pthread_mutex_unlock(&sc_update_mtx); - - perform_slice_config_update_count = 1; } -int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news) -{ - /* not setting the old configuration is intentional, as it will be picked up - * later when reading the configuration. There is thus a direct feedback - * whether it has been set. */ - int changes = 0; - if (olds->intraslice_share_active != news->intraslice_share_active) { - flexran_set_intraslice_sharing_active(mod_id, news->intraslice_share_active); - changes++; - } - if (olds->interslice_share_active != news->interslice_share_active) { - flexran_set_interslice_sharing_active(mod_id, news->interslice_share_active); - changes++; - } - return changes; -} - -int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc) -{ - /* not setting the old configuration is intentional, as it will be picked up - * later when reading the configuration. There is thus a direct feedback - * whether it has been set. */ - int changes = 0; - int slice_idx = flexran_find_dl_slice(mod_id, newc->id); - if (slice_idx < 0) { - LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); - return 0; - } - if (oldc->percentage != newc->percentage) { - flexran_set_dl_slice_percentage(mod_id, slice_idx, newc->percentage); - changes++; - } - if (oldc->isolation != newc->isolation) { - flexran_set_dl_slice_isolation(mod_id, slice_idx, newc->isolation); - changes++; - } - if (oldc->priority != newc->priority) { - flexran_set_dl_slice_priority(mod_id, slice_idx, newc->priority); - changes++; - } - if (oldc->position_low != newc->position_low) { - flexran_set_dl_slice_position_low(mod_id, slice_idx, newc->position_low); - changes++; - } - if (oldc->position_high != newc->position_high) { - flexran_set_dl_slice_position_high(mod_id, slice_idx, newc->position_high); - changes++; - } - if (oldc->maxmcs != newc->maxmcs) { - flexran_set_dl_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); - changes++; - } - if (check_dl_sorting_update(oldc, newc)) { - flexran_set_dl_slice_sorting(mod_id, slice_idx, newc->sorting, newc->n_sorting); - changes++; - } - if (oldc->accounting != newc->accounting) { - flexran_set_dl_slice_accounting_policy(mod_id, slice_idx, newc->accounting); - changes++; - } - if (!oldc->scheduler_name - || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - int ret = flexran_set_dl_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); - AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", - newc->id, slice_idx); - changes++; - } - return changes; -} - -int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc) -{ - /* not setting the old configuration is intentional, as it will be picked up - * later when reading the configuration. There is thus a direct feedback - * whether it has been set. */ - int changes = 0; - int slice_idx = flexran_find_ul_slice(mod_id, newc->id); - if (slice_idx < 0) { - LOG_W(FLEXRAN_AGENT, "[%d] cannot find index for slice ID %d\n", mod_id, newc->id); - return 0; - } - if (oldc->percentage != newc->percentage) { - flexran_set_ul_slice_percentage(mod_id, slice_idx, newc->percentage); - changes++; - } - if (oldc->isolation != newc->isolation) { - /*flexran_set_ul_slice_isolation(mod_id, slice_idx, newc->isolation); - *changes++;*/ - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting isolation is not supported\n", - mod_id, newc->id); - } - if (oldc->priority != newc->priority) { - /*flexran_set_ul_slice_priority(mod_id, slice_idx, newc->priority); - *changes++;*/ - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the priority is not supported\n", - mod_id, newc->id); - } - if (oldc->first_rb != newc->first_rb) { - flexran_set_ul_slice_first_rb(mod_id, slice_idx, newc->first_rb); - changes++; - } - /*if (oldc->length_rb != newc->length_rb) { - flexran_set_ul_slice_length_rb(mod_id, slice_idx, newc->length_rb); - changes++; - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting length_rb is not supported\n", - mod_id, newc->id); - }*/ - if (oldc->maxmcs != newc->maxmcs) { - flexran_set_ul_slice_maxmcs(mod_id, slice_idx, newc->maxmcs); - changes++; - } - /*if (check_ul_sorting_update(oldc, newc)) { - flexran_set_ul_slice_sorting(mod_id, slice_idx, newc->sorting, n); - changes++; - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the sorting is not supported\n", - mod_id, newc->id); - }*/ - if (oldc->accounting != newc->accounting) { - /*flexran_set_ul_slice_accounting_policy(mod_id, slice_idx, newc->accounting); - *changes++;*/ - LOG_W(FLEXRAN_AGENT, "[%d][UL slice %d] setting the accounting is not supported\n", - mod_id, newc->id); - } - if (!oldc->scheduler_name - || strcmp(oldc->scheduler_name, newc->scheduler_name) != 0) { - int ret = flexran_set_ul_slice_scheduler(mod_id, slice_idx, newc->scheduler_name); - AssertFatal(ret, "could not set DL slice scheduler for slice %d idx %d\n", - newc->id, slice_idx); - changes++; - } - return changes; -} void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) { @@ -1723,24 +1075,8 @@ int apply_ue_slice_assoc_update(mid_t mod_id) continue; } if (ue_slice_assoc_update[i]->has_dl_slice_id) { - int slice_idx = flexran_find_dl_slice(mod_id, ue_slice_assoc_update[i]->dl_slice_id); - if (flexran_dl_slice_exists(mod_id, slice_idx)) { - flexran_set_ue_dl_slice_idx(mod_id, ue_id, slice_idx); - changes++; - } else { - LOG_W(FLEXRAN_AGENT, "[%d] DL slice %d does not exist, refusing change\n", - mod_id, ue_slice_assoc_update[i]->dl_slice_id); - } } if (ue_slice_assoc_update[i]->has_ul_slice_id) { - int slice_idx = flexran_find_ul_slice(mod_id, ue_slice_assoc_update[i]->ul_slice_id); - if (flexran_ul_slice_exists(mod_id, slice_idx)) { - flexran_set_ue_ul_slice_idx(mod_id, ue_id, slice_idx); - changes++; - } else { - LOG_W(FLEXRAN_AGENT, "[%d] UL slice %d does not exist, refusing change\n", - mod_id, ue_slice_assoc_update[i]->ul_slice_id); - } } } n_ue_slice_assoc_updates = 0; diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index 957fe6065e..ef2a7e40a9 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -111,30 +111,10 @@ Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) * Protocol__FlexSliceConfig struct */ void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s); -/* read the DL slice config via the RAN into a given Protocol__FlexDlSlice - * struct */ -void flexran_agent_read_slice_dl_config(mid_t mod_id, int slice_idx, Protocol__FlexDlSlice *dl_slice); - -/* read the UL slice config via the RAN into a given Protocol__FlexUlSlice - * struct */ -void flexran_agent_read_slice_ul_config(mid_t mod_id, int slice_idx, Protocol__FlexUlSlice *ul_slice); - /* reads content of slice over the sc_update structure, so that it can be * applied later by performing a diff between slice_config and sc_update */ void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice); -/* apply generic slice parameters (e.g. intra-/interslice sharing activated or - * not) if there are changes. Returns the number of changed parameters. */ -int apply_new_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *olds, Protocol__FlexSliceConfig *news); - -/* apply new configuration of slice in DL if there are changes between the - * parameters. Returns the number of changed parameters. */ -int apply_new_slice_dl_config(mid_t mod_id, Protocol__FlexDlSlice *oldc, Protocol__FlexDlSlice *newc); - -/* apply new configuration of slice in UL if there are changes between the - * parameters. Returns the number of changed parameters. */ -int apply_new_slice_ul_config(mid_t mod_id, Protocol__FlexUlSlice *oldc, Protocol__FlexUlSlice *newc); - /* inserts a new ue_config into the structure keeping ue to slice association * updates and marks so it can be applied */ void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c index f7f60541f5..6e54e155c2 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.c @@ -28,346 +28,3 @@ #include "flexran_agent_mac_slice_verification.h" - -/* overlap check for UL slices, helper type */ -struct sregion_s { - int start; - int length; -}; - -/* forward declaration of locally-used verification functions */ -int flexran_dl_slice_verify_pct(int pct); -int flexran_dl_slice_verify_priority(int prio); -int flexran_dl_slice_verify_position(int pos_low, int pos_high); -int flexran_dl_slice_verify_maxmcs(int maxmcs); -int flexran_ul_slice_verify_pct(int pct); -int flexran_ul_slice_verify_priority(int prio); -int flexran_ul_slice_verify_first_rb(int first_rb); -int flexran_ul_slice_verify_maxmcs(int maxmcs); -int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n); - -int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls) -{ - /* check mandatory parameters */ - if (!dls->has_id) { - LOG_E(FLEXRAN_AGENT, "[%d] Incoming DL slice configuration has no ID\n", mod_id); - return 0; - } - - /* verify parameters individualy */ - /* label is enum */ - if (!flexran_dl_slice_verify_pct(dls->percentage)) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice percentage (%d)\n", - mod_id, dls->id, dls->percentage); - return 0; - } - /* isolation is a protobuf bool */ - if (!flexran_dl_slice_verify_priority(dls->priority)) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice priority (%d)\n", - mod_id, dls->id, dls->priority); - return 0; - } - if (!flexran_dl_slice_verify_position(dls->position_low, dls->position_high)) { - LOG_E(FLEXRAN_AGENT, - "[%d][DL slice %d] illegal DL slice position low (%d) and/or high (%d)\n", - mod_id, dls->id, dls->position_low, dls->position_high); - return 0; - } - if (!flexran_dl_slice_verify_maxmcs(dls->maxmcs)) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] illegal DL slice max mcs %d\n", - mod_id, dls->id, dls->maxmcs); - return 0; - } - if (dls->n_sorting == 0) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting in DL slice\n", - mod_id, dls->id); - return 0; - } - if (!dls->sorting) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no sorting found in DL slice\n", - mod_id, dls->id); - return 0; - } - /* sorting is an enum */ - /* accounting is an enum */ - if (!dls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] no scheduler name found\n", - mod_id, dls->id); - return 0; - } - if (strcmp(dls->scheduler_name, "schedule_ue_spec") != 0) { - LOG_E(FLEXRAN_AGENT, "[%d][DL slice %d] setting the scheduler to something " - "different than schedule_ue_spec is currently not allowed\n", - mod_id, dls->id); - return 0; - } - - return 1; -} - -int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, - int n_ex, Protocol__FlexDlSlice **update, int n_up) -{ - int i, j, n; - int pct, pct_orig; - /* for every update, array points to existing slice, or NULL if update - * creates new slice */ - Protocol__FlexDlSlice *s[n_up]; - for (i = 0; i < n_up; i++) { - s[i] = NULL; - for (j = 0; j < n_ex; j++) { - if (existing[j]->id == update[i]->id) - s[i] = existing[j]; - } - } - - /* check that number of created and number of added slices in total matches - * [1,10] */ - n = n_ex; - for (i = 0; i < n_up; i++) { - /* new slice */ - if (!s[i]) n += 1; - /* slice will be deleted */ - else if (s[i]->percentage == 0) n -= 1; - /* else "only" an update */ - } - - if (n < 1 || n > 10) { - LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting DL slices (%d -> %d)\n", - mod_id, n_ex, n); - return 0; - } - - /* check that the sum of all slices percentages (including removed/added - * slices) matches [1,100] */ - pct = 0; - for (i = 0; i < n_ex; i++) { - pct += existing[i]->percentage; - } - pct_orig = pct; - for (i = 0; i < n_up; i++) { - /* if there is an existing slice, subtract its percentage and add the - * update's percentage */ - if (s[i]) - pct -= s[i]->percentage; - pct += update[i]->percentage; - } - if (pct < 1 || pct > 100) { - LOG_E(FLEXRAN_AGENT, - "[%d] invalid total RB share for DL slices (%d%% -> %d%%)\n", - mod_id, pct_orig, pct); - return 0; - } - - return 1; -} - -int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls) -{ - /* check mandatory parameters */ - if (!uls->has_id) { - LOG_E(FLEXRAN_AGENT, "[%d] Incoming UL slice configuration has no ID\n", mod_id); - return 0; - } - - /* verify parameters individually */ - /* label is enum */ - if (!flexran_ul_slice_verify_pct(uls->percentage)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", - mod_id, uls->id, uls->percentage); - return 0; - } - /* isolation is a protobuf bool */ - if (!flexran_ul_slice_verify_priority(uls->priority)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice percentage (%d)\n", - mod_id, uls->id, uls->priority); - return 0; - } - if (!flexran_ul_slice_verify_first_rb(uls->first_rb)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice first RB (%d)\n", - mod_id, uls->id, uls->first_rb); - return 0; - } - if (!flexran_ul_slice_verify_maxmcs(uls->maxmcs)) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] illegal UL slice max mcs (%d)\n", - mod_id, uls->id, uls->maxmcs); - return 0; - } - /* TODO - if (uls->n_sorting == 0) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting in UL slice\n", - mod_id, uls->id); - return 0; - } - if (!uls->sorting) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no sorting found in UL slice\n", - mod_id, uls->id); - return 0; - } - */ - /* sorting is an enum */ - /* accounting is an enum */ - if (!uls->scheduler_name) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] no scheduler name found\n", - mod_id, uls->id); - return 0; - } - if (strcmp(uls->scheduler_name, "schedule_ulsch_rnti") != 0) { - LOG_E(FLEXRAN_AGENT, "[%d][UL slice %d] setting the scheduler to something " - "different than schedule_ulsch_rnti is currently not allowed\n", - mod_id, uls->id); - return 0; - } - - return 1; -} - -int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, - int n_ex, Protocol__FlexUlSlice **update, int n_up) -{ - int i, j, n; - int pct, pct_orig; - /* for every update, array "s" points to existing slice, or NULL if update - * creates new slice; array "offs" gives the offset of this slice */ - Protocol__FlexUlSlice *s[n_up]; - int offs[n_up]; - for (i = 0; i < n_up; i++) { - s[i] = NULL; - offs[i] = 0; - for (j = 0; j < n_ex; j++) { - if (existing[j]->id == update[i]->id) { - s[i] = existing[j]; - offs[i] = j; - } - } - } - - /* check that number of created and number of added slices in total matches - * [1,10] */ - n = n_ex; - for (i = 0; i < n_up; i++) { - /* new slice */ - if (!s[i]) n += 1; - /* slice will be deleted */ - else if (s[i]->percentage == 0) n -= 1; - /* else "only" an update */ - } - - if (n < 1 || n > 10) { - LOG_E(FLEXRAN_AGENT, "[%d] Illegal number of resulting UL slices (%d -> %d)\n", - mod_id, n_ex, n); - return 0; - } - - /* check that the sum of all slices percentages (including removed/added - * slices) matches [1,100] */ - pct = 0; - for (i = 0; i < n_ex; i++) { - pct += existing[i]->percentage; - } - pct_orig = pct; - for (i = 0; i < n_up; i++) { - /* if there is an existing slice, subtract its percentage and add the - * update's percentage */ - if (s[i]) - pct -= s[i]->percentage; - pct += update[i]->percentage; - } - if (pct < 1 || pct > 100) { - LOG_E(FLEXRAN_AGENT, "[%d] invalid total RB share (%d%% -> %d%%)\n", - mod_id, pct_orig, pct); - return 0; - } - - /* check that there is no overlap in slices resulting as the combination of - * first_rb and percentage */ - struct sregion_s sregion[n]; - const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ - int k = n_ex; - for (i = 0; i < n_ex; i++) { - sregion[i].start = existing[i]->first_rb; - sregion[i].length = existing[i]->percentage * N_RB / 100; - } - for (i = 0; i < n_up; i++) { - ptrdiff_t d = s[i] ? offs[i] : k++; - AssertFatal(d >= 0 && d < k, "illegal pointer offset (%ld, k=%d)\n", d, k); - sregion[d].start = update[i]->first_rb; - sregion[d].length = update[i]->percentage * N_RB / 100; - } - AssertFatal(k == n, "illegal number of slices while calculating overlap\n"); - if (!check_ul_slice_overlap(mod_id, sregion, k)) { - LOG_E(FLEXRAN_AGENT, "[%d] UL slices are overlapping\n", mod_id); - return 0; - } - - return 1; -} - -int flexran_dl_slice_verify_pct(int pct) -{ - return pct >= 0 && pct <= 100; -} - -int flexran_dl_slice_verify_priority(int prio) -{ - return prio >= 0; -} - -int flexran_dl_slice_verify_position(int pos_low, int pos_high) -{ - return pos_low < pos_high && pos_low >= 0 && pos_high <= N_RBG_MAX; -} - -int flexran_dl_slice_verify_maxmcs(int maxmcs) -{ - return maxmcs >= 0 && maxmcs <= 28; -} - -int flexran_ul_slice_verify_pct(int pct) -{ - return pct >= 0 && pct <= 100; -} - -int flexran_ul_slice_verify_priority(int prio) -{ - return prio >= 0; -} - -int flexran_ul_slice_verify_first_rb(int first_rb) -{ - return first_rb >= 0 && first_rb < 100; -} - -int flexran_ul_slice_verify_maxmcs(int maxmcs) -{ - return maxmcs >= 0 && maxmcs <= 20; -} - -int sregion_compare(const void *_a, const void *_b) -{ - const struct sregion_s *a = (const struct sregion_s *)_a; - const struct sregion_s *b = (const struct sregion_s *)_b; - const int res = a->start - b->start; - if (res < 0) return -1; - else if (res == 0) return 0; - else return 1; -} - -int check_ul_slice_overlap(mid_t mod_id, struct sregion_s *sr, int n) -{ - int i; - int overlap, op, u; - const int N_RB = flexran_get_N_RB_UL(mod_id, 0); /* assume PCC */ - qsort(sr, n, sizeof(sr[0]), sregion_compare); - for (i = 0; i < n; i++) { - u = i == n-1 ? N_RB : sr[i+1].start; - AssertFatal(sr[i].start <= u, "unsorted slice list\n"); - overlap = sr[i].start + sr[i].length - u; - if (overlap <= 0) continue; - op = overlap * 100 / sr[i].length; - LOG_W(FLEXRAN_AGENT, "[%d] slice overlap of %d%% detected\n", mod_id, op); - if (op >= 10) /* more than 10% overlap -> refuse */ - return 0; - } - return 1; -} diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h index a8f4030d36..c9e66b6f88 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_slice_verification.h @@ -29,9 +29,3 @@ #include "flexran_agent_common_internal.h" #include "flexran_agent_mac_internal.h" -int flexran_verify_dl_slice(mid_t mod_id, Protocol__FlexDlSlice *dls); -int flexran_verify_group_dl_slices(mid_t mod_id, Protocol__FlexDlSlice **existing, - int n_ex, Protocol__FlexDlSlice **update, int n_up); -int flexran_verify_ul_slice(mid_t mod_id, Protocol__FlexUlSlice *uls); -int flexran_verify_group_ul_slices(mid_t mod_id, Protocol__FlexUlSlice **existing, - int n_ex, Protocol__FlexUlSlice **update, int n_up); diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index 733d883c92..e5d01ebdc0 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -61,83 +61,6 @@ enum flex_qam { // // Slice config related structures and enums // -enum flex_dl_sorting { - - CR_ROUND = 0; // Highest HARQ first - CR_SRB12 = 1; // Highest SRB1+2 first - CR_HOL = 2; // Highest HOL first - CR_LC = 3; // Greatest RLC buffer first - CR_CQI = 4; // Highest CQI first - CR_LCP = 5; // Highest LC priority first -} - -enum flex_ul_sorting { - CRU_ROUND = 0; // Highest HARQ first - CRU_BUF = 1; // Highest BSR first - CRU_BTS = 2; // More bytes to schedule first - CRU_MCS = 3; // Highest MCS first - CRU_LCP = 4; // Highest LC priority first - CRU_HOL = 5; // Highest HOL first -} - -enum flex_dl_accounting_policy { - POL_FAIR = 0; - POL_GREEDY = 1; - POL_NUM = 2; -} - -enum flex_ul_accounting_policy { - POLU_FAIR = 0; - POLU_GREEDY = 1; - POLU_NUM = 2; -} - -enum flex_slice_label { - xMBB = 0; - URLLC = 1; - mMTC = 2; - xMTC = 3; - Other = 4; -} - -message flex_dl_slice { - optional uint32 id = 1; - optional flex_slice_label label = 2; - // should be between 0 and 100 - optional uint32 percentage = 3; - // whether this slice should be exempted form interslice sharing - optional bool isolation = 4; - // increasing value means increasing prio - optional uint32 priority = 5; - // min and max RB to use (in frequency) in the range [0, N_RBG_MAX] - optional uint32 position_low = 6; - optional uint32 position_high = 7; - // maximum MCS to be allowed in this slice - optional uint32 maxmcs = 8; - repeated flex_dl_sorting sorting = 9; - optional flex_dl_accounting_policy accounting = 10; - optional string scheduler_name = 11; -} - -message flex_ul_slice { - optional uint32 id = 1; - optional flex_slice_label label = 2; - // should be between 0 and 100 - optional uint32 percentage = 3; - // whether this slice should be exempted form interslice sharing - optional bool isolation = 4; - // increasing value means increasing prio - optional uint32 priority = 5; - // RB start to use (in frequency) in the range [0, N_RB_MAX] - optional uint32 first_rb = 6; - // TODO RB number - //optional uint32 length_rb = 7; - // maximum MCS to be allowed in this slice - optional uint32 maxmcs = 8; - repeated flex_ul_sorting sorting = 9; - optional flex_ul_accounting_policy accounting = 10; - optional string scheduler_name = 11; -} // // UE config related structures and enums diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 324153613d..1a66a4f20f 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -49,14 +49,6 @@ message flex_cell_config { } message flex_slice_config { - // whether remaining RBs after first intra-slice allocation will - // be allocated to UEs of the same slice - optional bool intraslice_share_active = 3; - // whether remaining RBs after slice allocation will be allocated - // to UEs of another slice. Isolated slices will be ignored. - optional bool interslice_share_active = 4; - repeated flex_dl_slice dl = 1; - repeated flex_ul_slice ul = 2; } message flex_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index e77b2fb386..3dd9f5b957 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -316,25 +316,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { } if (reply->cell_config[i]->slice_config) { - for (int j = 0; j < reply->cell_config[i]->slice_config->n_dl; ++j) { - if (reply->cell_config[i]->slice_config->dl[j]->n_sorting > 0) - free(reply->cell_config[i]->slice_config->dl[j]->sorting); - - free(reply->cell_config[i]->slice_config->dl[j]->scheduler_name); - free(reply->cell_config[i]->slice_config->dl[j]); - } - - free(reply->cell_config[i]->slice_config->dl); - - for (int j = 0; j < reply->cell_config[i]->slice_config->n_ul; ++j) { - if (reply->cell_config[i]->slice_config->ul[j]->n_sorting > 0) - free(reply->cell_config[i]->slice_config->ul[j]->sorting); - - free(reply->cell_config[i]->slice_config->ul[j]->scheduler_name); - free(reply->cell_config[i]->slice_config->ul[j]); - } - - free(reply->cell_config[i]->slice_config->ul); + /* TODO */ free(reply->cell_config[i]->slice_config); } diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index 291c4dc7d8..cd8b0b8f67 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -3018,142 +3018,44 @@ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { return 0; } -void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { - if (!mac_is_present(mod_id)) return; -} - int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; return 0; } -void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_dl_slice_exists(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return 0; -} - +/* TODO */ int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; return -1; } +/* TODO */ +int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { + if (!mac_is_present(mod_id)) return -1; + return -1; +} + int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; return -1; } -int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} +//int flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { +//} int flexran_get_num_dl_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; return 0; } -int flexran_get_intraslice_sharing_active(mid_t mod_id) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active) { +/* TODO */ +void flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return; + return; } -int flexran_get_interslice_sharing_active(mid_t mod_id) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active) { - if (!mac_is_present(mod_id)) return; -} - -slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n) { - if (!mac_is_present(mod_id)) return; -} - -Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; - return PROTOCOL__FLEX_DL_ACCOUNTING_POLICY__POL_FAIR; -} -void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting) { - if (!mac_is_present(mod_id)) return; -} - -char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return NULL; - return NULL; -} -int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { - if (!mac_is_present(mod_id)) return 0; - return 0; -} - -int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { +/* TODO */ +int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { if (!mac_is_present(mod_id)) return -1; return -1; } @@ -3163,62 +3065,14 @@ int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) { return -1; } -int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} +//int flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { +//} int flexran_get_num_ul_slices(mid_t mod_id) { if (!mac_is_present(mod_id)) return -1; return 0; } -int flexran_ul_slice_exists(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return 0; -} - -slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} - -void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb) { - if (!mac_is_present(mod_id)) return; -} - -int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; -} -void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs) { - if (!mac_is_present(mod_id)) return; -} - -char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return NULL; - return ""; -} -int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name) { - if (!mac_is_present(mod_id)) return 0; - return 0; -} /************************** S1AP **************************/ int flexran_get_s1ap_mme_pending(mid_t mod_id){ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index 9d1bfb9d3e..c29ba53c11 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -659,153 +659,38 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti); /* Get the DL slice ID for a UE */ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id); - /* Set the DL slice index(!) for a UE */ -void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +//void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); /* Get the UL slice ID for a UE */ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id); - /* Set the UL slice index(!) for a UE */ -void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +//void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); -/* Whether intraslice sharing is active, return boolean */ -int flexran_get_intraslice_sharing_active(mid_t mod_id); -/* Set whether intraslice sharing is active */ -void flexran_set_intraslice_sharing_active(mid_t mod_id, int intraslice_active); - -/* Whether intraslice sharing is active, return boolean */ -int flexran_get_interslice_sharing_active(mid_t mod_id); -/* Set whether intraslice sharing is active */ -void flexran_set_interslice_sharing_active(mid_t mod_id, int interslice_active); +/* Create slice in DL, returns the new slice index */ +//int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in DL, returns new number of slices or -1 on error */ +//int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); +/* Finds slice in DL with given slice_id and returns slice index */ +int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); +/* Return the parameters of slice at index slice_idx */ +//void flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); /* Get the number of slices in DL */ int flexran_get_num_dl_slices(mid_t mod_id); -/* Query slice existence in DL. Return is boolean value */ -int flexran_dl_slice_exists(mid_t mod_id, int slice_idx); +/* Create slice in UL, returns the new slice index */ +//int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); +/* Remove slice in UL */ +//int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); -/* Create slice in DL, returns the new slice index */ -int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); /* Finds slice in DL with given slice_id and returns slice index */ -int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); -/* Remove slice in DL, returns new number of slices or -1 on error */ -int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); - -/* Get the ID of a slice in DL */ -slice_id_t flexran_get_dl_slice_id(mid_t mod_id, int slice_idx); -/* Set the ID of a slice in DL */ -void flexran_set_dl_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); - -/* Get the RB share a slice in DL, value 0-100 */ -int flexran_get_dl_slice_percentage(mid_t mod_id, int slice_idx); -/* Set the RB share a slice in DL, value 0-100 */ -void flexran_set_dl_slice_percentage(mid_t mod_id, int slice_idx, int percentage); - -/* Whether a slice in DL is isolated */ -int flexran_get_dl_slice_isolation(mid_t mod_id, int slice_idx); -/* Set whether a slice in DL is isolated */ -void flexran_set_dl_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated); - -/* Get the priority of a slice in DL */ -int flexran_get_dl_slice_priority(mid_t mod_id, int slice_idx); -/* Get the priority of a slice in DL */ -void flexran_set_dl_slice_priority(mid_t mod_id, int slice_idx, int priority); - -/* Get the lower end of the frequency range for the slice positioning in DL */ -int flexran_get_dl_slice_position_low(mid_t mod_id, int slice_idx); -/* Set the lower end of the frequency range for the slice positioning in DL */ -void flexran_set_dl_slice_position_low(mid_t mod_id, int slice_idx, int poslow); - -/* Get the higher end of the frequency range for the slice positioning in DL */ -int flexran_get_dl_slice_position_high(mid_t mod_id, int slice_idx); -/* Set the higher end of the frequency range for the slice positioning in DL */ -void flexran_set_dl_slice_position_high(mid_t mod_id, int slice_idx, int poshigh); - -/* Get the maximum MCS for slice in DL */ -int flexran_get_dl_slice_maxmcs(mid_t mod_id, int slice_idx); -/* Set the maximum MCS for slice in DL */ -void flexran_set_dl_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); - -/* Get the sorting order of a slice in DL, return value is number of elements - * in sorting_list */ -int flexran_get_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting **sorting_list); -/* Set the sorting order of a slice in DL */ -void flexran_set_dl_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexDlSorting *sorting_list, int n); - -/* Get the accounting policy for a slice in DL */ -Protocol__FlexDlAccountingPolicy flexran_get_dl_slice_accounting_policy(mid_t mod_id, int slice_idx); -/* Set the accounting policy for a slice in DL */ -void flexran_set_dl_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__FlexDlAccountingPolicy accounting); - -/* Get the scheduler name for a slice in DL */ -char *flexran_get_dl_slice_scheduler(mid_t mod_id, int slice_idx); -/* Set the scheduler name for a slice in DL */ -int flexran_set_dl_slice_scheduler(mid_t mod_id, int slice_idx, char *name); - +int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); +/* Return the parameters of slice at index slice_idx */ +//void flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); /* Get the number of slices in UL */ int flexran_get_num_ul_slices(mid_t mod_id); -/* Query slice existence in UL. Return is boolean value */ -int flexran_ul_slice_exists(mid_t mod_id, int slice_idx); - -/* Create slice in UL, returns the new slice index */ -int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); -/* Finds slice in UL with given slice_id and returns slice index */ -int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); -/* Remove slice in UL */ -int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); - -/* Get the ID of a slice in UL */ -slice_id_t flexran_get_ul_slice_id(mid_t mod_id, int slice_idx); -/* Set the ID of a slice in UL */ -void flexran_set_ul_slice_id(mid_t mod_id, int slice_idx, slice_id_t slice_id); - -/* Get the RB share a slice in UL, value 0-100 */ -int flexran_get_ul_slice_percentage(mid_t mod_id, int slice_idx); -/* Set the RB share a slice in UL, value 0-100 */ -void flexran_set_ul_slice_percentage(mid_t mod_id, int slice_idx, int percentage); - -/* TODO Whether a slice in UL is isolated */ -/*int flexran_get_ul_slice_isolation(mid_t mod_id, int slice_idx);*/ -/* TODO Set whether a slice in UL is isolated */ -/*void flexran_set_ul_slice_isolation(mid_t mod_id, int slice_idx, int is_isolated);*/ - -/* TODO Get the priority of a slice in UL */ -/*int flexran_get_ul_slice_priority(mid_t mod_id, int slice_idx);*/ -/* TODO Set the priority of a slice in UL */ -/*void flexran_set_ul_slice_priority(mid_t mod_id, int slice_idx, int priority);*/ - -/* Get the first RB for allocation in a slice in UL */ -int flexran_get_ul_slice_first_rb(mid_t mod_id, int slice_idx); -/* Set the first RB for allocation in a slice in UL */ -void flexran_set_ul_slice_first_rb(mid_t mod_id, int slice_idx, int first_rb); - -/* TODO Get the number of RB for the allocation in a slice in UL */ -/*int flexran_get_ul_slice_length_rb(mid_t mod_id, int slice_idx);*/ -/* TODO Set the of number of RB for the allocation in a slice in UL */ -/*void flexran_set_ul_slice_length_rb(mid_t mod_id, int slice_idx, int poshigh);*/ - -/* Get the maximum MCS for slice in UL */ -int flexran_get_ul_slice_maxmcs(mid_t mod_id, int slice_idx); -/* Set the maximum MCS for slice in UL */ -void flexran_set_ul_slice_maxmcs(mid_t mod_id, int slice_idx, int maxmcs); - -/* TODO Get the sorting order of a slice in UL, return value is number of elements - * in sorting_list */ -/*int flexran_get_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting **sorting_list);*/ -/* TODO Set the sorting order of a slice in UL */ -/*void flexran_set_ul_slice_sorting(mid_t mod_id, int slice_idx, Protocol__FlexUlSorting *sorting_list, int n);*/ - -/* TODO Get the accounting policy for a slice in UL */ -/*Protocol__UlAccountingPolicy flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx);*/ -/* TODO Set the accounting policy for a slice in UL */ -/*void flexran_get_ul_slice_accounting_policy(mid_t mod_id, int slice_idx, Protocol__UlAccountingPolicy accountin);*/ - -/* Get the scheduler name for a slice in UL */ -char *flexran_get_ul_slice_scheduler(mid_t mod_id, int slice_idx); -/* Set the scheduler name for a slice in UL */ -int flexran_set_ul_slice_scheduler(mid_t mod_id, int slice_idx, char *name); /************************** S1AP **************************/ /* Get the number of MMEs to be connected */ From 2b4e52906879d1001380679aac92306121946793 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 15:16:21 +0200 Subject: [PATCH 086/171] Simplify add_ue_list(), remove_ue_list(); add init_ue_list() --- .../LAYER2/MAC/eNB_scheduler_primitives.c | 43 ++++++++++--------- openair2/LAYER2/MAC/mac_proto.h | 1 + openair2/LAYER2/MAC/main.c | 5 +-- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index 78d6f6a3d7..b75ab774c6 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2131,33 +2131,36 @@ dump_ue_list(UE_list_t *listP) { * Add a UE to UE_list listP */ inline void add_ue_list(UE_list_t *listP, int UE_id) { - if (listP->head == -1) { - listP->head = UE_id; - listP->next[UE_id] = -1; - } else { - int i = listP->head; - while (listP->next[i] >= 0) - i = listP->next[i]; - listP->next[i] = UE_id; - listP->next[UE_id] = -1; - } + int *cur = &listP->head; + while (*cur >= 0) + cur = &listP->next[*cur]; + *cur = UE_id; } //------------------------------------------------------------------------------ /* - * Remove a UE from the UE_list listP, return the previous element + * Remove a UE from the UE_list listP */ inline int remove_ue_list(UE_list_t *listP, int UE_id) { - listP->next[UE_id] = -1; - if (listP->head == UE_id) { - listP->head = listP->next[UE_id]; - return -1; - } + int *cur = &listP->head; + while (*cur != -1 && *cur != UE_id) + cur = &listP->next[*cur]; + if (*cur == -1) + return 0; + int *next = &listP->next[*cur]; + *cur = listP->next[*cur]; + *next = -1; + return 1; +} - int previous = prev(listP, UE_id); - if (previous != -1) - listP->next[previous] = listP->next[UE_id]; - return previous; +//------------------------------------------------------------------------------ +/* + * Initialize the UE_list listP + */ +inline void init_ue_list(UE_list_t *listP) { + listP->head = -1; + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + listP->next[i] = -1; } //------------------------------------------------------------------------------ diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 61251ef088..818eb834fb 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -659,6 +659,7 @@ int prev(UE_list_t *listP, int nodeP); void add_ue_list(UE_list_t *listP, int UE_id); int remove_ue_list(UE_list_t *listP, int UE_id); void dump_ue_list(UE_list_t *listP); +void init_ue_list(UE_list_t *listP); int UE_num_active_CC(UE_info_t *listP, int ue_idP); int UE_PCCID(module_id_t mod_idP, int ue_idP); rnti_t UE_RNTI(module_id_t mod_idP, int ue_idP); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 35b5136889..659c7250e8 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -45,11 +45,8 @@ extern RAN_CONTEXT_t RC; void init_UE_info(UE_info_t *UE_info) { - int list_el; UE_info->num_UEs = 0; - UE_info->list.head = -1; - for (list_el = 0; list_el < MAX_MOBILES_PER_ENB; list_el++) - UE_info->list.next[list_el] = -1; + init_ue_list(&UE_info->list); memset(UE_info->DLSCH_pdu, 0, sizeof(UE_info->DLSCH_pdu)); memset(UE_info->UE_template, 0, sizeof(UE_info->UE_template)); memset(UE_info->eNB_UE_stats, 0, sizeof(UE_info->eNB_UE_stats)); From 9956b96049a32ec9ccb3aa9e78ff6aa0008044f8 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 14:38:05 +0200 Subject: [PATCH 087/171] Use fptr for preproc and align UL PP definition --- openair2/ENB_APP/enb_config.c | 9 +-- openair2/LAYER2/MAC/eNB_scheduler_dlsch.c | 5 +- .../LAYER2/MAC/eNB_scheduler_primitives.c | 12 ++++ openair2/LAYER2/MAC/eNB_scheduler_ulsch.c | 4 +- openair2/LAYER2/MAC/mac.h | 59 +++++++++++++++++-- openair2/LAYER2/MAC/mac_proto.h | 6 +- openair2/LAYER2/MAC/main.c | 13 ++-- openair2/LAYER2/MAC/pre_processor.c | 46 +++++++-------- 8 files changed, 110 insertions(+), 44 deletions(-) diff --git a/openair2/ENB_APP/enb_config.c b/openair2/ENB_APP/enb_config.c index 0308c2fd79..1d189832b4 100644 --- a/openair2/ENB_APP/enb_config.c +++ b/openair2/ENB_APP/enb_config.c @@ -266,10 +266,11 @@ void RCconfig_macrlc(int macrlc_has_f1[MAX_MAC_INST]) { void *d = dlsym(NULL, s); AssertFatal(d, "%s(): no default scheduler DL algo '%s' found\n", __func__, s); // release default, add new - RC.mac[j]->dl_algo.unset(&RC.mac[j]->dl_algo.data); - RC.mac[j]->dl_algo = *(default_sched_dl_algo_t *) d; - RC.mac[j]->dl_algo.data = RC.mac[j]->dl_algo.setup(); - LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", RC.mac[j]->dl_algo.name); + pp_impl_param_t *dl_pp = &RC.mac[j]->pre_processor_dl; + dl_pp->dl_algo.unset(&dl_pp->dl_algo.data); + dl_pp->dl_algo = *(default_sched_dl_algo_t *) d; + dl_pp->dl_algo.data = dl_pp->dl_algo.setup(); + LOG_I(ENB_APP, "using default scheduler DL algo '%s'\n", dl_pp->dl_algo.name); }// j=0..num_inst } /*else {// MacRLC_ParamList.numelt > 0 // ignore it diff --git a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c index 783d4e8b1a..1f99f50ece 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_dlsch.c @@ -573,10 +573,7 @@ schedule_ue_spec(module_id_t module_idP, VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN); start_meas(&eNB->schedule_dlsch_preprocessor); - dlsch_scheduler_pre_processor(module_idP, - CC_id, - frameP, - subframeP); + eNB->pre_processor_dl.dl(module_idP, CC_id, frameP, subframeP); stop_meas(&eNB->schedule_dlsch_preprocessor); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c index b75ab774c6..89c2ecc83d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_primitives.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_primitives.c @@ -2199,6 +2199,12 @@ add_new_ue(module_id_t mod_idP, UE_info->active[UE_id] = TRUE; add_ue_list(&UE_info->list, UE_id); dump_ue_list(&UE_info->list); + pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl; + if (dl->slices) // inform slice implementation about new UE + dl->add_UE(dl->slices, UE_id); + pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul; + if (ul->slices) // inform slice implementation about new UE + ul->add_UE(ul->slices, UE_id); if (IS_SOFTMODEM_IQPLAYER)// not specific to record/playback ? UE_info->UE_template[cc_idP][UE_id].pre_assigned_mcs_ul = 0; UE_info->UE_template[cc_idP][UE_id].rach_resource_type = rach_resource_type; @@ -2262,6 +2268,12 @@ rrc_mac_remove_ue(module_id_t mod_idP, UE_info->num_UEs--; remove_ue_list(&UE_info->list, UE_id); + pp_impl_param_t* dl = &RC.mac[mod_idP]->pre_processor_dl; + if (dl->slices) // inform slice implementation about new UE + dl->remove_UE(dl->slices, UE_id); + pp_impl_param_t* ul = &RC.mac[mod_idP]->pre_processor_ul; + if (ul->slices) // inform slice implementation about new UE + ul->remove_UE(ul->slices, UE_id); /* Clear all remaining pending transmissions */ memset(&UE_info->UE_template[pCC_id][UE_id], 0, sizeof(UE_TEMPLATE)); diff --git a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c index 3062e5c964..2de45db856 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_ulsch.c @@ -1301,11 +1301,11 @@ schedule_ulsch_rnti(module_id_t module_idP, /* * ULSCH preprocessor: set UE_template-> - * pre_allocated_nb_rb_ul[slice_idx] + * pre_allocated_nb_rb_ul * pre_assigned_mcs_ul * pre_allocated_rb_table_index_ul */ - ulsch_scheduler_pre_processor(module_idP, CC_id, frameP, subframeP, sched_frame, sched_subframeP); + mac->pre_processor_ul.ul(module_idP, CC_id, frameP, subframeP, sched_frame, sched_subframeP); for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { if (UE_info->UE_template[CC_id][UE_id].rach_resource_type > 0) diff --git a/openair2/LAYER2/MAC/mac.h b/openair2/LAYER2/MAC/mac.h index 8349d84d48..faefc481f6 100644 --- a/openair2/LAYER2/MAC/mac.h +++ b/openair2/LAYER2/MAC/mac.h @@ -540,7 +540,6 @@ typedef enum { SCHED_MODE_FAIR_RR /// fair raund robin } SCHEDULER_MODES; - /*! \brief temporary struct for ULSCH sched */ typedef struct { rnti_t rnti; @@ -1199,6 +1198,56 @@ typedef struct { void *data; } default_sched_ul_algo_t; +typedef void (*pp_impl_dl)(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe); +typedef void (*pp_impl_ul)(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe, + frame_t sched_frame, + sub_frame_t sched_subframe); + +struct slice_info_s; +typedef struct { + int algorithm; + + /// inform the slice algorithm about a new UE + void (*add_UE)(struct slice_info_s *s, int UE_id); + /// inform the slice algorithm about a UE that disconnected + void (*remove_UE)(struct slice_info_s *s, int UE_id); + /// move a UE to a slice in DL/UL, -1 means don't move (no-op). + void (*move_UE)(struct slice_info_s *s, int UE_id, int idx); + + /// Adds a new slice through admission control. slice_params are + /// algorithm-specific parameters. sched is either a default_sched_ul_algo_t + /// or default_sched_dl_algo_t, depending on whether this implementation + /// handles UL/DL. If slice at index exists, updates existing + /// slice. Returns index of new slice or -1 on failure. + int (*addmod_slice)(struct slice_info_s *s, + int id, + char *label, + void *sched, + void *slice_params); + /// Returns slice through slice_idx. 1 if successful, 0 if not. + int (*remove_slice)(struct slice_info_s *s, uint8_t slice_idx); + + union { + pp_impl_dl dl; + pp_impl_ul ul; + }; + + union { + default_sched_ul_algo_t ul_algo; + default_sched_dl_algo_t dl_algo; + }; + + void (*destroy)(struct slice_info_s **s); + + struct slice_info_s *slices; +} pp_impl_param_t; + /*! \brief eNB common channels */ typedef struct { int physCellId; @@ -1354,9 +1403,11 @@ typedef struct eNB_MAC_INST_s { UE_free_list_t UE_free_list; /// for scheduling selection SCHEDULER_MODES scheduler_mode; - /// scheduling algorithm used in default scheduler - default_sched_dl_algo_t dl_algo; - default_sched_ul_algo_t ul_algo; + /// Default scheduler: Pre-processor implementation. Algorithms for UL/DL + /// are called by ULSCH/DLSCH, respectively. Pro-processor implementation can + /// encapsulate slicing. + pp_impl_param_t pre_processor_dl; + pp_impl_param_t pre_processor_ul; int32_t puSch10xSnr; int32_t puCch10xSnr; diff --git a/openair2/LAYER2/MAC/mac_proto.h b/openair2/LAYER2/MAC/mac_proto.h index 818eb834fb..9d49fdffd5 100644 --- a/openair2/LAYER2/MAC/mac_proto.h +++ b/openair2/LAYER2/MAC/mac_proto.h @@ -674,10 +674,10 @@ void set_ul_DAI(int module_idP, void ulsch_scheduler_pre_processor(module_id_t module_idP, int CC_id, - int frameP, + frame_t frameP, sub_frame_t subframeP, - int sched_frameP, - unsigned char sched_subframeP); + frame_t sched_frameP, + sub_frame_t sched_subframeP); int phy_stats_exist(module_id_t Mod_id, int rnti); diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 659c7250e8..24038e60d5 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -99,16 +99,21 @@ void mac_top_init_eNB(void) } mac[i]->if_inst = IF_Module_init(i); + + mac[i]->pre_processor_dl.dl = dlsch_scheduler_pre_processor; char *s = "round_robin_dl"; void *d = dlsym(NULL, s); AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); - mac[i]->dl_algo = *(default_sched_dl_algo_t *) d; - mac[i]->dl_algo.data = mac[i]->dl_algo.setup(); + mac[i]->pre_processor_dl.dl_algo = *(default_sched_dl_algo_t *) d; + mac[i]->pre_processor_dl.dl_algo.data = mac[i]->pre_processor_dl.dl_algo.setup(); + + mac[i]->pre_processor_ul.ul = ulsch_scheduler_pre_processor; s = "round_robin_ul"; d = dlsym(NULL, s); AssertFatal(d, "%s(): no scheduler algo '%s' found\n", __func__, s); - mac[i]->ul_algo = *(default_sched_ul_algo_t *) d; - mac[i]->ul_algo.data = mac[i]->ul_algo.setup(); + mac[i]->pre_processor_ul.ul_algo = *(default_sched_ul_algo_t *) d; + mac[i]->pre_processor_ul.ul_algo.data = mac[i]->pre_processor_ul.ul_algo.setup(); + init_UE_info(&mac[i]->UE_info); } diff --git a/openair2/LAYER2/MAC/pre_processor.c b/openair2/LAYER2/MAC/pre_processor.c index d7dfc7816a..6477d60021 100644 --- a/openair2/LAYER2/MAC/pre_processor.c +++ b/openair2/LAYER2/MAC/pre_processor.c @@ -703,15 +703,15 @@ dlsch_scheduler_pre_processor(module_id_t Mod_id, n_rbg_sched += rbgalloc_mask[i]; } - mac->dl_algo.run(Mod_id, - CC_id, - frameP, - subframeP, - &UE_to_sched, - 4, // max_num_ue - n_rbg_sched, - rbgalloc_mask, - mac->dl_algo.data); + mac->pre_processor_dl.dl_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + &UE_to_sched, + 4, // max_num_ue + n_rbg_sched, + rbgalloc_mask, + mac->pre_processor_dl.dl_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for @@ -1080,10 +1080,10 @@ default_sched_ul_algo_t round_robin_ul = { void ulsch_scheduler_pre_processor(module_id_t Mod_id, int CC_id, - int frameP, + frame_t frameP, sub_frame_t subframeP, - int sched_frameP, - unsigned char sched_subframeP) { + frame_t sched_frameP, + sub_frame_t sched_subframeP) { eNB_MAC_INST *mac = RC.mac[Mod_id]; UE_info_t *UE_info = &mac->UE_info; const int N_RB_UL = to_prb(mac->common_channels[CC_id].ul_Bandwidth); @@ -1140,17 +1140,17 @@ void ulsch_scheduler_pre_processor(module_id_t Mod_id, } } - mac->ul_algo.run(Mod_id, - CC_id, - frameP, - subframeP, - sched_frameP, - sched_subframeP, - &UE_to_sched, - 4, // max_num_ue - n_contig, - rbs, - mac->ul_algo.data); + mac->pre_processor_ul.ul_algo.run(Mod_id, + CC_id, + frameP, + subframeP, + sched_frameP, + sched_subframeP, + &UE_to_sched, + 4, // max_num_ue + n_contig, + rbs, + mac->pre_processor_ul.ul_algo.data); // the following block is meant for validation of the pre-processor to check // whether all UE allocations are non-overlapping and is not necessary for From 872cfc03fe2323f708acbc7008f3d4294f3df2de Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Sun, 12 Apr 2020 18:33:55 +0200 Subject: [PATCH 088/171] Implement Static Slicing --- cmake_targets/CMakeLists.txt | 1 + openair2/LAYER2/MAC/slicing/slicing.c | 586 ++++++++++++++++++ openair2/LAYER2/MAC/slicing/slicing.h | 74 +++ .../LAYER2/MAC/slicing/slicing_internal.h | 46 ++ 4 files changed, 707 insertions(+) create mode 100644 openair2/LAYER2/MAC/slicing/slicing.c create mode 100644 openair2/LAYER2/MAC/slicing/slicing.h create mode 100644 openair2/LAYER2/MAC/slicing/slicing_internal.h diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 7e59f38e8d..0b60172747 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -1830,6 +1830,7 @@ set (MAC_SRC ${MAC_DIR}/eNB_scheduler_fairRR.c ${MAC_DIR}/eNB_scheduler_phytest.c ${MAC_DIR}/pre_processor.c + ${MAC_DIR}/slicing/slicing.c ${MAC_DIR}/config.c ${MAC_DIR}/config_ue.c ) diff --git a/openair2/LAYER2/MAC/slicing/slicing.c b/openair2/LAYER2/MAC/slicing/slicing.c new file mode 100644 index 0000000000..a1de326df0 --- /dev/null +++ b/openair2/LAYER2/MAC/slicing/slicing.c @@ -0,0 +1,586 @@ +/* + * 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 slicing.c + * \brief Generic slicing helper functions and Static Slicing Implementation + * \author Robert Schmidt + * \date 2020 + * \email robert.schmidt@eurecom.fr + */ + +#define _GNU_SOURCE +#include +#include + +#include "assertions.h" +#include "common/utils/LOG/log.h" + +#include "slicing.h" +#include "slicing_internal.h" + +#include "common/ran_context.h" +extern RAN_CONTEXT_t RC; + +#define RET_FAIL(ret, x...) do { LOG_E(MAC, x); return ret; } while (0) + +int slicing_get_UE_slice_idx(slice_info_t *si, int UE_id) { + return si->UE_assoc_slice[UE_id]; +} + +void slicing_add_UE(slice_info_t *si, int UE_id) { + add_ue_list(&si->s[0]->UEs, UE_id); + si->UE_assoc_slice[UE_id] = 0; +} + +void _remove_UE(slice_t **s, uint8_t *assoc, int UE_id) { + const uint8_t i = assoc[UE_id]; + DevAssert(remove_ue_list(&s[i]->UEs, UE_id)); + assoc[UE_id] = -1; +} + +void slicing_remove_UE(slice_info_t *si, int UE_id) { + _remove_UE(si->s, si->UE_assoc_slice, UE_id); +} + +void _move_UE(slice_t **s, uint8_t *assoc, int UE_id, int to) { + const uint8_t i = assoc[UE_id]; + const int ri = remove_ue_list(&s[i]->UEs, UE_id); + if (!ri) + LOG_W(MAC, "did not find UE %d in DL slice index %d\n", UE_id, i); + add_ue_list(&s[to]->UEs, UE_id); + assoc[UE_id] = to; +} + +void slicing_move_UE(slice_info_t *si, int UE_id, int idx) { + DevAssert(idx >= -1 && idx < si->num); + if (idx >= 0) + _move_UE(si->s, si->UE_assoc_slice, UE_id, idx); +} + +int _exists_slice(uint8_t n, slice_t **s, int id) { + for (int i = 0; i < n; ++i) + if (s[i]->id == id) + return i; + return -1; +} + +slice_t *_add_slice(uint8_t *n, slice_t **s) { + s[*n] = calloc(1, sizeof(slice_t)); + if (!s[*n]) + return NULL; + init_ue_list(&s[*n]->UEs); + *n += 1; + return s[*n - 1]; +} + +slice_t *_remove_slice(uint8_t *n, slice_t **s, uint8_t *assoc, int idx) { + if (idx >= *n) + return NULL; + + slice_t *sr = s[idx]; + while (sr->UEs.head >= 0) + _move_UE(s, assoc, sr->UEs.head, 0); + + for (int i = idx + 1; i < *n; ++i) + s[i - 1] = s[i]; + *n -= 1; + s[*n] = NULL; + + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + if (assoc[i] > idx) + assoc[i] -= 1; + + if (sr->label) + free(sr->label); + + return sr; +} + +/************************ Static Slicing Implementation ************************/ + +int addmod_static_slice_dl(slice_info_t *si, + int id, + char *label, + void *algo, + void *slice_params_dl) { + static_slice_param_t *dl = slice_params_dl; + if (dl && dl->posLow > dl->posHigh) + RET_FAIL(-1, "%s(): slice id %d posLow > posHigh\n", __func__, id); + + uint8_t rbgMap[25] = { 0 }; + int index = _exists_slice(si->num, si->s, id); + if (index >= 0) { + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *sd = dl && si->s[s]->id == id ? dl : si->s[s]->algo_data; + for (int i = sd->posLow; i <= sd->posHigh; ++i) { + if (rbgMap[i]) + RET_FAIL(-33, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + rbgMap[i] = 1; + } + } + /* no problem, can allocate */ + slice_t *s = si->s[index]; + if (label) { + if (s->label) free(s->label); + s->label = label; + } + if (algo) { + s->dl_algo.unset(&s->dl_algo.data); + s->dl_algo = *(default_sched_dl_algo_t *) algo; + if (!s->dl_algo.data) + s->dl_algo.data = s->dl_algo.setup(); + } + if (dl) { + free(s->algo_data); + s->algo_data = dl; + } + return index; + } + + if (!dl) + RET_FAIL(-100, "%s(): no parameters for new slice %d, aborting\n", __func__, id); + + if (si->num >= MAX_STATIC_SLICES) + RET_FAIL(-2, "%s(): cannot have more than %d slices\n", __func__, MAX_STATIC_SLICES); + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *sd = si->s[s]->algo_data; + for (int i = sd->posLow; i <= sd->posHigh; ++i) + rbgMap[i] = 1; + } + + for (int i = dl->posLow; i <= dl->posHigh; ++i) + if (rbgMap[i]) + RET_FAIL(-3, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + + if (!algo) + RET_FAIL(-14, "%s(): no scheduler algorithm provided\n", __func__); + + slice_t *ns = _add_slice(&si->num, si->s); + if (!ns) + RET_FAIL(-4, "%s(): could not create new slice\n", __func__); + ns->id = id; + ns->label = label; + ns->dl_algo = *(default_sched_dl_algo_t *) algo; + if (!ns->dl_algo.data) + ns->dl_algo.data = ns->dl_algo.setup(); + ns->algo_data = dl; + + return si->num - 1; +} + +int addmod_static_slice_ul(slice_info_t *si, + int id, + char *label, + void *algo, + void *slice_params_ul) { + static_slice_param_t *ul = slice_params_ul; + /* Minimum 3RBs, because LTE stack requires this */ + if (ul && ul->posLow + 2 > ul->posHigh) + RET_FAIL(-1, "%s(): slice id %d posLow + 2 > posHigh\n", __func__, id); + + uint8_t rbMap[110] = { 0 }; + int index = _exists_slice(si->num, si->s, id); + if (index >= 0) { + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *su = ul && si->s[s]->id == id && ul ? ul : si->s[s]->algo_data; + for (int i = su->posLow; i <= su->posHigh; ++i) { + if (rbMap[i]) + RET_FAIL(-33, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + rbMap[i] = 1; + } + } + /* no problem, can allocate */ + slice_t *s = si->s[index]; + if (algo) { + s->ul_algo.unset(&s->ul_algo.data); + s->ul_algo = *(default_sched_ul_algo_t *) algo; + if (!s->ul_algo.data) + s->ul_algo.data = s->ul_algo.setup(); + } + if (label) { + if (s->label) free(s->label); + s->label = label; + } + if (ul) { + free(s->algo_data); + s->algo_data = ul; + } + return index; + } + + if (!ul) + RET_FAIL(-100, "%s(): no parameters for new slice %d, aborting\n", __func__, id); + + if (si->num >= MAX_STATIC_SLICES) + RET_FAIL(-2, "%s(): cannot have more than %d slices\n", __func__, MAX_STATIC_SLICES); + for (int s = 0; s < si->num; ++s) { + static_slice_param_t *sd = si->s[s]->algo_data; + for (int i = sd->posLow; i <= sd->posHigh; ++i) + rbMap[i] = 1; + } + + for (int i = ul->posLow; i <= ul->posHigh; ++i) + if (rbMap[i]) + RET_FAIL(-3, "%s(): overlap of slices detected at RBG %d\n", __func__, i); + + if (!algo) + RET_FAIL(-14, "%s(): no scheduler algorithm provided\n", __func__); + + slice_t *ns = _add_slice(&si->num, si->s); + if (!ns) + RET_FAIL(-4, "%s(): could not create new slice\n", __func__); + ns->id = id; + ns->label = label; + ns->ul_algo = *(default_sched_ul_algo_t *) algo; + if (!ns->ul_algo.data) + ns->ul_algo.data = ns->ul_algo.setup(); + ns->algo_data = ul; + + return si->num - 1; +} + +int remove_static_slice(slice_info_t *si, uint8_t slice_idx) { + if (slice_idx == 0) + return 0; + slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx); + if (!sr) + return 0; + free(sr->algo_data); + free(sr); + return 1; +} + +void static_dl(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe) { + UE_info_t *UE_info = &RC.mac[mod_id]->UE_info; + + store_dlsch_buffer(mod_id, CC_id, frame, subframe); + + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + + /* initialize per-UE scheduling information */ + ue_sched_ctrl->pre_nb_available_rbs[CC_id] = 0; + ue_sched_ctrl->dl_pow_off[CC_id] = 2; + memset(ue_sched_ctrl->rballoc_sub_UE[CC_id], 0, sizeof(ue_sched_ctrl->rballoc_sub_UE[CC_id])); + ue_sched_ctrl->pre_dci_dl_pdu_idx = -1; + } + + const int N_RBG = to_rbg(RC.mac[mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth); + const int RBGsize = get_min_rb_unit(mod_id, CC_id); + uint8_t *vrb_map = RC.mac[mod_id]->common_channels[CC_id].vrb_map; + uint8_t rbgalloc_mask[N_RBG_MAX]; + for (int i = 0; i < N_RBG; i++) { + // calculate mask: init to one + "AND" with vrb_map: + // if any RB in vrb_map is blocked (1), the current RBG will be 0 + rbgalloc_mask[i] = 1; + for (int j = 0; j < RBGsize; j++) + rbgalloc_mask[i] &= !vrb_map[RBGsize * i + j]; + } + + slice_info_t *s = RC.mac[mod_id]->pre_processor_dl.slices; + int max_num_ue; + switch (s->num) { + case 1: + max_num_ue = 4; + break; + case 2: + max_num_ue = 2; + break; + default: + max_num_ue = 1; + break; + } + for (int i = 0; i < s->num; ++i) { + if (s->s[i]->UEs.head < 0) + continue; + uint8_t rbgalloc_slice_mask[N_RBG_MAX]; + memset(rbgalloc_slice_mask, 0, sizeof(rbgalloc_slice_mask)); + static_slice_param_t *p = s->s[i]->algo_data; + int n_rbg_sched = 0; + for (int rbg = p->posLow; rbg <= p->posHigh && rbg <= N_RBG; ++rbg) { + rbgalloc_slice_mask[rbg] = rbgalloc_mask[rbg]; + n_rbg_sched += rbgalloc_mask[rbg]; + } + + s->s[i]->dl_algo.run(mod_id, + CC_id, + frame, + subframe, + &s->s[i]->UEs, + max_num_ue, // max_num_ue + n_rbg_sched, + rbgalloc_slice_mask, + s->s[i]->dl_algo.data); + } + + // the following block is meant for validation of the pre-processor to check + // whether all UE allocations are non-overlapping and is not necessary for + // scheduling functionality + char t[26] = "_________________________"; + t[N_RBG] = 0; + for (int i = 0; i < N_RBG; i++) + for (int j = 0; j < RBGsize; j++) + if (vrb_map[RBGsize*i+j] != 0) + t[i] = 'x'; + int print = 0; + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + const UE_sched_ctrl_t *ue_sched_ctrl = &UE_info->UE_sched_ctrl[UE_id]; + + if (ue_sched_ctrl->pre_nb_available_rbs[CC_id] == 0) + continue; + + LOG_D(MAC, + "%4d.%d UE%d %d RBs allocated, pre MCS %d\n", + frame, + subframe, + UE_id, + ue_sched_ctrl->pre_nb_available_rbs[CC_id], + UE_info->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1); + + print = 1; + + for (int i = 0; i < N_RBG; i++) { + if (!ue_sched_ctrl->rballoc_sub_UE[CC_id][i]) + continue; + for (int j = 0; j < RBGsize; j++) { + if (vrb_map[RBGsize*i+j] != 0) { + LOG_I(MAC, "%4d.%d DL scheduler allocation list: %s\n", frame, subframe, t); + LOG_E(MAC, "%4d.%d: UE %d allocated at locked RB %d/RBG %d\n", frame, + subframe, UE_id, RBGsize * i + j, i); + } + vrb_map[RBGsize*i+j] = 1; + } + t[i] = '0' + UE_id; + } + } + if (print) + LOG_D(MAC, "%4d.%d DL scheduler allocation list: %s\n", frame, subframe, t); +} + +void static_ul(module_id_t mod_id, + int CC_id, + frame_t frame, + sub_frame_t subframe, + frame_t sched_frame, + sub_frame_t sched_subframe) { + UE_info_t *UE_info = &RC.mac[mod_id]->UE_info; + const int N_RB_UL = to_prb(RC.mac[mod_id]->common_channels[CC_id].ul_Bandwidth); + COMMON_channels_t *cc = &RC.mac[mod_id]->common_channels[CC_id]; + + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id]; + UE_template->pre_assigned_mcs_ul = 0; + UE_template->pre_allocated_nb_rb_ul = 0; + UE_template->pre_allocated_rb_table_index_ul = -1; + UE_template->pre_first_nb_rb_ul = 0; + UE_template->pre_dci_ul_pdu_idx = -1; + } + + slice_info_t *s = RC.mac[mod_id]->pre_processor_ul.slices; + int max_num_ue; + switch (s->num) { + case 1: + max_num_ue = 4; + break; + case 2: + max_num_ue = 2; + break; + default: + max_num_ue = 1; + break; + } + for (int i = 0; i < s->num; ++i) { + if (s->s[i]->UEs.head < 0) + continue; + int last_rb_blocked = 1; + int n_contig = 0; + contig_rbs_t rbs[2]; // up to two contig RBs for PRACH in between + static_slice_param_t *p = s->s[i]->algo_data; + for (int rb = p->posLow; rb <= p->posHigh && rb < N_RB_UL; ++rb) { + if (cc->vrb_map_UL[rb] == 0 && last_rb_blocked) { + last_rb_blocked = 0; + n_contig++; + AssertFatal(n_contig <= 2, "cannot handle more than two contiguous RB regions\n"); + rbs[n_contig - 1].start = rb; + } + if (cc->vrb_map_UL[rb] == 1 && !last_rb_blocked) { + last_rb_blocked = 1; + rbs[n_contig - 1].length = rb - rbs[n_contig - 1].start; + } + } + if (!last_rb_blocked) + rbs[n_contig - 1].length = p->posHigh - rbs[n_contig - 1].start + 1; + + s->s[i]->ul_algo.run(mod_id, + CC_id, + frame, + subframe, + sched_frame, + sched_subframe, + &s->s[i]->UEs, + max_num_ue, // max_num_ue + n_contig, + rbs, + s->s[i]->ul_algo.data); + } + + // the following block is meant for validation of the pre-processor to check + // whether all UE allocations are non-overlapping and is not necessary for + // scheduling functionality + char t[101] = "__________________________________________________" + "__________________________________________________"; + t[N_RB_UL] = 0; + for (int j = 0; j < N_RB_UL; j++) + if (cc->vrb_map_UL[j] != 0) + t[j] = 'x'; + int print = 0; + for (int UE_id = UE_info->list.head; UE_id >= 0; UE_id = UE_info->list.next[UE_id]) { + UE_TEMPLATE *UE_template = &UE_info->UE_template[CC_id][UE_id]; + if (UE_template->pre_allocated_nb_rb_ul == 0) + continue; + + print = 1; + uint8_t harq_pid = subframe2harqpid(&RC.mac[mod_id]->common_channels[CC_id], + sched_frame, sched_subframe); + LOG_D(MAC, "%4d.%d UE%d %d RBs (index %d) at start %d, pre MCS %d %s\n", + frame, + subframe, + UE_id, + UE_template->pre_allocated_nb_rb_ul, + UE_template->pre_allocated_rb_table_index_ul, + UE_template->pre_first_nb_rb_ul, + UE_template->pre_assigned_mcs_ul, + UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] > 0 ? "(retx)" : ""); + + for (int i = 0; i < UE_template->pre_allocated_nb_rb_ul; ++i) { + /* only check if this is not a retransmission */ + if (UE_info->UE_sched_ctrl[UE_id].round_UL[CC_id][harq_pid] == 0 + && cc->vrb_map_UL[UE_template->pre_first_nb_rb_ul + i] == 1) { + + LOG_I(MAC, "%4d.%d UL scheduler allocation list: %s\n", frame, subframe, t); + LOG_E(MAC, + "%4d.%d: UE %d allocated at locked RB %d (is: allocated start " + "%d/length %d)\n", + frame, subframe, UE_id, UE_template->pre_first_nb_rb_ul + i, + UE_template->pre_first_nb_rb_ul, + UE_template->pre_allocated_nb_rb_ul); + } + cc->vrb_map_UL[UE_template->pre_first_nb_rb_ul + i] = 1; + t[UE_template->pre_first_nb_rb_ul + i] = UE_id + '0'; + } + } + if (print) + LOG_D(MAC, + "%4d.%d UL scheduler allocation list: %s\n", + sched_frame, + sched_subframe, + t); +} + +void static_destroy(slice_info_t **si) { + const int n = (*si)->num; + (*si)->num = 0; + for (int i = 0; i < n; ++i) { + slice_t *s = (*si)->s[i]; + if (s->label) + free(s->label); + free(s->algo_data); + free(s); + } + free((*si)->s); + free(*si); +} + +pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) { + slice_info_t *si = calloc(1, sizeof(slice_info_t)); + DevAssert(si); + + si->num = 0; + si->s = calloc(MAX_STATIC_SLICES, sizeof(slice_t)); + DevAssert(si->s); + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + si->UE_assoc_slice[i] = -1; + + /* insert default slice, all resources */ + static_slice_param_t *dlp = malloc(sizeof(static_slice_param_t)); + dlp->posLow = 0; + dlp->posHigh = to_rbg(RC.mac[mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - 1; + default_sched_dl_algo_t *algo = &RC.mac[mod_id]->pre_processor_dl.dl_algo; + DevAssert(0 == addmod_static_slice_dl(si, 0, strdup("default"), algo, dlp)); + const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) + slicing_add_UE(si, UE_id); + + pp_impl_param_t sttc; + sttc.algorithm = STATIC_SLICING; + sttc.add_UE = slicing_add_UE; + sttc.remove_UE = slicing_remove_UE; + sttc.move_UE = slicing_move_UE; + sttc.addmod_slice = addmod_static_slice_dl; + sttc.remove_slice = remove_static_slice; + sttc.dl = static_dl; + // current DL algo becomes default scheduler + sttc.dl_algo = *algo; + sttc.destroy = static_destroy; + sttc.slices = si; + + return sttc; +} + +pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) { + slice_info_t *si = calloc(1, sizeof(slice_info_t)); + DevAssert(si); + + si->num = 0; + si->s = calloc(MAX_STATIC_SLICES, sizeof(slice_t)); + DevAssert(si->s); + for (int i = 0; i < MAX_MOBILES_PER_ENB; ++i) + si->UE_assoc_slice[i] = -1; + + /* insert default slice, all resources */ + static_slice_param_t *ulp = malloc(sizeof(static_slice_param_t)); + ulp->posLow = 0; + ulp->posHigh = to_prb(RC.mac[mod_id]->common_channels[CC_id].ul_Bandwidth) - 1; + default_sched_ul_algo_t *algo = &RC.mac[mod_id]->pre_processor_ul.ul_algo; + DevAssert(0 == addmod_static_slice_ul(si, 0, strdup("default"), algo, ulp)); + const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; + for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) + slicing_add_UE(si, UE_id); + + pp_impl_param_t sttc; + sttc.algorithm = STATIC_SLICING; + sttc.add_UE = slicing_add_UE; + sttc.remove_UE = slicing_remove_UE; + sttc.move_UE = slicing_move_UE; + sttc.addmod_slice = addmod_static_slice_ul; + sttc.remove_slice = remove_static_slice; + sttc.ul = static_ul; + // current DL algo becomes default scheduler + sttc.ul_algo = *algo; + sttc.destroy = static_destroy; + sttc.slices = si; + + return sttc; +} diff --git a/openair2/LAYER2/MAC/slicing/slicing.h b/openair2/LAYER2/MAC/slicing/slicing.h new file mode 100644 index 0000000000..1099b50ea0 --- /dev/null +++ b/openair2/LAYER2/MAC/slicing/slicing.h @@ -0,0 +1,74 @@ +/* + * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The OpenAirInterface Software Alliance licenses this file to You under + * the OAI Public License, Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.openairinterface.org/?page_id=698 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------------------- + * For more information about the OpenAirInterface (OAI) Software Alliance: + * contact@openairinterface.org + */ + +/*! + * \file slicing.h + * \brief General slice definition and helper parameters + * \author Robert Schmidt + * \date 2020 + * \email robert.schmidt@eurecom.fr + */ + +#ifndef __SLICING_H__ +#define __SLICING_H__ + +#include "openair2/LAYER2/MAC/mac.h" + +typedef struct slice_s { + /// Arbitrary ID + slice_id_t id; + /// Arbitrary label + char *label; + + union { + default_sched_dl_algo_t dl_algo; + default_sched_ul_algo_t ul_algo; + }; + + /// A specific algorithm's implementation parameters + void *algo_data; + /// Internal data that might be kept alongside a slice's params + void *int_data; + + // list of users in this slice + UE_list_t UEs; +} slice_t; + +typedef struct slice_info_s { + uint8_t num; + slice_t **s; + uint8_t UE_assoc_slice[MAX_MOBILES_PER_ENB]; +} slice_info_t; + +int slicing_get_UE_slice_idx(slice_info_t *si, int UE_id); + +#define STATIC_SLICING 10 +/* only four static slices for UL, DL resp. (not enough DCIs) */ +#define MAX_STATIC_SLICES 4 +typedef struct { + uint16_t posLow; + uint16_t posHigh; +} static_slice_param_t; +pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id); +pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id); + + +#endif /* __SLICING_H__ */ diff --git a/openair2/LAYER2/MAC/slicing/slicing_internal.h b/openair2/LAYER2/MAC/slicing/slicing_internal.h new file mode 100644 index 0000000000..744f8924d9 --- /dev/null +++ b/openair2/LAYER2/MAC/slicing/slicing_internal.h @@ -0,0 +1,46 @@ +/* + * 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 slicing_internal.h + * \brief Internal slice helper functions + * \author Robert Schmidt + * \date 2020 + * \email robert.schmidt@eurecom.fr + */ + +#ifndef __SLICING_INTERNAL_H__ +#define __SLICING_INTERNAL_H__ + +#include "slicing.h" + +void slicing_add_UE(slice_info_t *si, int UE_id); + +void _remove_UE(slice_t **s, uint8_t *assoc, int UE_id); +void slicing_remove_UE(slice_info_t *si, int UE_id); + +void _move_UE(slice_t **s, uint8_t *assoc, int UE_id, int to); +void slicing_move_UE(slice_info_t *si, int UE_id, int idx); + +slice_t *_add_slice(uint8_t *n, slice_t **s); +slice_t *_remove_slice(uint8_t *n, slice_t **s, uint8_t *assoc, int idx); + +#endif /* __SLICING_INTERNAL_H__ */ From 4901daf75901901d66df158bc10a10db471f53f3 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Thu, 18 Jun 2020 19:12:15 +0200 Subject: [PATCH 089/171] FlexRAN: New protobuf slice structure + Static Slice handling --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 139 ++++++--- .../CONTROL_MODULES/MAC/flexran_agent_mac.h | 13 +- .../MAC/flexran_agent_mac_internal.c | 202 ++++++++++--- .../MAC/flexran_agent_mac_internal.h | 20 +- .../ENB_APP/MESSAGES/V2/config_common.proto | 25 ++ .../ENB_APP/MESSAGES/V2/config_messages.proto | 2 + openair2/ENB_APP/flexran_agent_common.c | 12 +- openair2/ENB_APP/flexran_agent_ran_api.c | 277 ++++++++++++++++-- openair2/ENB_APP/flexran_agent_ran_api.h | 45 ++- openair2/LAYER2/MAC/main.c | 2 + openair2/LAYER2/MAC/slicing/slicing.c | 21 +- 11 files changed, 614 insertions(+), 144 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 4800fccea9..e5d1c94c95 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1452,9 +1452,74 @@ void flexran_agent_fill_mac_cell_config(mid_t mod_id, uint8_t cc_id, conf->si_config->has_sfn = 1; } - /* get a pointer to the config which is maintained in the agent throughout - * its lifetime */ - conf->slice_config = flexran_agent_get_slice_config(mod_id); + conf->slice_config = malloc(sizeof(Protocol__FlexSliceConfig)); + if (conf->slice_config) { + protocol__flex_slice_config__init(conf->slice_config); + Protocol__FlexSliceConfig *sc = conf->slice_config; + + sc->dl = malloc(sizeof(Protocol__FlexSliceDlUlConfig)); + DevAssert(sc->dl); + protocol__flex_slice_dl_ul_config__init(sc->dl); + sc->dl->algorithm = flexran_get_dl_slice_algo(mod_id); + sc->dl->has_algorithm = 1; + sc->dl->n_slices = flexran_get_num_dl_slices(mod_id); + if (sc->dl->n_slices > 0) { + sc->dl->slices = calloc(sc->dl->n_slices, sizeof(Protocol__FlexSlice *)); + DevAssert(sc->dl->slices); + for (int i = 0; i < sc->dl->n_slices; ++i) { + sc->dl->slices[i] = malloc(sizeof(Protocol__FlexSlice)); + DevAssert(sc->dl->slices[i]); + protocol__flex_slice__init(sc->dl->slices[i]); + flexran_get_dl_slice(mod_id, i, sc->dl->slices[i], sc->dl->algorithm); + } + } else { + sc->dl->scheduler = flexran_get_dl_scheduler_name(mod_id); + } + + sc->ul = malloc(sizeof(Protocol__FlexSliceDlUlConfig)); + DevAssert(sc->ul); + protocol__flex_slice_dl_ul_config__init(sc->ul); + sc->ul->algorithm = flexran_get_ul_slice_algo(mod_id); + sc->ul->has_algorithm = 1; + sc->ul->n_slices = flexran_get_num_ul_slices(mod_id); + if (sc->ul->n_slices > 0) { + sc->ul->slices = calloc(sc->ul->n_slices, sizeof(Protocol__FlexSlice *)); + DevAssert(sc->ul->slices); + for (int i = 0; i < sc->ul->n_slices; ++i) { + sc->ul->slices[i] = malloc(sizeof(Protocol__FlexSlice)); + DevAssert(sc->ul->slices[i]); + protocol__flex_slice__init(sc->ul->slices[i]); + flexran_get_ul_slice(mod_id, i, sc->ul->slices[i], sc->ul->algorithm); + } + } else { + sc->ul->scheduler = flexran_get_ul_scheduler_name(mod_id); + } + } +} + +void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf) { + Protocol__FlexSliceConfig *sc = conf->slice_config; + for (int i = 0; i < sc->dl->n_slices; ++i) { + free(sc->dl->slices[i]); + sc->dl->slices[i] = NULL; + /* scheduler names are not freed: we assume we read them directly from the + * underlying memory and do not dispose it */ + } + free(sc->dl->slices); + /* scheduler name is not freed */ + free(sc->dl); + sc->dl = NULL; + for (int i = 0; i < sc->ul->n_slices; ++i) { + free(sc->ul->slices[i]); + sc->ul->slices[i] = NULL; + /* scheduler names are not freed */ + } + free(sc->ul->slices); + /* scheduler name is not freed */ + free(sc->ul); + sc->ul = NULL; + free(conf->slice_config); + conf->slice_config = NULL; } void flexran_agent_fill_mac_ue_config(mid_t mod_id, mid_t ue_id, @@ -1568,46 +1633,46 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) return 0; } - -void flexran_create_config_structures(mid_t mod_id) -{ - int i; - int n_dl = flexran_get_num_dl_slices(mod_id); - int m_ul = flexran_get_num_ul_slices(mod_id); - slice_config[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); - sc_update[mod_id] = flexran_agent_create_slice_config(n_dl, m_ul); - if (!slice_config[mod_id] || !sc_update[mod_id]) return; - - //flexran_agent_read_slice_config(mod_id, slice_config[mod_id]); - //flexran_agent_read_slice_config(mod_id, sc_update[mod_id]); - for (i = 0; i < n_dl; i++) { - //flexran_agent_read_slice_dl_config(mod_id, i, slice_config[mod_id]->dl[i]); - //flexran_agent_read_slice_dl_config(mod_id, i, sc_update[mod_id]->dl[i]); +void helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) { + if (slice_config->dl) { + if (slice_config->dl->scheduler) + free(slice_config->dl->scheduler); + for (int i = 0; i < slice_config->dl->n_slices; i++) + if (slice_config->dl->slices[i]->scheduler) + free(slice_config->dl->slices[i]->scheduler); } - for (i = 0; i < m_ul; i++) { - //flexran_agent_read_slice_ul_config(mod_id, i, slice_config[mod_id]->ul[i]); - //flexran_agent_read_slice_ul_config(mod_id, i, sc_update[mod_id]->ul[i]); + if (slice_config->ul) { + if (slice_config->ul->scheduler) + free(slice_config->ul->scheduler); + for (int i = 0; i < slice_config->ul->n_slices; i++) + if (slice_config->ul->slices[i]->scheduler) + free(slice_config->ul->slices[i]->scheduler); } + + Protocol__FlexCellConfig helper; + helper.slice_config = slice_config; + flexran_agent_destroy_mac_slice_config(&helper); } -void flexran_check_and_remove_slices(mid_t mod_id) -{ +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) { + if (!*slice_config) return; + Protocol__FlexSliceConfig *sc = *slice_config; + *slice_config = NULL; + + /* TODO handle using lock-free queue */ + apply_update_dl_slice_config(mod_id, sc->dl); + apply_update_ul_slice_config(mod_id, sc->ul); + + helper_destroy_mac_slice_config(*slice_config); } -void flexran_agent_slice_update(mid_t mod_id) -{ +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config) { + /* TODO handle using lock-free queue */ + apply_ue_slice_assoc_update(mod_id, *ue_config); + + free(*ue_config); + *ue_config = NULL; } -Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id) -{ - if (!slice_config[mod_id]) return NULL; - Protocol__FlexSliceConfig *config = NULL; - - pthread_mutex_lock(&sc_update_mtx); - if (!config) { - pthread_mutex_unlock(&sc_update_mtx); - return NULL; - } - pthread_mutex_unlock(&sc_update_mtx); - return config; +void flexran_agent_slice_update(mid_t mod_id) { } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h index 2f9f99c740..5a8d4f31aa 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.h @@ -115,7 +115,16 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id); /* Inform controller about possibility to update slice configuration */ void flexran_agent_slice_update(mid_t mod_id); -/* return a pointer to the current config */ -Protocol__FlexSliceConfig *flexran_agent_get_slice_config(mid_t mod_id); +/* marks slice_config so that it can be applied later. Takes ownership of the + * FlexSliceConfig message */ +void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice); + +/* inserts a new ue_config into the structure keeping ue to slice association + * updates and marks so it can be applied. Takes ownership of the FlexUeConfig message */ +void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config); + +/* free slice_config part of flexCellConfig, filled in + * flexran_agent_fill_mac_cell_config() */ +void flexran_agent_destroy_mac_slice_config(Protocol__FlexCellConfig *conf); #endif diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c index 4c80c561ee..93de0b11ec 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.c @@ -1025,60 +1025,166 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name) { } -Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul) -{ - Protocol__FlexSliceConfig *fsc = malloc(sizeof(Protocol__FlexSliceConfig)); - if (!fsc) return NULL; - protocol__flex_slice_config__init(fsc); - - /* TODO */ - return fsc; -} - -void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *sup) -{ -} - - -void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) -{ - if (n_ue_slice_assoc_updates == 10) { - LOG_E(FLEXRAN_AGENT, - "[%d] can not handle flex_ue_config message, buffer is full; try again later\n", - mod_id); - return; +void update_or_remove_dl(mid_t mod_id, Protocol__FlexSlice *s) { + if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET + && !s->label && !s->scheduler) { + LOG_I(FLEXRAN_AGENT, "remove DL slice ID %d\n", s->id); + const int rc = flexran_remove_dl_slice(mod_id, s); + if (!rc) + LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id); + } else { + LOG_I(FLEXRAN_AGENT, "updating DL slice ID %d\n", s->id); + const int rc = flexran_create_dl_slice(mod_id, s); + if (rc < 0) + LOG_W(FLEXRAN_AGENT, + "error while update slice ID %d: flexran_create_dl_slice() -> %d\n", + s->id, rc); } +} + +void update_or_remove_ul(mid_t mod_id, Protocol__FlexSlice *s) { + if (s->params_case == PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET + && !s->label && !s->scheduler) { + LOG_I(FLEXRAN_AGENT, "remove UL slice ID %d\n", s->id); + const int rc = flexran_remove_ul_slice(mod_id, s); + if (!rc) + LOG_W(FLEXRAN_AGENT, "error while removing slice ID %d\n", s->id); + } else { + LOG_I(FLEXRAN_AGENT, "updating UL slice ID %d\n", s->id); + const int rc = flexran_create_ul_slice(mod_id, s); + if (rc < 0) + LOG_W(FLEXRAN_AGENT, + "error while updating slice ID %d: flexran_create_ul_slice() -> %d)\n", + s->id, rc); + } +} + +void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *dl) { + if (!dl) + return; + + Protocol__FlexSliceAlgorithm dl_algo = flexran_get_dl_slice_algo(mod_id); + if (dl->has_algorithm && dl_algo != dl->algorithm) { + LOG_I(FLEXRAN_AGENT, "loading new DL slice algorithm %d\n", dl->algorithm); + dl_algo = dl->algorithm; + flexran_set_dl_slice_algo(mod_id, dl_algo); + } + + /* first update existing slices, then create new. Thus, we go through the + * list twice. First round, if a slice exists, handle and mark as such. Then, + * apply all others in the second round */ + if (dl->n_slices > 0) { + if (dl_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n"); + return; + } + int handled_dl[dl->n_slices]; + for (int i = 0; i < dl->n_slices; ++i) { + if (flexran_find_dl_slice(mod_id, dl->slices[i]->id) < 0) { + handled_dl[i] = 0; + continue; + } + update_or_remove_dl(mod_id, dl->slices[i]); + handled_dl[i] = 1; + } + for (int i = 0; i < dl->n_slices; ++i) { + if (handled_dl[i]) + continue; + update_or_remove_dl(mod_id, dl->slices[i]); + } + } + + if (dl->scheduler) { + if (dl_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n"); + return; + } + LOG_I(FLEXRAN_AGENT, "loading DL new scheduling algorithm '%s'\n", dl->scheduler); + const int rc = flexran_set_dl_scheduler(mod_id, dl->scheduler); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, + "error while updating scheduling algorithm: " + "flexran_update_dl_sched_algo() -> %d)\n", + rc); + return; + } + } +} + +void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *ul) { + if (!ul) + return; + + Protocol__FlexSliceAlgorithm ul_algo = flexran_get_ul_slice_algo(mod_id); + if (ul->has_algorithm && ul_algo != ul->algorithm) { + LOG_I(FLEXRAN_AGENT, "loading new UL slice algorithm %d\n", ul->algorithm); + ul_algo = ul->algorithm; + flexran_set_ul_slice_algo(mod_id, ul_algo); + } + if (ul->n_slices > 0) { + if (ul_algo == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update slices: no algorithm loaded\n"); + return; + } + int handled_ul[ul->n_slices]; + for (int i = 0; i < ul->n_slices; ++i) { + if (flexran_find_ul_slice(mod_id, ul->slices[i]->id) < 0) { + handled_ul[i] = 0; + continue; + } + update_or_remove_ul(mod_id, ul->slices[i]); + handled_ul[i] = 1; + } + for (int i = 0; i < ul->n_slices; ++i) { + if (handled_ul[i]) + continue; + update_or_remove_ul(mod_id, ul->slices[i]); + } + } + + if (ul->scheduler) { + if (ul_algo != PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "cannot update scheduling algorithm: slice algorithm loaded\n"); + return; + } + LOG_I(FLEXRAN_AGENT, "loading new UL scheduling algorithm '%s'\n", ul->scheduler); + const int rc = flexran_set_ul_scheduler(mod_id, ul->scheduler); + if (rc < 0) { + LOG_E(FLEXRAN_AGENT, + "error while updating scheduling algorithm: " + "flexran_update_dl_sched_algo() -> %d)\n", + rc); + return; + } + } +} + +int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config) +{ if (!ue_config->has_rnti) { LOG_E(FLEXRAN_AGENT, "[%d] cannot update UE to slice association, no RNTI in flex_ue_config message\n", mod_id); - return; + return 0; } - if (ue_config->has_dl_slice_id) - LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to DL slice ID %d\n", - mod_id, ue_config->rnti, ue_config->dl_slice_id); - if (ue_config->has_ul_slice_id) - LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %#x to UL slice ID %d\n", - mod_id, ue_config->rnti, ue_config->ul_slice_id); - ue_slice_assoc_update[n_ue_slice_assoc_updates++] = ue_config; - perform_slice_config_update_count = 2; -} - -int apply_ue_slice_assoc_update(mid_t mod_id) -{ - int i; - int changes = 0; - for (i = 0; i < n_ue_slice_assoc_updates; i++) { - int ue_id = find_UE_id(mod_id, ue_slice_assoc_update[i]->rnti); - if (ue_id < 0 || ue_id > MAX_MOBILES_PER_ENB){ - LOG_E(FLEXRAN_AGENT,"UE_id %d is wrong!!\n",ue_id); - continue; - } - if (ue_slice_assoc_update[i]->has_dl_slice_id) { - } - if (ue_slice_assoc_update[i]->has_ul_slice_id) { + int UE_id = flexran_get_mac_ue_id_rnti(mod_id, ue_config->rnti); + if (ue_config->has_dl_slice_id) { + if (flexran_get_dl_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "no DL slice algorithm loaded\n"); + } else { + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to DL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->dl_slice_id); + flexran_set_ue_dl_slice_id(mod_id, UE_id, ue_config->dl_slice_id); } } - n_ue_slice_assoc_updates = 0; - return changes; + if (ue_config->has_ul_slice_id) { + if (flexran_get_ul_slice_algo(mod_id) == PROTOCOL__FLEX_SLICE_ALGORITHM__None) { + LOG_E(FLEXRAN_AGENT, "no UL slice algorithm loaded\n"); + } else { + LOG_I(FLEXRAN_AGENT, "[%d] associating UE RNTI %04x - %d/UE %d to UL slice ID %d\n", + mod_id, ue_config->rnti, ue_config->rnti, UE_id, ue_config->ul_slice_id); + flexran_set_ue_ul_slice_id(mod_id, UE_id, ue_config->ul_slice_id); + } + } + return 0; } diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h index ef2a7e40a9..9db5d61a11 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac_internal.h @@ -103,23 +103,11 @@ int load_dl_scheduler_function(mid_t mod_id, const char *function_name); /*** Functions for handling a slice config ***/ -/* allocate memory for a Protocol__FlexSliceConfig structure with n_dl DL slice - * configs and m_ul UL slice configs */ -Protocol__FlexSliceConfig *flexran_agent_create_slice_config(int n_dl, int m_ul); - -/* read the general slice parameters via RAN into the given - * Protocol__FlexSliceConfig struct */ -void flexran_agent_read_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *s); - -/* reads content of slice over the sc_update structure, so that it can be - * applied later by performing a diff between slice_config and sc_update */ -void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig *slice); - -/* inserts a new ue_config into the structure keeping ue to slice association - * updates and marks so it can be applied */ -void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); +/* Prepare the application of a slicing config */ +void apply_update_dl_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice); +void apply_update_ul_slice_config(mid_t mod_id, Protocol__FlexSliceDlUlConfig *slice); /* apply a new association between a UE and a slice (both DL and UL) */ -int apply_ue_slice_assoc_update(mid_t mod_id); +int apply_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig *ue_config); #endif /*FLEXRAN_AGENT_MAC_INTERNAL_H_*/ diff --git a/openair2/ENB_APP/MESSAGES/V2/config_common.proto b/openair2/ENB_APP/MESSAGES/V2/config_common.proto index e5d01ebdc0..2f2267b628 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_common.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_common.proto @@ -61,6 +61,31 @@ enum flex_qam { // // Slice config related structures and enums // +enum flex_slice_algorithm { + None = 0; + Static = 1; + NVS = 2; +} + +message flex_slice_static { + optional uint32 posLow = 1; + optional uint32 posHigh = 2; +} + +message flex_slice { + optional uint32 id = 1; + optional string label = 2; + optional string scheduler = 3; + oneof params { + flex_slice_static static = 10; + } +} + +message flex_slice_dl_ul_config { + optional flex_slice_algorithm algorithm = 1; + repeated flex_slice slices = 2; + optional string scheduler = 3; // if no slicing +} // // UE config related structures and enums diff --git a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto index 1a66a4f20f..1a69deec71 100644 --- a/openair2/ENB_APP/MESSAGES/V2/config_messages.proto +++ b/openair2/ENB_APP/MESSAGES/V2/config_messages.proto @@ -49,6 +49,8 @@ message flex_cell_config { } message flex_slice_config { + optional flex_slice_dl_ul_config dl = 6; + optional flex_slice_dl_ul_config ul = 7; } message flex_ue_config { diff --git a/openair2/ENB_APP/flexran_agent_common.c b/openair2/ENB_APP/flexran_agent_common.c index 3dd9f5b957..7569ca1ac1 100644 --- a/openair2/ENB_APP/flexran_agent_common.c +++ b/openair2/ENB_APP/flexran_agent_common.c @@ -306,6 +306,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { if (reply->cell_config[i]->mbsfn_subframe_config_sfalloc) free(reply->cell_config[i]->mbsfn_subframe_config_sfalloc); + /* si_config is shared between MAC and RRC, free here */ if (reply->cell_config[i]->si_config) { for(int j = 0; j < reply->cell_config[i]->si_config->n_si_message; j++) { free(reply->cell_config[i]->si_config->si_message[j]); @@ -316,8 +317,7 @@ int flexran_agent_destroy_enb_config_reply(Protocol__FlexranMessage *msg) { } if (reply->cell_config[i]->slice_config) { - /* TODO */ - free(reply->cell_config[i]->slice_config); + flexran_agent_destroy_mac_slice_config(reply->cell_config[i]); } free(reply->cell_config[i]); @@ -880,7 +880,7 @@ int flexran_agent_handle_enb_config_reply(mid_t mod_id, const void *params, Prot if (enb_config->n_cell_config > 0) { if (flexran_agent_get_mac_xface(mod_id) && enb_config->cell_config[0]->slice_config) { - prepare_update_slice_config(mod_id, enb_config->cell_config[0]->slice_config); + prepare_update_slice_config(mod_id, &enb_config->cell_config[0]->slice_config); } if (enb_config->cell_config[0]->has_eutra_band && enb_config->cell_config[0]->has_dl_freq @@ -921,7 +921,11 @@ int flexran_agent_handle_ue_config_reply(mid_t mod_id, const void *params, Proto Protocol__FlexUeConfigReply *ue_config_reply = input->ue_config_reply_msg; for (i = 0; flexran_agent_get_mac_xface(mod_id) && i < ue_config_reply->n_ue_config; i++) - prepare_ue_slice_assoc_update(mod_id, ue_config_reply->ue_config[i]); + prepare_ue_slice_assoc_update(mod_id, &ue_config_reply->ue_config[i]); + /* prepare_ue_slice_assoc_update takes ownership of the individual + * FlexUeConfig messages. Therefore, mark zero messages to not accidentally + * free them twice */ + ue_config_reply->n_ue_config = 0; *msg = NULL; return 0; diff --git a/openair2/ENB_APP/flexran_agent_ran_api.c b/openair2/ENB_APP/flexran_agent_ran_api.c index cd8b0b8f67..79c992a4d7 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.c +++ b/openair2/ENB_APP/flexran_agent_ran_api.c @@ -30,6 +30,7 @@ #include "flexran_agent_ran_api.h" #include "s1ap_eNB_ue_context.h" #include "s1ap_eNB_management_procedures.h" +#include "openair2/LAYER2/MAC/slicing/slicing.h" static inline int phy_is_present(mid_t mod_id, uint8_t cc_id) { return RC.eNB && RC.eNB[mod_id] && RC.eNB[mod_id][cc_id]; @@ -3013,66 +3014,294 @@ uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti) } /**************************** SLICING ****************************/ +Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id) { + if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + + switch (RC.mac[mod_id]->pre_processor_dl.algorithm) { + case STATIC_SLICING: + return PROTOCOL__FLEX_SLICE_ALGORITHM__Static; + default: + return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + } +} + +int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return 0; + eNB_MAC_INST *mac = RC.mac[mod_id]; + const int cc_id = 0; + + pp_impl_param_t dl = mac->pre_processor_dl; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + mac->pre_processor_dl = static_dl_init(mod_id, cc_id); + break; + default: + mac->pre_processor_dl.algorithm = 0; + mac->pre_processor_dl.dl = dlsch_scheduler_pre_processor; + mac->pre_processor_dl.dl_algo.data = mac->pre_processor_dl.dl_algo.setup(); + mac->pre_processor_dl.slices = NULL; + break; + } + if (dl.slices) + dl.destroy(&dl.slices); + if (dl.dl_algo.data) + dl.dl_algo.unset(&dl.dl_algo.data); + return 1; +} + +Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id) { + if (!mac_is_present(mod_id)) return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + + switch (RC.mac[mod_id]->pre_processor_ul.algorithm) { + case STATIC_SLICING: + return PROTOCOL__FLEX_SLICE_ALGORITHM__Static; + default: + return PROTOCOL__FLEX_SLICE_ALGORITHM__None; + } +} + +int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return 0; + eNB_MAC_INST *mac = RC.mac[mod_id]; + const int cc_id = 0; + + pp_impl_param_t ul = mac->pre_processor_ul; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + mac->pre_processor_ul = static_ul_init(mod_id, cc_id); + break; + default: + mac->pre_processor_ul.algorithm = 0; + mac->pre_processor_ul.ul = ulsch_scheduler_pre_processor; + mac->pre_processor_ul.ul_algo.data = mac->pre_processor_ul.ul_algo.setup(); + mac->pre_processor_ul.slices = NULL; + break; + } + if (ul.slices) + ul.destroy(&ul.slices); + if (ul.ul_algo.data) + ul.ul_algo.unset(&ul.ul_algo.data); + return 1; +} + int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - return 0; + slice_info_t *slices = RC.mac[mod_id]->pre_processor_dl.slices; + if (!slices) return -1; + const int idx = slices->UE_assoc_slice[ue_id]; + return slices->s[idx]->id; +} + +void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { + if (!mac_is_present(mod_id)) return; + int idx = flexran_find_dl_slice(mod_id, slice_id); + if (idx < 0) return; + pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; + dl->move_UE(dl->slices, ue_id, idx); } int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id) { if (!mac_is_present(mod_id)) return -1; - return 0; + slice_info_t *slices = RC.mac[mod_id]->pre_processor_ul.slices; + if (!slices) return -1; + const int idx = slices->UE_assoc_slice[ue_id]; + return slices->s[idx]->id; } -/* TODO */ -int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return -1; - return -1; +void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id) { + if (!mac_is_present(mod_id)) return; + int idx = flexran_find_ul_slice(mod_id, slice_id); + if (idx < 0) return; + pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; + ul->move_UE(ul->slices, ue_id, idx); } -/* TODO */ -int flexran_remove_dl_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; +int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return 0; + void *params = NULL; + switch (s->params_case) { + case PROTOCOL__FLEX_SLICE__PARAMS_STATIC: + params = malloc(sizeof(static_slice_param_t)); + if (!params) return 0; + ((static_slice_param_t *)params)->posLow = s->static_->poslow; + ((static_slice_param_t *)params)->posHigh = s->static_->poshigh; + break; + default: + break; + } + pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; + char *l = s->label ? strdup(s->label) : NULL; + void *algo = &dl->dl_algo; // default scheduler + if (s->scheduler) { + algo = dlsym(NULL, s->scheduler); + if (!algo) { + free(params); + LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); + return -15; + } + } + return dl->addmod_slice(dl->slices, s->id, l, algo, params); +} + +int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return 0; + const int idx = flexran_find_dl_slice(mod_id, s->id); + if (idx < 0) return 0; + pp_impl_param_t *dl = &RC.mac[mod_id]->pre_processor_dl; + return dl->remove_slice(dl->slices, idx); } int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; + slice_info_t *si = RC.mac[mod_id]->pre_processor_dl.slices; + for (int i = 0; i < si->num; ++i) + if (si->s[i]->id == slice_id) + return i; return -1; } -//int flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { -//} +void flexran_get_dl_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return; + slice_t *s_ = RC.mac[mod_id]->pre_processor_dl.slices->s[slice_idx]; + slice->has_id = 1; + slice->id = s_->id; + slice->label = s_->label; + slice->scheduler = s_->dl_algo.name; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic)); + if (!slice->static_) return; + protocol__flex_slice_static__init(slice->static_); + slice->static_->has_poslow = 1; + slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow; + slice->static_->has_poshigh = 1; + slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC; + break; + default: + break; + } +} int flexran_get_num_dl_slices(mid_t mod_id) { - if (!mac_is_present(mod_id)) return -1; - return 0; + if (!mac_is_present(mod_id)) return 0; + if (!RC.mac[mod_id]->pre_processor_dl.slices) return 0; + return RC.mac[mod_id]->pre_processor_dl.slices->num; } -/* TODO */ -void flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id) { - if (!mac_is_present(mod_id)) return; - return; +int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return -1; + void *params = NULL; + switch (s->params_case) { + case PROTOCOL__FLEX_SLICE__PARAMS_STATIC: + params = malloc(sizeof(static_slice_param_t)); + if (!params) return 0; + ((static_slice_param_t *)params)->posLow = s->static_->poslow; + ((static_slice_param_t *)params)->posHigh = s->static_->poshigh; + break; + default: + break; + } + pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; + char *l = s->label ? strdup(s->label) : NULL; + void *algo = &ul->ul_algo; // default scheduler + if (s->scheduler) { + algo = dlsym(NULL, s->scheduler); + if (!algo) { + free(params); + LOG_E(FLEXRAN_AGENT, "cannot locate scheduler '%s'\n", s->scheduler); + return -15; + } + } + return ul->addmod_slice(ul->slices, s->id, l, algo, params); } -/* TODO */ -int flexran_remove_ul_slice(mid_t mod_id, int slice_idx) { - if (!mac_is_present(mod_id)) return -1; - return -1; +int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s) { + if (!mac_is_present(mod_id)) return 0; + const int idx = flexran_find_ul_slice(mod_id, s->id); + if (idx < 0) return 0; + pp_impl_param_t *ul = &RC.mac[mod_id]->pre_processor_ul; + return ul->remove_slice(ul->slices, idx); } int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id) { if (!mac_is_present(mod_id)) return -1; + slice_info_t *si = RC.mac[mod_id]->pre_processor_ul.slices; + for (int i = 0; i < si->num; ++i) + if (si->s[i]->id == slice_id) + return i; return -1; } -//int flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s) { -//} +void flexran_get_ul_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo) { + if (!mac_is_present(mod_id)) return; + slice_t *s_ = RC.mac[mod_id]->pre_processor_ul.slices->s[slice_idx]; + slice->has_id = 1; + slice->id = s_->id; + slice->label = s_->label; + slice->scheduler = s_->ul_algo.name; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS__NOT_SET; + switch (algo) { + case PROTOCOL__FLEX_SLICE_ALGORITHM__Static: + slice->static_ = malloc(sizeof(Protocol__FlexSliceStatic)); + if (!slice->static_) return; + protocol__flex_slice_static__init(slice->static_); + slice->static_->has_poslow = 1; + slice->static_->poslow = ((static_slice_param_t *)s_->algo_data)->posLow; + slice->static_->has_poshigh = 1; + slice->static_->poshigh = ((static_slice_param_t *)s_->algo_data)->posHigh; + slice->params_case = PROTOCOL__FLEX_SLICE__PARAMS_STATIC; + break; + default: + break; + } + +} int flexran_get_num_ul_slices(mid_t mod_id) { + if (!mac_is_present(mod_id)) return 0; + if (!RC.mac[mod_id]->pre_processor_ul.slices) return 0; + return RC.mac[mod_id]->pre_processor_ul.slices->num; +} + +char *flexran_get_dl_scheduler_name(mid_t mod_id) { + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->pre_processor_dl.dl_algo.name; +} + +int flexran_set_dl_scheduler(mid_t mod_id, char *sched) { if (!mac_is_present(mod_id)) return -1; + void *d = dlsym(NULL, sched); + if (!d) return -2; + pp_impl_param_t *dl_pp = &RC.mac[mod_id]->pre_processor_dl; + dl_pp->dl_algo.unset(&dl_pp->dl_algo.data); + dl_pp->dl_algo = *(default_sched_dl_algo_t *) d; + dl_pp->dl_algo.data = dl_pp->dl_algo.setup(); return 0; } +char *flexran_get_ul_scheduler_name(mid_t mod_id) { + if (!mac_is_present(mod_id)) return NULL; + return RC.mac[mod_id]->pre_processor_ul.ul_algo.name; +} + +int flexran_set_ul_scheduler(mid_t mod_id, char *sched) { + if (!mac_is_present(mod_id)) return -1; + void *d = dlsym(NULL, sched); + if (!d) return -2; + pp_impl_param_t *ul_pp = &RC.mac[mod_id]->pre_processor_ul; + ul_pp->ul_algo.unset(&ul_pp->ul_algo.data); + ul_pp->ul_algo = *(default_sched_ul_algo_t *) d; + ul_pp->ul_algo.data = ul_pp->ul_algo.setup(); + return 0; +} /************************** S1AP **************************/ int flexran_get_s1ap_mme_pending(mid_t mod_id){ diff --git a/openair2/ENB_APP/flexran_agent_ran_api.h b/openair2/ENB_APP/flexran_agent_ran_api.h index c29ba53c11..2d8a86f7d0 100644 --- a/openair2/ENB_APP/flexran_agent_ran_api.h +++ b/openair2/ENB_APP/flexran_agent_ran_api.h @@ -656,41 +656,66 @@ int flexran_agent_rrc_gtp_get_teid_sgw(mid_t mod_id, rnti_t rnti, int index); uint32_t flexran_get_rrc_enb_ue_s1ap_id(mid_t mod_id, rnti_t rnti); /************************** Slice configuration **************************/ +/* Get the currently active DL slicing algorithm */ +Protocol__FlexSliceAlgorithm flexran_get_dl_slice_algo(mid_t mod_id); +/* Set the active DL slicing algorithm */ +int flexran_set_dl_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo); + +/* Get the currently active UL slicing algorithm */ +Protocol__FlexSliceAlgorithm flexran_get_ul_slice_algo(mid_t mod_id); +/* Set the active UL slicing algorithm */ +int flexran_set_ul_slice_algo(mid_t mod_id, Protocol__FlexSliceAlgorithm algo); /* Get the DL slice ID for a UE */ int flexran_get_ue_dl_slice_id(mid_t mod_id, mid_t ue_id); -/* Set the DL slice index(!) for a UE */ -//void flexran_set_ue_dl_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +/* Set the DL slice for a UE */ +void flexran_set_ue_dl_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); /* Get the UL slice ID for a UE */ int flexran_get_ue_ul_slice_id(mid_t mod_id, mid_t ue_id); -/* Set the UL slice index(!) for a UE */ -//void flexran_set_ue_ul_slice_idx(mid_t mod_id, mid_t ue_id, int slice_idx); +/* Set the UL slice for a UE */ +void flexran_set_ue_ul_slice_id(mid_t mod_id, mid_t ue_id, slice_id_t slice_id); /* Create slice in DL, returns the new slice index */ -//int flexran_create_dl_slice(mid_t mod_id, slice_id_t slice_id); +int flexran_create_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Remove slice in DL, returns new number of slices or -1 on error */ -//int flexran_remove_dl_slice(mid_t mod_id, int slice_idx); +int flexran_remove_dl_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Finds slice in DL with given slice_id and returns slice index */ int flexran_find_dl_slice(mid_t mod_id, slice_id_t slice_id); /* Return the parameters of slice at index slice_idx */ -//void flexran_get_dl_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); +void flexran_get_dl_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo); /* Get the number of slices in DL */ int flexran_get_num_dl_slices(mid_t mod_id); /* Create slice in UL, returns the new slice index */ -//int flexran_create_ul_slice(mid_t mod_id, slice_id_t slice_id); +int flexran_create_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Remove slice in UL */ -//int flexran_remove_ul_slice(mid_t mod_id, int slice_idx); +int flexran_remove_ul_slice(mid_t mod_id, const Protocol__FlexSlice *s); /* Finds slice in DL with given slice_id and returns slice index */ int flexran_find_ul_slice(mid_t mod_id, slice_id_t slice_id); /* Return the parameters of slice at index slice_idx */ -//void flexran_get_ul_slice(mid_t mod_id, int slice_idx, Protocol__FlexSlice *s); +void flexran_get_ul_slice(mid_t mod_id, + int slice_idx, + Protocol__FlexSlice *slice, + Protocol__FlexSliceAlgorithm algo); /* Get the number of slices in UL */ int flexran_get_num_ul_slices(mid_t mod_id); +/* Get the name of/Set the DL scheduling algorithm. If slicing is active, this + * corresponds to the default algorithm for slices, otherwise the currently + * used one. */ +char *flexran_get_dl_scheduler_name(mid_t mod_id); +int flexran_set_dl_scheduler(mid_t mod_id, char *sched); + +/* Get the name of/Set the UL scheduler algorithm. Same applies as for the DL + * case */ +char *flexran_get_ul_scheduler_name(mid_t mod_id); +int flexran_set_ul_scheduler(mid_t mod_id, char *sched); /************************** S1AP **************************/ /* Get the number of MMEs to be connected */ diff --git a/openair2/LAYER2/MAC/main.c b/openair2/LAYER2/MAC/main.c index 24038e60d5..af6d1a7ac3 100644 --- a/openair2/LAYER2/MAC/main.c +++ b/openair2/LAYER2/MAC/main.c @@ -100,6 +100,7 @@ void mac_top_init_eNB(void) mac[i]->if_inst = IF_Module_init(i); + mac[i]->pre_processor_dl.algorithm = 0; mac[i]->pre_processor_dl.dl = dlsch_scheduler_pre_processor; char *s = "round_robin_dl"; void *d = dlsym(NULL, s); @@ -107,6 +108,7 @@ void mac_top_init_eNB(void) mac[i]->pre_processor_dl.dl_algo = *(default_sched_dl_algo_t *) d; mac[i]->pre_processor_dl.dl_algo.data = mac[i]->pre_processor_dl.dl_algo.setup(); + mac[i]->pre_processor_ul.algorithm = 0; mac[i]->pre_processor_ul.ul = ulsch_scheduler_pre_processor; s = "round_robin_ul"; d = dlsym(NULL, s); diff --git a/openair2/LAYER2/MAC/slicing/slicing.c b/openair2/LAYER2/MAC/slicing/slicing.c index a1de326df0..9c88f6cffb 100644 --- a/openair2/LAYER2/MAC/slicing/slicing.c +++ b/openair2/LAYER2/MAC/slicing/slicing.c @@ -258,13 +258,26 @@ int addmod_static_slice_ul(slice_info_t *si, return si->num - 1; } -int remove_static_slice(slice_info_t *si, uint8_t slice_idx) { +int remove_static_slice_dl(slice_info_t *si, uint8_t slice_idx) { if (slice_idx == 0) return 0; slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx); if (!sr) return 0; free(sr->algo_data); + sr->dl_algo.unset(&sr->dl_algo.data); + free(sr); + return 1; +} + +int remove_static_slice_ul(slice_info_t *si, uint8_t slice_idx) { + if (slice_idx == 0) + return 0; + slice_t *sr = _remove_slice(&si->num, si->s, si->UE_assoc_slice, slice_idx); + if (!sr) + return 0; + free(sr->algo_data); + sr->ul_algo.unset(&sr->ul_algo.data); free(sr); return 1; } @@ -528,6 +541,7 @@ pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) { dlp->posLow = 0; dlp->posHigh = to_rbg(RC.mac[mod_id]->common_channels[CC_id].mib->message.dl_Bandwidth) - 1; default_sched_dl_algo_t *algo = &RC.mac[mod_id]->pre_processor_dl.dl_algo; + algo->data = NULL; DevAssert(0 == addmod_static_slice_dl(si, 0, strdup("default"), algo, dlp)); const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) @@ -539,7 +553,7 @@ pp_impl_param_t static_dl_init(module_id_t mod_id, int CC_id) { sttc.remove_UE = slicing_remove_UE; sttc.move_UE = slicing_move_UE; sttc.addmod_slice = addmod_static_slice_dl; - sttc.remove_slice = remove_static_slice; + sttc.remove_slice = remove_static_slice_dl; sttc.dl = static_dl; // current DL algo becomes default scheduler sttc.dl_algo = *algo; @@ -564,6 +578,7 @@ pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) { ulp->posLow = 0; ulp->posHigh = to_prb(RC.mac[mod_id]->common_channels[CC_id].ul_Bandwidth) - 1; default_sched_ul_algo_t *algo = &RC.mac[mod_id]->pre_processor_ul.ul_algo; + algo->data = NULL; DevAssert(0 == addmod_static_slice_ul(si, 0, strdup("default"), algo, ulp)); const UE_list_t *UE_list = &RC.mac[mod_id]->UE_info.list; for (int UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) @@ -575,7 +590,7 @@ pp_impl_param_t static_ul_init(module_id_t mod_id, int CC_id) { sttc.remove_UE = slicing_remove_UE; sttc.move_UE = slicing_move_UE; sttc.addmod_slice = addmod_static_slice_ul; - sttc.remove_slice = remove_static_slice; + sttc.remove_slice = remove_static_slice_ul; sttc.ul = static_ul; // current DL algo becomes default scheduler sttc.ul_algo = *algo; From 07313fd96d2b598ca5deb7574b2b7124fe9a0019 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jun 2020 13:25:28 +0200 Subject: [PATCH 090/171] FlexRAN Bugfix: Free Ringbuffer on exit --- openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index e5d1c94c95..4c5f3e5609 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -1619,6 +1619,11 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) LOG_E(FLEXRAN_AGENT, "MAC agent CM for eNB %d is not registered\n", mod_id); return -1; } + + lfds700_ringbuffer_cleanup(&ringbuffer_state[mod_id], NULL ); + free(dl_mac_config_array[mod_id]); + lfds700_misc_library_cleanup(); + AGENT_MAC_xface *xface = agent_mac_xface[mod_id]; xface->flexran_agent_send_sr_info = NULL; xface->flexran_agent_send_sf_trigger = NULL; From 33b860f1b4a5eab264548281596cae53d03da414 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Tue, 23 Jun 2020 13:50:59 +0200 Subject: [PATCH 091/171] FlexRAN: use lock-free ringbuffers for slice conf Use LFDS 7.0.0 Ringbuffer implementation to handle * Slice Configuration * UE slice association which is then uploaded through MAC scheduling thread --- .../CONTROL_MODULES/MAC/flexran_agent_mac.c | 100 ++++++++++++++++-- 1 file changed, 92 insertions(+), 8 deletions(-) diff --git a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c index 4c5f3e5609..f1daacbb65 100644 --- a/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c +++ b/openair2/ENB_APP/CONTROL_MODULES/MAC/flexran_agent_mac.c @@ -49,6 +49,14 @@ struct lfds700_misc_prng_state ps[NUM_MAX_ENB]; struct lfds700_ringbuffer_element *dl_mac_config_array[NUM_MAX_ENB]; struct lfds700_ringbuffer_state ringbuffer_state[NUM_MAX_ENB]; +/* Ringbuffer-related to slice configuration */ +struct lfds700_ringbuffer_element *slice_config_array[NUM_MAX_ENB]; +struct lfds700_ringbuffer_state slice_config_ringbuffer_state[NUM_MAX_ENB]; + +/* Ringbuffer-related to slice configuration */ +struct lfds700_ringbuffer_element *ue_assoc_array[NUM_MAX_ENB]; +struct lfds700_ringbuffer_state ue_assoc_ringbuffer_state[NUM_MAX_ENB]; + int flexran_agent_mac_stats_reply_ue(mid_t mod_id, Protocol__FlexUeStatsReport **ue_report, int n_ue, @@ -1341,6 +1349,33 @@ void flexran_agent_init_mac_agent(mid_t mod_id) { AssertFatal(i == 0, "posix_memalign(): could not allocate aligned memory for lfds library\n"); lfds700_ringbuffer_init_valid_on_current_logical_core(&ringbuffer_state[mod_id], dl_mac_config_array[mod_id], num_elements, &ps[mod_id], NULL); + + struct lfds700_misc_prng_state scrng; + i = posix_memalign((void **) &slice_config_array[mod_id], + LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, + sizeof(struct lfds700_ringbuffer_element) * num_elements); + AssertFatal(i == 0, + "posix_memalign(): could not allocate aligned memory\n"); + lfds700_ringbuffer_init_valid_on_current_logical_core( + &slice_config_ringbuffer_state[mod_id], + slice_config_array[mod_id], + num_elements, + &scrng, + NULL); + + struct lfds700_misc_prng_state uarng; + i = posix_memalign((void **) &ue_assoc_array[mod_id], + LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES, + sizeof(struct lfds700_ringbuffer_element) * num_elements); + AssertFatal(i == 0, + "posix_memalign(): could not allocate aligned memory\n"); + lfds700_ringbuffer_init_valid_on_current_logical_core( + &ue_assoc_ringbuffer_state[mod_id], + ue_assoc_array[mod_id], + num_elements, + &uarng, + NULL); + for (i = 0; i < MAX_MOBILES_PER_ENB; i++) { for (j = 0; j < 8; j++) { if (RC.mac && RC.mac[mod_id]) @@ -1622,6 +1657,10 @@ int flexran_agent_unregister_mac_xface(mid_t mod_id) lfds700_ringbuffer_cleanup(&ringbuffer_state[mod_id], NULL ); free(dl_mac_config_array[mod_id]); + lfds700_ringbuffer_cleanup(&slice_config_ringbuffer_state[mod_id], NULL ); + free(slice_config_array[mod_id]); + lfds700_ringbuffer_cleanup(&ue_assoc_ringbuffer_state[mod_id], NULL ); + free(ue_assoc_array[mod_id]); lfds700_misc_library_cleanup(); AGENT_MAC_xface *xface = agent_mac_xface[mod_id]; @@ -1661,23 +1700,68 @@ void helper_destroy_mac_slice_config(Protocol__FlexSliceConfig *slice_config) { void prepare_update_slice_config(mid_t mod_id, Protocol__FlexSliceConfig **slice_config) { if (!*slice_config) return; + /* just use the memory and set to NULL in original */ Protocol__FlexSliceConfig *sc = *slice_config; *slice_config = NULL; - /* TODO handle using lock-free queue */ - apply_update_dl_slice_config(mod_id, sc->dl); - apply_update_ul_slice_config(mod_id, sc->ul); + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + enum lfds700_misc_flag overwrite_occurred_flag; - helper_destroy_mac_slice_config(*slice_config); + Protocol__FlexSliceConfig *overwritten_sc; + lfds700_ringbuffer_write(&slice_config_ringbuffer_state[mod_id], + NULL, + (void *)sc, + &overwrite_occurred_flag, + NULL, + (void **)&overwritten_sc, + &ls); + + if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) { + helper_destroy_mac_slice_config(overwritten_sc); + LOG_E(FLEXRAN_AGENT, "lost slice config: too many reconfigurations at once\n"); + } } void prepare_ue_slice_assoc_update(mid_t mod_id, Protocol__FlexUeConfig **ue_config) { - /* TODO handle using lock-free queue */ - apply_ue_slice_assoc_update(mod_id, *ue_config); + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + enum lfds700_misc_flag overwrite_occurred_flag; - free(*ue_config); - *ue_config = NULL; + Protocol__FlexUeConfig *overwritten_ue_config; + lfds700_ringbuffer_write(&ue_assoc_ringbuffer_state[mod_id], + NULL, + (void *) *ue_config, + &overwrite_occurred_flag, + NULL, + (void **)&overwritten_ue_config, + &ls); + + if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) { + free(overwritten_ue_config); + LOG_E(FLEXRAN_AGENT, "lost UE-slice association: too many UE-slice associations at once\n"); + } } void flexran_agent_slice_update(mid_t mod_id) { + struct lfds700_misc_prng_state ls; + LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE; + lfds700_misc_prng_init(&ls); + + Protocol__FlexSliceConfig *sc = NULL; + struct lfds700_ringbuffer_state *state = &slice_config_ringbuffer_state[mod_id]; + if (lfds700_ringbuffer_read(state, NULL, (void **) &sc, &ls) != 0) { + apply_update_dl_slice_config(mod_id, sc->dl); + apply_update_ul_slice_config(mod_id, sc->ul); + helper_destroy_mac_slice_config(sc); + } + + Protocol__FlexUeConfig *ue_config = NULL; + state = &ue_assoc_ringbuffer_state[mod_id]; + if (lfds700_ringbuffer_read(state, NULL, (void **) &ue_config, &ls) != 0) { + apply_ue_slice_assoc_update(mod_id, ue_config); + free(ue_config); + } } From 6eb00a0895e2c6a9e9da94161c46cf8a060041ed Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Mon, 20 Jul 2020 09:33:35 +0200 Subject: [PATCH 092/171] Enable multi-module support in pdcp_fifo_flush_sdus() --- openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c index 6c23332687..6c6bd30070 100644 --- a/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c +++ b/openair2/LAYER2/PDCP_v10.1.0/pdcp_fifo.c @@ -114,7 +114,9 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { int ret=0; while ((sdu_p = pollNotifiedFIFO(&pdcp_sdu_list)) != NULL ) { pdcp_data_ind_header_t * pdcpHead=(pdcp_data_ind_header_t *)NotifiedFifoData(sdu_p); - AssertFatal(pdcpHead->inst==ctxt_pP->module_id, "To implement correctly multi module id\n"); + + /* Note: we ignore the instance ID in the context and use the one in the + * PDCP packet to pick the right socket below */ int rb_id = pdcpHead->rb_id; int sizeToWrite= sizeof (pdcp_data_ind_header_t) + @@ -130,19 +132,19 @@ int pdcp_fifo_flush_sdus(const protocol_ctxt_t *const ctxt_pP) { sizeof(sidelink_pc5s_element), 0, (struct sockaddr *)&prose_pdcp_addr,sizeof(prose_pdcp_addr) ); } else if (UE_NAS_USE_TUN) { - //ret = write(nas_sock_fd[ctxt_pP->module_id], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); + //ret = write(nas_sock_fd[pdcpHead->inst], &(sdu_p->data[sizeof(pdcp_data_ind_header_t)]),sizeToWrite ); if(rb_id == mbms_rab_id){ ret = write(nas_sock_mbms_fd, pdcpData,sizeToWrite ); LOG_I(PDCP,"[PDCP_FIFOS] ret %d TRIED TO PUSH MBMS DATA TO rb_id %d handle %d sizeToWrite %d\n", - ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); + ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite); } else { if( LOG_DEBUGFLAG(DEBUG_PDCP) ) log_dump(PDCP, pdcpData, sizeToWrite, LOG_DUMP_CHAR,"PDCP output to be sent to TUN interface: \n"); - ret = write(nas_sock_fd[ctxt_pP->module_id], pdcpData,sizeToWrite ); + ret = write(nas_sock_fd[pdcpHead->inst], pdcpData,sizeToWrite ); LOG_T(PDCP,"[UE PDCP_FIFOS] ret %d TRIED TO PUSH DATA TO rb_id %d handle %d sizeToWrite %d\n", - ret,rb_id,nas_sock_fd[ctxt_pP->module_id],sizeToWrite); + ret,rb_id,nas_sock_fd[pdcpHead->inst],sizeToWrite); } } else if (ENB_NAS_USE_TUN) { if( LOG_DEBUGFLAG(DEBUG_PDCP) ) From 331c74af2af9e0449441d716e24cec590accca39 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Mon, 20 Jul 2020 14:21:11 +0200 Subject: [PATCH 093/171] fixing execution issues following recent changes --- ci-scripts/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7bfe331fc2..65a0b0d836 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1911,7 +1911,7 @@ class OaiCiTest(): # Kill iperf server on EPC side if launchFromEpc: - SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password + SSH.open(EPC.IPAddress, EPC.UserName, EPC.Password) SSH.command('killall --signal SIGKILL iperf', EPC.UserName, 5) SSH.close() else: @@ -3524,7 +3524,7 @@ elif re.match('^InitiateHtml$', mode, re.IGNORECASE): sys.exit('Insufficient Parameter') count = 0 foundCount = 0 - while (count < HTML.GetnbTestXMLfiles()): + while (count < HTML.nbTestXMLfiles): #xml_test_file = cwd + "/" + CiTestObj.testXMLfiles[count] xml_test_file = sys.path[0] + "/" + CiTestObj.testXMLfiles[count] if (os.path.isfile(xml_test_file)): From 0f0ede038d0148bd7f1aa35d6b49834feb21f965 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 20 Jul 2020 16:25:04 +0200 Subject: [PATCH 094/171] removing a printf in pusch scheduling --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 11a2f8d2a5..3a003ab1c6 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -918,8 +918,8 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, pusch_pdu->pusch_identity = *scc->physCellId; } pusch_dmrs_AdditionalPosition_t additional_pos; - if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL){printf("%d\n",2); - additional_pos = 2;} + if (NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NULL) + additional_pos = 2; else { if (*NR_DMRS_UplinkConfig->dmrs_AdditionalPosition == NR_DMRS_UplinkConfig__dmrs_AdditionalPosition_pos3) additional_pos = 3; From 87dccea43fdfd0a7871e6a8db1f7cc2135219119 Mon Sep 17 00:00:00 2001 From: hardy Date: Mon, 20 Jul 2020 16:44:51 +0200 Subject: [PATCH 095/171] integrating cots ue control into CI --- ci-scripts/cls_cots_ue.py | 89 +++++++++++++++++++++ ci-scripts/main.py | 7 ++ ci-scripts/xml_files/fr1_toggle_cots_ue.xml | 39 +++++++++ 3 files changed, 135 insertions(+) create mode 100644 ci-scripts/cls_cots_ue.py create mode 100644 ci-scripts/xml_files/fr1_toggle_cots_ue.xml diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py new file mode 100644 index 0000000000..821d39fb6f --- /dev/null +++ b/ci-scripts/cls_cots_ue.py @@ -0,0 +1,89 @@ +# * 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 +# */ +#--------------------------------------------------------------------- +# Python for CI of OAI-eNB + COTS-UE +# +# Required Python Version +# Python 3.x +# +# Required Python Package +# pexpect +#--------------------------------------------------------------------- + +#to use logging.info() +import logging +#to create a SSH object locally in the methods +import sshconnection + + +class CotsUe: + def __init__(self,model,UEIPAddr,UEUserName,UEPassWord): + self.model = model + self.UEIPAddr = UEIPAddr + self.UEUserName = UEUserName + self.UEPassWord = UEPassWord + self.runargs = '' #on of off to toggle airplane mode on/off + self.__SetAirplaneRetry = 3 + +#-----------------$ +#PUBLIC Methods$ +#-----------------$ + + def Check_Airplane(self): + mySSH = sshconnection.SSHConnection() + mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord) + + mySSH.command('cd /home/oaici/remi/android-sdk-linux/platform-tools', '\$', 5) + status=mySSH.cde_check_value('sudo ./adb shell settings get global airplane_mode_on ', ['0','1'],5) + mySSH.close() + return status + + + def Set_Airplane(self,target_state_str): + print("toggling state to : "+target_state_str) + current_state = self.Check_Airplane() + if target_state_str.lower()=="on": + target_state=1 + else: + target_state=0 + if current_state != target_state: + #toggle state + mySSH = sshconnection.SSHConnection() + mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord) + retry = 0 + while (current_state!=target_state) and (retry < self.__SetAirplaneRetry): + mySSH.command('cd /home/oaici/remi/android-sdk-linux/platform-tools', '\$', 5) + mySSH.command('sudo ./adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5) + mySSH.command('sudo ./adb shell input keyevent 20', '\$', 5) + mySSH.command('sudo ./adb shell input tap 968 324', '\$', 5) + time.sleep(1) + current_state = self.Check_Airplane() + retry+=1 + if current_state != target_state: + print("ATTENTION : Could not toggle to : "+target_state_str) + print("Current state is : "+ str(current_state)) + mySSH.close() + else: + print("Airplane mode is already "+ target_state_str) + + + + + diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 65a0b0d836..d1103be3f2 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3236,6 +3236,10 @@ def GetParametersFromXML(action): if action == 'Run_PhySim': ldpc.runargs = test.findtext('physim_run_args') + + if action == 'COTS_UE_Airplane': + COTS_UE=CotsUe('oppo', self.UEIPAddress, self.UEUserName,UEPassword) + COTS_UE.runargs = test.findtext('cots_ue_airplane_args') #check if given test is in list #it is in list if one of the strings in 'list' is at the beginning of 'test' @@ -3274,6 +3278,9 @@ RAN.EpcObj=EPC import cls_physim #class PhySim for physical simulators build and test ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build +import cls_cots_ue #class CotsUe + + argvs = sys.argv argc = len(argvs) cwd = os.getcwd() diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml new file mode 100644 index 0000000000..8271d333e2 --- /dev/null +++ b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml @@ -0,0 +1,39 @@ + + + test-toggle-airplane-mode + Airplane + tasks + + 010101 + + + + + COTS_UE_Airplane + toggle on + ON + + + + From dfe6278ee175e650cca7cbb676219681ebc5370c Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Mon, 20 Jul 2020 18:06:02 +0200 Subject: [PATCH 096/171] fixing issues for CI integration --- ci-scripts/cls_cots_ue.py | 19 ++++++++++--------- ci-scripts/main.py | 13 ++++++++++--- ci-scripts/xml_files/fr1_toggle_cots_ue.xml | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py index 821d39fb6f..3e4c8179a8 100644 --- a/ci-scripts/cls_cots_ue.py +++ b/ci-scripts/cls_cots_ue.py @@ -31,7 +31,8 @@ import logging #to create a SSH object locally in the methods import sshconnection - +#time.sleep +import time class CotsUe: def __init__(self,model,UEIPAddr,UEUserName,UEPassWord): @@ -47,9 +48,8 @@ class CotsUe: #-----------------$ def Check_Airplane(self): - mySSH = sshconnection.SSHConnection() + mySSH = sshconnection.SSHConnection() mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord) - mySSH.command('cd /home/oaici/remi/android-sdk-linux/platform-tools', '\$', 5) status=mySSH.cde_check_value('sudo ./adb shell settings get global airplane_mode_on ', ['0','1'],5) mySSH.close() @@ -57,7 +57,11 @@ class CotsUe: def Set_Airplane(self,target_state_str): - print("toggling state to : "+target_state_str) + mySSH = sshconnection.SSHConnection() + mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord) + mySSH.command('cd /home/oaici/remi/android-sdk-linux/platform-tools', '\$', 5) + mySSH.command('sudo ./adb start-server','$',5) + logging.info("Toggling COTS UE Airplane mode to : "+target_state_str) current_state = self.Check_Airplane() if target_state_str.lower()=="on": target_state=1 @@ -65,11 +69,8 @@ class CotsUe: target_state=0 if current_state != target_state: #toggle state - mySSH = sshconnection.SSHConnection() - mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord) retry = 0 while (current_state!=target_state) and (retry < self.__SetAirplaneRetry): - mySSH.command('cd /home/oaici/remi/android-sdk-linux/platform-tools', '\$', 5) mySSH.command('sudo ./adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5) mySSH.command('sudo ./adb shell input keyevent 20', '\$', 5) mySSH.command('sudo ./adb shell input tap 968 324', '\$', 5) @@ -79,10 +80,10 @@ class CotsUe: if current_state != target_state: print("ATTENTION : Could not toggle to : "+target_state_str) print("Current state is : "+ str(current_state)) - mySSH.close() else: print("Airplane mode is already "+ target_state_str) - + mySSH.command('sudo ./adb kill-server','$',5) + mySSH.close() diff --git a/ci-scripts/main.py b/ci-scripts/main.py index d1103be3f2..521cd3aa51 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -50,6 +50,7 @@ logging.basicConfig( format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s" ) +import cls_cots_ue #----------------------------------------------------------- # Class Declaration @@ -3063,7 +3064,7 @@ class OaiCiTest(): logging.debug('\u001B[1m----------------------------------------\u001B[0m') def CheckClassValidity(action,id): - if action!='Build_PhySim' and action!='Run_PhySim' and action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': + if action!='COTS_UE_Airplane' and action!='Build_PhySim' and action!='Run_PhySim' and action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) return False return True @@ -3238,7 +3239,6 @@ def GetParametersFromXML(action): ldpc.runargs = test.findtext('physim_run_args') if action == 'COTS_UE_Airplane': - COTS_UE=CotsUe('oppo', self.UEIPAddress, self.UEUserName,UEPassword) COTS_UE.runargs = test.findtext('cots_ue_airplane_args') #check if given test is in list @@ -3278,7 +3278,6 @@ RAN.EpcObj=EPC import cls_physim #class PhySim for physical simulators build and test ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build -import cls_cots_ue #class CotsUe argvs = sys.argv @@ -3450,6 +3449,12 @@ while len(argvs) > 1: HELP.GenericHelp(CONST.Version) sys.exit('Invalid Parameter: ' + myArgv) + +COTS_UE=cls_cots_ue.CotsUe('oppo', CiTestObj.UEIPAddress, CiTestObj.UEUserName,CiTestObj.UEPassword) + + + + if re.match('^TerminateeNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': HELP.GenericHelp(CONST.Version) @@ -3754,6 +3759,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re if ldpc.exitStatus==1:sys.exit() elif action == 'Run_PhySim': HTML=ldpc.Run_PhySim(HTML,CONST,id) + elif action == 'COTS_UE_Airplane': + COTS_UE.Set_Airplane(COTS_UE.runargs) else: sys.exit('Invalid action') CiTestObj.FailReportCnt += 1 diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml index 8271d333e2..371063c791 100644 --- a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml +++ b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml @@ -31,7 +31,7 @@ COTS_UE_Airplane - toggle on + Toggle COTS Airplane mode ON ON From d244ea4b994bd7cd7ec7877a3a2603949299fd89 Mon Sep 17 00:00:00 2001 From: hardy Date: Mon, 20 Jul 2020 22:45:24 +0200 Subject: [PATCH 097/171] slight reformatiing of main.py ; introducing yaml for xml class definition --- ci-scripts/main.py | 97 +++++++++++++++++++++++++---------- ci-scripts/xml_class_list.yml | 35 +++++++++++++ 2 files changed, 106 insertions(+), 26 deletions(-) create mode 100755 ci-scripts/xml_class_list.yml diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 521cd3aa51..21d1104546 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -28,15 +28,30 @@ # pexpect #--------------------------------------------------------------------- -import constants as CONST #----------------------------------------------------------- -# Import +# Import Components +#----------------------------------------------------------- + +import helpreadme as HELP +import constants as CONST + +import cls_physim #class PhySim for physical simulators build and test +import cls_cots_ue #class CotsUe for Airplane mode control + +import sshconnection +import epc +import ran +import html + + +#----------------------------------------------------------- +# Import Libs #----------------------------------------------------------- import sys # arg import re # reg -import pexpect # pexpect +import pexpect # pexpect import time # sleep import os import subprocess @@ -50,10 +65,10 @@ logging.basicConfig( format="[%(asctime)s] %(name)s:%(levelname)s: %(message)s" ) -import cls_cots_ue + #----------------------------------------------------------- -# Class Declaration +# OaiCiTest Class Definition #----------------------------------------------------------- class OaiCiTest(): @@ -3054,20 +3069,33 @@ class OaiCiTest(): HTML.CpuMHz[idx]=CpuMHz SSH.close() -#----------------------------------------------------------- -# ShowTestID() -#----------------------------------------------------------- def ShowTestID(self): logging.debug('\u001B[1m----------------------------------------\u001B[0m') logging.debug('\u001B[1mTest ID:' + self.testCase_id + '\u001B[0m') logging.debug('\u001B[1m' + self.desc + '\u001B[0m') logging.debug('\u001B[1m----------------------------------------\u001B[0m') + + +#----------------------------------------------------------- +# General Functions +#----------------------------------------------------------- + + + def CheckClassValidity(action,id): - if action!='COTS_UE_Airplane' and action!='Build_PhySim' and action!='Run_PhySim' and action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': - logging.debug('ERROR: test-case ' + id + ' has wrong class ' + action) - return False - return True +# if action !='COTS_UE_Airplane' and action!='Build_PhySim' and action!='Run_PhySim' and action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and +# action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and +# action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and +# action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and +# action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and +# action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': + if action not in xml_class_list: + logging.debug('ERROR: test-case ' + id + ' has unlisted class ' + action + ' ##CHECK xml_class_list.yml') + resp=False + else: + resp=True + return resp def GetParametersFromXML(action): if action == 'Build_eNB': @@ -3253,18 +3281,25 @@ def test_in_list(test, list): def receive_signal(signum, frame): sys.exit(1) -#----------------------------------------------------------- -# Parameter Check -#----------------------------------------------------------- -mode = '' -CiTestObj = OaiCiTest() -import sshconnection -import epc -import helpreadme as HELP -import ran -import html -import constants + + + + +#----------------------------------------------------------- +# MAIN PART +#----------------------------------------------------------- + +#loading xml action list from yaml +import yaml +with open('xml_class_list.yml','r') as file: + # The FullLoader parameter handles the conversion from YAML + # scalar values to Python the dictionary format + xml_class_list = yaml.load(file,Loader=yaml.FullLoader) + +mode = '' + +CiTestObj = OaiCiTest() SSH = sshconnection.SSHConnection() EPC = epc.EPCManagement() @@ -3275,11 +3310,15 @@ EPC.HtmlObj=HTML RAN.HtmlObj=HTML RAN.EpcObj=EPC -import cls_physim #class PhySim for physical simulators build and test + ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build +#----------------------------------------------------------- +# Parameter Check +#----------------------------------------------------------- + argvs = sys.argv argc = len(argvs) cwd = os.getcwd() @@ -3450,10 +3489,16 @@ while len(argvs) > 1: sys.exit('Invalid Parameter: ' + myArgv) +#----------------------------------------------------------- +# COTS UE instanciation +#----------------------------------------------------------- +#COTS_UE instanciation can only be done here for the moment, due to code architecture COTS_UE=cls_cots_ue.CotsUe('oppo', CiTestObj.UEIPAddress, CiTestObj.UEUserName,CiTestObj.UEPassword) - +#----------------------------------------------------------- +# XML class (action) analysis +#----------------------------------------------------------- if re.match('^TerminateeNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': @@ -3762,7 +3807,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re elif action == 'COTS_UE_Airplane': COTS_UE.Set_Airplane(COTS_UE.runargs) else: - sys.exit('Invalid action') + sys.exit('Invalid class (action) from xml') CiTestObj.FailReportCnt += 1 if CiTestObj.FailReportCnt == CiTestObj.repeatCounts[0] and RAN.prematureExit: logging.debug('Testsuite failed ' + str(CiTestObj.FailReportCnt) + ' time(s)') diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml new file mode 100755 index 0000000000..56890c1fc6 --- /dev/null +++ b/ci-scripts/xml_class_list.yml @@ -0,0 +1,35 @@ + - COTS_UE_Airplane + - Build_PhySim + - Run_PhySim + - Build_eNB + - WaitEndBuild_eNB + - Initialize_eNB + - Terminate_eNB + - Initialize_UE + - Terminate_UE + - Attach_UE + - Detach_UE + - Build_OAI_UE + - Initialize_OAI_UE + - Terminate_OAI_UE + - DataDisable_UE + - DataEnable_ + - CheckStatusUE + - Ping + - Iperf + - Reboot_UE + - Initialize_FlexranCtrl + - Terminate_FlexranCtrl + - Initialize_HSS + - Terminate_HSS + - Initialize_MME + - Terminate_MME + - Initialize_SPGW + - Terminate_SPGW + - Initialize_CatM_module + - Terminate_CatM_module + - Attach_CatM_module + - Detach_CatM_module + - Ping_CatM_module + - IdleSleep + - Perform_X2_Handover From 3d365b0d8ef46905b8fedf05a1485f3b65bf54f9 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Tue, 21 Jul 2020 17:04:23 +0200 Subject: [PATCH 098/171] WIP fr1 set up --- ci-scripts/cls_cots_ue.py | 4 ++-- ci-scripts/ran.py | 3 ++- ci-scripts/xml_files/fr1_multi_node_build.xml | 20 ++++++++----------- ci-scripts/xml_files/fr1_toggle_cots_ue.xml | 4 ++-- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py index 3e4c8179a8..23feba982b 100644 --- a/ci-scripts/cls_cots_ue.py +++ b/ci-scripts/cls_cots_ue.py @@ -78,8 +78,8 @@ class CotsUe: current_state = self.Check_Airplane() retry+=1 if current_state != target_state: - print("ATTENTION : Could not toggle to : "+target_state_str) - print("Current state is : "+ str(current_state)) + logging.error("ATTENTION : Could not toggle to : "+target_state_str) + logging.error("Current state is : "+ str(current_state)) else: print("Airplane mode is already "+ target_state_str) mySSH.command('sudo ./adb kill-server','$',5) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 5673b4c082..6ebecec843 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -431,7 +431,8 @@ class RANManagement(): os.remove('./tmp_build' + testcaseId + '.zip') mySSH.open(self.eNBIPAddress, self.eNBUserName, self.eNBPassword) mySSH.command('cd ' + self.eNBSourceCodePath + '/cmake_targets', '\$', 5) - mySSH.command('unzip -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5) + #-qq quiet / -u update orcreate files + mySSH.command('unzip -u -qq -DD tmp_build' + testcaseId + '.zip', '\$', 5) mySSH.command('rm -f tmp_build' + testcaseId + '.zip', '\$', 5) mySSH.close() else: diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml index b2c0daa74e..579eef27a8 100644 --- a/ci-scripts/xml_files/fr1_multi_node_build.xml +++ b/ci-scripts/xml_files/fr1_multi_node_build.xml @@ -25,41 +25,37 @@ Build wrench - 010101 010102 - 000101 000102 + 000001 000002 + 000003 000004 - + Build_eNB Build eNB - -w USRP -c --eNB --ninja + -w USRP -c --eNB 0 0 - True - + WaitEndBuild_eNB Wait for end of Build eNB - -w USRP -c --eNB --ninja 0 0 - + Build_eNB Build gNB - -w USRP -c --gNB --ninja + -w USRP -c --gNB 1 1 - True - + WaitEndBuild_eNB Wait for end of Build gNB - -w USRP -c --gNB --ninja 1 1 diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml index 371063c791..ee4d36f00a 100644 --- a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml +++ b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml @@ -25,11 +25,11 @@ Airplane tasks - 010101 + 010000 - + COTS_UE_Airplane Toggle COTS Airplane mode ON ON From 4b48e457ba86b951c98fb10b5e61960f233cf686 Mon Sep 17 00:00:00 2001 From: hardy Date: Tue, 21 Jul 2020 23:55:20 +0200 Subject: [PATCH 099/171] WIP : yaml config files for multiple eNB or gNB nodes --- ci-scripts/main.py | 39 ++++++++++++++++++++++++++-- ci-scripts/py_params.yaml | 54 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 ci-scripts/py_params.yaml diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 21d1104546..2865f5984b 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3083,7 +3083,7 @@ class OaiCiTest(): -def CheckClassValidity(action,id): +def CheckClassValidity(xml_class_list,action,id): # if action !='COTS_UE_Airplane' and action!='Build_PhySim' and action!='Run_PhySim' and action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and # action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and # action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and @@ -3097,6 +3097,20 @@ def CheckClassValidity(action,id): resp=True return resp + +#assigning parameters to object instance attributes (even if the attributes do not exist !!) +def AssignParams(params_dict): + #-- + mode=params_dict['mode'] + #-- + for key,value in params_dict.items(): + setattr(CITestObj, key, value) + setattr(RAN, key, value) + setattr(HTML, key, value) + setattr(ldpc, key, value) + + + def GetParametersFromXML(action): if action == 'Build_eNB': RAN.Build_eNB_args=test.findtext('Build_eNB_args') @@ -3326,9 +3340,23 @@ cwd = os.getcwd() while len(argvs) > 1: myArgv = argvs.pop(1) # 0th is this file's name + #--help if re.match('^\-\-help$', myArgv, re.IGNORECASE): HELP.GenericHelp(CONST.Version) sys.exit(0) + + #--apply= as parameters file, to replace inline parameters + elif re.match('^\-\-apply=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-apply=(.+)$', myArgv, re.IGNORECASE) + py_params_file = matchReg.group(1) + with open(py_params_file,'r') as file: + # The FullLoader parameter handles the conversion from YAML + # scalar values to Python dictionary format + py_params = yaml.load(file,Loader=yaml.FullLoader) + py_param_file_present = True #to be removed once validated + #AssignParams(py_params) #to be uncommented once validated + + #consider inline parameters elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) mode = matchReg.group(1) @@ -3489,6 +3517,13 @@ while len(argvs) > 1: sys.exit('Invalid Parameter: ' + myArgv) +#----------------------------------------------------------- +# TEMPORARY params management +#----------------------------------------------------------- +#temporary solution for testing: +if py_param_file_present == True: + AssignParams(py_params) + #----------------------------------------------------------- # COTS UE instanciation #----------------------------------------------------------- @@ -3723,7 +3758,7 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re CiTestObj.desc = test.findtext('desc') HTML.desc=CiTestObj.desc action = test.findtext('class') - if (CheckClassValidity(action, id) == False): + if (CheckClassValidity(xml_class_list, action, id) == False): continue CiTestObj.ShowTestID() GetParametersFromXML(action) diff --git a/ci-scripts/py_params.yaml b/ci-scripts/py_params.yaml new file mode 100644 index 0000000000..68471763f7 --- /dev/null +++ b/ci-scripts/py_params.yaml @@ -0,0 +1,54 @@ +mode : a +eNBRepository : b +ranRepository : c +eNB_AllowMerge : +ranAllowMerge : +eNBBranch : f +ranBranch : g +eNBCommitID : +ranCommitID : i +eNBTargetBranch : j +ranTargetBranch : k + +nodes : + - type : eNB + IPAddress : 001.1.1 + UserName : toto + Password : qwe + SourceCodePath : l + - type : gNB + IPAddress : 002.2.2 + UserName : tata + Password : asd + SourceCodePath : m + - type : eNB + IPAddress : 003.3.3 + UserName : titi + Password : zxc + SourceCodePath : n + - type : gNB + IPAddress : 004.4.4 + UserName : caca + Password : pepe + SourceCodePath : o + +EPCIPAddress : p +EPCUserName : q +EPCPassword : r +EPCSourceCodePath : s +EPCType : t +EPCContainerPrefix : u + +ADBIPAddress : v +ADBUserName : w +ADBType : x +ADBPassword : y + +XMLTestFile : z + +UEIPAddress : qqq +UEUserName : www +UEPassword : eee +UESourceCodePath : yyy + +finalStatus : bbb \ No newline at end of file From 5331189c8b78568a035f91f3000ab37cad5d4c57 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 22 Jul 2020 15:07:04 +0200 Subject: [PATCH 100/171] bugfixes --- openair1/SCHED_NR/fapi_nr_l1.c | 1 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index ddebcc3e06..2870f1d42e 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -160,6 +160,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ gNB->dlsch[i][0]->harq_mask=0; } gNB->pdcch_pdu = NULL; + gNB->ul_dci_pdu = NULL; gNB->pbch_configured=0; for (int i=0;irv = pusch_pdu->pusch_data.rv_index; dci_pdu_rel15->harq_pid = pusch_pdu->pusch_data.harq_process_id; dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; - //dci_pdu_rel15->dai[0].val = ???; //TODO + dci_pdu_rel15->dai[0].val = 0; //TODO // bwp indicator if (n_ubwp < 4) dci_pdu_rel15->bwp_indicator.val = bwp_id; From 39b22f17b330332621a0572c7e2717c94cd821ab Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 22 Jul 2020 15:11:17 +0200 Subject: [PATCH 101/171] calloc for dci_pdu --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 1 - openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index 10d4e9ab3c..f40d822b6b 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -2010,7 +2010,6 @@ uint16_t nr_dci_size(NR_ServingCellConfigCommon_t *scc, } // Precoding info and number of layers long transformPrecoder; - dci_pdu->precoding_information.nbits = 0; if (pusch_Config->transformPrecoder == NULL){ // if transform precoder is null, apply the values from msg3 if(scc->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->msg3_transformPrecoder == NULL) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index c1565bd408..89de2da0e5 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -1052,9 +1052,10 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, return; } else { - dci_pdu_rel15_t dci_pdu_rel15[MAX_DCI_CORESET]; - config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,n_ubwp,bwp_id); - fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id); + dci_pdu_rel15_t *dci_pdu_rel15 = calloc(MAX_DCI_CORESET,sizeof(dci_pdu_rel15_t)); + config_uldci(ubwp,pusch_pdu,pdcch_pdu_rel15,&dci_pdu_rel15[0],dci_formats,rnti_types,time_domain_assignment,n_ubwp,bwp_id); + fill_dci_pdu_rel15(scc,secondaryCellGroup,pdcch_pdu_rel15,dci_pdu_rel15,dci_formats,rnti_types,pusch_pdu->bwp_size,bwp_id); + free(dci_pdu_rel15); } } From 390c648a81ee2b209b73dbdb5b5dce7a7d51a4e4 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 22 Jul 2020 09:13:04 +0200 Subject: [PATCH 102/171] bugfix in time domain assigment --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 5 +++-- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 89de2da0e5..8841083796 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -474,6 +474,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types, + int time_domain_assignment, int n_ubwp, int bwp_id) { switch(dci_formats[(pdcch_pdu_rel15->numDlDci)-1]) { @@ -482,7 +483,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp, pusch_pdu->rb_start, NRRIV2BW(ubwp->bwp_Common->genericParameters.locationAndBandwidth,275)); - dci_pdu_rel15->time_domain_assignment.val = 2; // row index used here instead of SLIV; + dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; dci_pdu_rel15->frequency_hopping_flag.val = pusch_pdu->frequency_hopping; dci_pdu_rel15->mcs = 9; @@ -511,7 +512,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp, else AssertFatal(1==0,"Only frequency resource allocation type 1 is currently supported\n"); // time domain assignment - dci_pdu_rel15->time_domain_assignment.val = 2; + dci_pdu_rel15->time_domain_assignment.val = time_domain_assignment; // mcs dci_pdu_rel15->mcs = pusch_pdu->mcs_index; // tpc command for pusch diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 8b38c357c6..74c6841a3a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -137,6 +137,7 @@ void config_uldci(NR_BWP_Uplink_t *ubwp, nfapi_nr_dl_tti_pdcch_pdu_rel15_t *pdcch_pdu_rel15, dci_pdu_rel15_t *dci_pdu_rel15, int *dci_formats, int *rnti_types, + int time_domain_assignment, int n_ubwp, int bwp_id); void configure_fapi_dl_Tx(module_id_t Mod_idP, From 220445f15798ee7daec0970d930fcb23af3a5dc4 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Wed, 22 Jul 2020 17:53:28 +0200 Subject: [PATCH 103/171] wip : fr1 set up automation / fixing issues from recent changes --- ci-scripts/main.py | 10 +++++----- ci-scripts/ran.py | 11 ++++++----- ci-scripts/xml_files/fr1_multi_node_build.xml | 1 + ci-scripts/xml_files/fr1_toggle_cots_ue.xml | 4 ++-- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 2865f5984b..82a1da0390 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3320,9 +3320,9 @@ EPC = epc.EPCManagement() RAN = ran.RANManagement() HTML = html.HTMLManagement() -EPC.HtmlObj=HTML -RAN.HtmlObj=HTML -RAN.EpcObj=EPC +EPC.htmlObj=HTML +RAN.htmlObj=HTML +RAN.epcObj=EPC ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU build @@ -3336,7 +3336,7 @@ ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU b argvs = sys.argv argc = len(argvs) cwd = os.getcwd() - +py_param_file_present = False while len(argvs) > 1: myArgv = argvs.pop(1) # 0th is this file's name @@ -3352,7 +3352,7 @@ while len(argvs) > 1: with open(py_params_file,'r') as file: # The FullLoader parameter handles the conversion from YAML # scalar values to Python dictionary format - py_params = yaml.load(file,Loader=yaml.FullLoader) + py_params = yaml.load(file,Loader=yaml.FullLoader) py_param_file_present = True #to be removed once validated #AssignParams(py_params) #to be uncommented once validated diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 6ebecec843..23a004e4ce 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -274,7 +274,7 @@ class RANManagement(): if self.Build_eNB_forced_workspace_cleanup: mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf ' + lSourcePath, '\$', 15) if self.htmlObj is not None: - self.testCase_id = self.htmlObj.GettestCase_id() + self.testCase_id = self.htmlObj.testCase_id else: self.testCase_id = '000000' # on RedHat/CentOS .git extension is mandatory @@ -388,7 +388,7 @@ class RANManagement(): def checkBuildeNB(self, lIpAddr, lUserName, lPassWord, lSourcePath, testcaseId): if self.htmlObj is not None: - self.htmlObj.SettestCase_id(testcaseId) + self.htmlObj.testCase_id=testcaseId mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) @@ -397,6 +397,7 @@ class RANManagement(): mySSH.command('ls ran_build/build', '\$', 3) #check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem, ocp-enb) + logging.info('CHECK Build with IP='+lIpAddr+' SourcePath='+lSourcePath) result = re.search(self.air_interface, mySSH.getBefore()) if result is None: buildStatus = False #if not, build failed @@ -471,7 +472,7 @@ class RANManagement(): sys.exit('Insufficient Parameter') if self.htmlObj is not None: - self.testCase_id = self.htmlObj.GettestCase_id() + self.testCase_id = self.htmlObj.testCase_id else: self.testCase_id = '000000' mySSH = SSH.SSHConnection() @@ -762,7 +763,7 @@ class RANManagement(): if (copyin_res == -1): logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m') if self.htmlObj is not None: - self.htmlObj.SetHmleNBFailureMsg('Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!') + self.htmlObj.HmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' self.htmlObj.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) self.eNBmbmsEnables[int(self.eNB_instance)] = False return @@ -1065,5 +1066,5 @@ class RANManagement(): htmleNBFailureMsg += rlcMsg + '\n' global_status = CONST.ENB_PROCESS_REALTIME_ISSUE if self.htmlObj is not None: - self.htmlObj.SetHmleNBFailureMsg(htmleNBFailureMsg) + self.htmlObj.HmleNBFailureMsg=htmleNBFailureMsg return global_status diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml index 579eef27a8..0b7dce29d8 100644 --- a/ci-scripts/xml_files/fr1_multi_node_build.xml +++ b/ci-scripts/xml_files/fr1_multi_node_build.xml @@ -60,4 +60,5 @@ 1 + diff --git a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml index ee4d36f00a..b2267efc77 100644 --- a/ci-scripts/xml_files/fr1_toggle_cots_ue.xml +++ b/ci-scripts/xml_files/fr1_toggle_cots_ue.xml @@ -21,8 +21,8 @@ --> - test-toggle-airplane-mode - Airplane + test-airplane-mode + AirplaneToggle tasks 010000 From 3d8e5e11ef14508fc767ae0fb7bb1c63dec1153e Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Wed, 22 Jul 2020 17:56:51 +0200 Subject: [PATCH 104/171] fixes for buffer overrun when L1 information is cleared upon UE removal in RRC. This is a temporary fix to solve a stability issue for Benetel pending more significant changes along the same lines in several places. --- openair2/RRC/LTE/rrc_eNB.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 1d44751dca..35a45714c4 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -994,11 +994,14 @@ void put_UE_in_freelist(module_id_t mod_id, rnti_t rnti, boolean_t removeFlag) { pthread_mutex_unlock(&lock_ue_freelist); } +extern int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); +extern int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); +extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); +extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + void release_UE_in_freeList(module_id_t mod_id) { int i, j, CC_id, pdu_number; protocol_ctxt_t ctxt; - LTE_eNB_ULSCH_t *ulsch = NULL; - LTE_eNB_DLSCH_t *dlsch = NULL; nfapi_ul_config_request_body_t *ul_req_tmp = NULL; PHY_VARS_eNB *eNB_PHY = NULL; struct rrc_eNB_ue_context_s *ue_context_pP = NULL; @@ -1032,6 +1035,25 @@ void release_UE_in_freeList(module_id_t mod_id) { for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) { eNB_PHY = RC.eNB[mod_id][CC_id]; + int id; + + // clean ULSCH entries for rnti + id = find_ulsch(rnti,eNB_PHY,SEARCH_EXIST); + if (id>0) clean_eNb_ulsch(eNB_PHY->ulsch[id]); + + // clean DLSCH entries for rnti + id = find_dlsch(rnti,eNB_PHY,SEARCH_EXIST); + if (id>0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]); + + // clean UCI entries for rnti + for (i=0; iuci_vars[i].rnti == rnti) { + LOG_I(MAC, "clean eNb uci_vars[%d] UE %x \n",i, rnti); + memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); + } + } + + /* for (i=0; iulsch[i]; @@ -1064,6 +1086,7 @@ void release_UE_in_freeList(module_id_t mod_id) { memset(&eNB_PHY->uci_vars[i],0,sizeof(LTE_eNB_UCI)); } } + */ if (flexran_agent_get_rrc_xface(mod_id)) { flexran_agent_get_rrc_xface(mod_id)->flexran_agent_notify_ue_state_change( From ea86120c4be2fa400c87d3495d97d8322d9a711c Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 16 Jul 2020 23:39:59 +0200 Subject: [PATCH 105/171] Restructured UE DCI configuration function: - moved RRC structs checks and mac configuration to config_ue.c - new implementation of DCI configuration according to 3GPP TS 38.331 version 15.9.0 Release 15 and 3GPP TS 38.213 version 15.9.0 Release 15 --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 80 +++- .../NR_MAC_UE/nr_ue_dci_configuration.c | 446 ++++++++++-------- 2 files changed, 321 insertions(+), 205 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 9330cfc5ef..31107aea62 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -325,6 +325,77 @@ void config_common_ue(NR_UE_MAC_INST_t *mac, } +/** \brief This function is relavant for the UE procedures for control. It loads the search spaces, the BWPs and the CORESETs into the MAC instance and + \brief performs assert checks on the relevant RRC configuration. + @param NR_UE_MAC_INST_t mac: pointer to local MAC instance + @returns void + */ +void config_control_ue(NR_UE_MAC_INST_t *mac){ + + uint8_t bwp_id = 1, coreset_id = 1, ss_id; + NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; + NR_BWP_DownlinkCommon_t *bwp_Common = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Common; + NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Dedicated; + NR_SetupRelease_PDCCH_Config_t *pdcch_Config = dl_bwp_Dedicated->pdcch_Config; + NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList; + struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList; + struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList; + NR_SearchSpace_t *NR_SearchSpace; + + // check pdcch_Config, pdcch_ConfigCommon and DL BWP + AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n"); + AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count); + mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]; + AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n"); + AssertFatal(bwp_Common != NULL, "bwp_Common is null\n"); + AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n"); + AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n"); + AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n"); + AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n"); + AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count); + mac->coreset[bwp_id - 1][coreset_id - 1] = controlResourceSetToAddModList->list.array[0]; + AssertFatal(controlResourceSetToAddModList->list.array[0] != NULL, "coreset[0][0] is null\n"); + + // Check dedicated UL BWP and pass to MAC + AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n"); + AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count); + mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[0]; + AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n"); + + // check available Search Spaces in the searchSpacesToAddModList and pass to MAC + // note: the network configures at most 10 Search Spaces per BWP per cell (including UE-specific and common Search Spaces). + AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n"); + AssertFatal(searchSpacesToAddModList->list.count > 0, "list of UE specifically configured Search Spaces is empty\n"); + AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count); + for (ss_id = 0; ss_id < searchSpacesToAddModList->list.count; ss_id++) { + NR_SearchSpace_t *ss = searchSpacesToAddModList->list.array[ss_id]; + AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); + AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n"); + AssertFatal(*ss->controlResourceSetId == mac->coreset[bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); + AssertFatal(ss->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n"); + AssertFatal(ss->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n"); + mac->SSpace[0][0][ss_id] = ss; + } + + // Check available CSSs in the commonSearchSpaceList (list of additional common search spaces) + // note: commonSearchSpaceList SIZE(1..4) + AssertFatal(commonSearchSpaceList != NULL, "commonSearchSpaceList is null\n"); + AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n"); + for (int css_id = 0; css_id < commonSearchSpaceList->list.count; css_id++) { + NR_SearchSpace_t *css = commonSearchSpaceList->list.array[css_id]; + AssertFatal(css->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); + AssertFatal(*css->controlResourceSetId == mac->coreset[bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); + AssertFatal(css->searchSpaceId != NULL, "css->searchSpaceId is null\n"); + AssertFatal(css->searchSpaceType != NULL, "css->searchSpaceType is null\n"); + AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n"); + AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n"); + mac->SSpace[0][0][ss_id] = css; + ss_id++; + } +} + int nr_rrc_mac_config_req_ue( module_id_t module_id, int cc_idP, @@ -337,16 +408,16 @@ int nr_rrc_mac_config_req_ue( NR_UE_MAC_INST_t *mac = get_mac_inst(module_id); - // NR_ServingCellConfig_t *serving_cell_config = spcell_configP->spCellConfigDedicated; // TODO do something FAPI-like P5 L1/L2 config interface in config_si, config_mib, etc. - if(mibP != NULL){ mac->mib = mibP; // update by every reception } if(cell_group_config != NULL ){ + mac->scg = cell_group_config; mac->servCellIndex = *cell_group_config->spCellConfig->servCellIndex; + config_control_ue(mac); if (cell_group_config->spCellConfig->reconfigurationWithSync) { mac->rach_ConfigDedicated = cell_group_config->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink; mac->scc = cell_group_config->spCellConfig->reconfigurationWithSync->spCellConfigCommon; @@ -354,7 +425,6 @@ int nr_rrc_mac_config_req_ue( mac->crnti = cell_group_config->spCellConfig->reconfigurationWithSync->newUE_Identity; LOG_I(MAC,"Configuring CRNTI %x\n",mac->crnti); } - mac->scg = cell_group_config; /* if(mac_cell_group_configP != NULL){ @@ -419,8 +489,8 @@ int nr_rrc_mac_config_req_ue( } } */ - } - + } + return 0; } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c index 2cadb5dac3..cfbaa8d2f8 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_dci_configuration.c @@ -46,6 +46,8 @@ #endif #define LOG_DCI_PARM(a...) LOG_D(PHY,"\t<-NR_PDCCH_DCI_TOOLS_DEBUG (nr_generate_ue_ul_dlsch_params_from_dci)" a) +// #define DEBUG_DCI + dci_pdu_rel15_t *def_dci_pdu_rel15; void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15) { @@ -62,217 +64,261 @@ void fill_dci_search_candidates(NR_SearchSpace_t *ss,fapi_nr_dl_config_dci_dl_pd } +void config_dci_pdu(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15, fapi_nr_dl_config_request_t *dl_config, int rnti_type, int ss_id, uint8_t dci_format){ + + uint16_t monitoringSymbolsWithinSlot; + uint8_t bwp_id = 1, coreset_id = 1; + int sps; + def_dci_pdu_rel15 = calloc(1,sizeof(dci_pdu_rel15_t)); + AssertFatal(mac->scc != NULL, "scc is null\n"); + NR_ServingCellConfigCommon_t *scc = mac->scc; + NR_BWP_DownlinkCommon_t *bwp_Common = mac->DLbwp[bwp_id - 1]->bwp_Common; + NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP; + NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id]; + + // DCI format configuration + rel15->dci_format = dci_format; + + // CORESET configuration + NR_ControlResourceSet_t *coreset = mac->coreset[bwp_id - 1][coreset_id - 1]; + rel15->coreset.duration = coreset->duration; + for (int i = 0; i < 6; i++) + rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i]; + rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; + if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) { + struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved; + rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize); + rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize); + AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n"); + rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId; + } else { + rel15->coreset.RegBundleSize = 0; + rel15->coreset.InterleaverSize = 0; + rel15->coreset.ShiftIndex = 0; + } + rel15->coreset.CoreSetType = 1; + rel15->coreset.precoder_granularity = coreset->precoderGranularity; + + // Scrambling RNTI + if (coreset->pdcch_DMRS_ScramblingID) { + rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID; + rel15->coreset.scrambling_rnti = mac->t_crnti; + } else { + rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId; + rel15->coreset.scrambling_rnti = 0; + } + + #ifdef DEBUG_DCI + LOG_D(MAC, "[DCI_CONFIG] Configure DCI PDU: ss_id %d bwp %p bwp_Id %d controlResourceSetId %d\n", ss_id, mac->DLbwp[bwp_id - 1], mac->DLbwp[bwp_id - 1]->bwp_Id, coreset->controlResourceSetId); + #endif + + // loop over RNTI type and configure resource allocation for DCI + switch(rnti_type) { + case NR_RNTI_C: + // we use DL BWP dedicated + sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; + // for SPS=14 8 MSBs in positions 13 down to 6 + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = mac->crnti; + rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275); + rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); + rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing; + rel15->dci_length = nr_dci_size(mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_C, rel15->BWPSize, bwp_id); + break; + case NR_RNTI_RA: + // we use the initial DL BWP + sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12; + monitoringSymbolsWithinSlot = (ss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (ss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); + rel15->rnti = mac->ra_rnti; + rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); //NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); + rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; + rel15->dci_length = nr_dci_size(mac->scg, def_dci_pdu_rel15, rel15->dci_format, NR_RNTI_RA, rel15->BWPSize, bwp_id); + break; + case NR_RNTI_P: + break; + case NR_RNTI_CS: + break; + case NR_RNTI_TC: + break; + case NR_RNTI_SP_CSI: + break; + case NR_RNTI_SI: + break; + case NR_RNTI_SFI: + break; + case NR_RNTI_INT: + break; + case NR_RNTI_TPC_PUSCH: + break; + case NR_RNTI_TPC_PUCCH: + break; + case NR_RNTI_TPC_SRS: + break; + default: + break; + } + for (int i = 0; i < sps; i++) { + if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) { + rel15->coreset.StartSymbolIndex = i; + break; + } + } + #ifdef DEBUG_DCI + LOG_D(MAC, "[DCI_CONFIG] Configure DCI PDU: rnti_type %d BWPSize %d BWPStart %d rel15->SubcarrierSpacing %d rel15->dci_format %d rel15->dci_length %d sps %d monitoringSymbolsWithinSlot %d \n", + rnti_type, + rel15->BWPSize, + rel15->BWPStart, + rel15->SubcarrierSpacing, + rel15->dci_format, + rel15->dci_length, + sps, + monitoringSymbolsWithinSlot); + #endif + // add DCI + dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; + dl_config->number_pdus = dl_config->number_pdus + 1; +} + void ue_dci_configuration(NR_UE_MAC_INST_t *mac, fapi_nr_dl_config_request_t *dl_config, frame_t frame, int slot) { - def_dci_pdu_rel15 = calloc(1,sizeof(dci_pdu_rel15_t)); - - NR_BWP_Downlink_t *bwp; - NR_BWP_DownlinkCommon_t *bwp_Common; - NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated; - NR_SetupRelease_PDCCH_Config_t *pdcch_Config; - NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon; - struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList; - struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList; - struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList; - NR_SearchSpace_t *NR_SearchSpace; - NR_ControlResourceSet_t *coreset; - - fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15; + int ss_id; + uint8_t bwp_id = 1, coreset_id = 1; NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; + NR_BWP_Downlink_t *bwp = mac->DLbwp[bwp_id - 1]; - uint8_t bwp_id = 1; - int ss_id, sps; + #ifdef DEBUG_DCI + LOG_D(MAC, "[DCI_CONFIG] ra_rnti %p (%x) crnti %p (%x) t_crnti %p (%x)\n", &mac->ra_rnti, mac->ra_rnti, &mac->crnti, mac->crnti, &mac->t_crnti, mac->t_crnti); + #endif - // get PDCCH configuration(s) (Coreset, SearchSpace, etc...) from BWP Dedicated in serving cell config dedicated (scd) - // get BWP 1, Coreset ID 0, SearchSpace ID 0 (i.e. configured in MIB and in ServingCellConfigCommon) + // loop over all available SS for BWP ID 1, CORESET ID 1 + for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id] != NULL; ss_id++){ + NR_SearchSpace_t *ss = mac->SSpace[bwp_id - 1][coreset_id - 1][ss_id]; + fapi_nr_dl_config_dci_dl_pdu_rel15_t *rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; + NR_BWP_DownlinkCommon_t *bwp_Common = bwp->bwp_Common; + NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; + struct NR_PhysicalCellGroupConfig *phy_cgc = mac->scg->physicalCellGroupConfig; + switch (ss->searchSpaceType->present){ + case NR_SearchSpace__searchSpaceType_PR_common: + // this is for CSSs, we use BWP common and pdcch_ConfigCommon - // Check dedicated DL BWP - if (mac->DLbwp[0] == NULL) { - NR_SearchSpace_t *ss; - int ss_id = 0; - - AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n"); - AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count); - mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]; - - dl_bwp_Dedicated = mac->DLbwp[0]->bwp_Dedicated; - AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n"); - - bwp_Common = mac->DLbwp[0]->bwp_Common; - AssertFatal(bwp_Common != NULL, "bwp_Common is null\n"); - - pdcch_Config = dl_bwp_Dedicated->pdcch_Config; - AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n"); - - pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; - AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n"); - AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n"); - - controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList; - AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n"); - - AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count); - - mac->coreset[0][0] = controlResourceSetToAddModList->list.array[0]; - coreset = mac->coreset[0][0]; - AssertFatal(coreset != NULL, "coreset[0][0] is null\n"); - - searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList; - AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n"); - AssertFatal(searchSpacesToAddModList->list.count > 0, "searchSpacesToAddModList is empty\n"); - AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count); - - for (int i = 0; i < searchSpacesToAddModList->list.count; i++) { - ss = searchSpacesToAddModList->list.array[i]; - AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); - AssertFatal(ss->searchSpaceType != NULL, "ss->searchSpaceType is null\n"); - AssertFatal(*ss->controlResourceSetId == coreset->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); - mac->SSpace[0][0][ss_id] = ss; - ss_id++; - } - } - - // Check dedicated UL BWP - if (mac->ULbwp[0] == NULL) { - uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList; - AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n"); - AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count); - mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[bwp_id - 1]; - AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n"); - } - - bwp = mac->DLbwp[0]; - bwp_Common = bwp->bwp_Common; - pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; - dl_bwp_Dedicated = bwp->bwp_Dedicated; - pdcch_Config = dl_bwp_Dedicated->pdcch_Config; - searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList; - - // check USSs - ss_id = 0; - NR_SearchSpace = mac->SSpace[0][0][ss_id]; - while(NR_SearchSpace != NULL && ss_id < searchSpacesToAddModList->list.count) { - AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot is null\n"); - AssertFatal(NR_SearchSpace->monitoringSymbolsWithinSlot->buf != NULL, "NR_SearchSpace->monitoringSymbolsWithinSlot->buf is null\n"); - ss_id++; - } - - if (mac->crnti > 0) { - - NR_SearchSpace_t *css; - NR_SearchSpace_t *uss = NULL; - NR_ServingCellConfigCommon_t *scc; - NR_SearchSpaceId_t ra_SearchSpaceId; - rel15 = &dl_config->dl_config_list[dl_config->number_pdus].dci_config_pdu.dci_config_rel15; - uint16_t monitoringSymbolsWithinSlot; - uint8_t add_dci = 1; - - AssertFatal(mac->scc != NULL, "scc is null\n"); - - scc = mac->scc; - rel15->dci_format = NR_DL_DCI_FORMAT_1_1; - - // CoReSet configuration - coreset = mac->coreset[0][0]; - rel15->coreset.duration = coreset->duration; - for (int i = 0; i < 6; i++) - rel15->coreset.frequency_domain_resource[i] = coreset->frequencyDomainResources.buf[i]; - - rel15->coreset.CceRegMappingType = coreset->cce_REG_MappingType.present == NR_ControlResourceSet__cce_REG_MappingType_PR_interleaved ? FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED : FAPI_NR_CCE_REG_MAPPING_TYPE_NON_INTERLEAVED; - - if (rel15->coreset.CceRegMappingType == FAPI_NR_CCE_REG_MAPPING_TYPE_INTERLEAVED) { - struct NR_ControlResourceSet__cce_REG_MappingType__interleaved *interleaved = coreset->cce_REG_MappingType.choice.interleaved; - rel15->coreset.RegBundleSize = (interleaved->reg_BundleSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__reg_BundleSize_n6) ? 6 : (2 + interleaved->reg_BundleSize); - rel15->coreset.InterleaverSize = (interleaved->interleaverSize == NR_ControlResourceSet__cce_REG_MappingType__interleaved__interleaverSize_n6) ? 6 : (2 + interleaved->interleaverSize); - AssertFatal(scc->physCellId != NULL, "mac->scc->physCellId is null\n"); - rel15->coreset.ShiftIndex = interleaved->shiftIndex != NULL ? *interleaved->shiftIndex : *scc->physCellId; - } else { - rel15->coreset.RegBundleSize = 0; - rel15->coreset.InterleaverSize = 0; - rel15->coreset.ShiftIndex = 0; - } - - rel15->coreset.CoreSetType = 1; - rel15->coreset.precoder_granularity = coreset->precoderGranularity; - - if (mac->ra_state == WAIT_RAR){ - - NR_BWP_DownlinkCommon_t *initialDownlinkBWP = scc->downlinkConfigCommon->initialDownlinkBWP; - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n"); - - ra_SearchSpaceId = *pdcch_ConfigCommon->choice.setup->ra_SearchSpace; - - // fetch the CSS for RA from the CSS list - for (int i = 0; i < commonSearchSpaceList->list.count; i++) { - css = commonSearchSpaceList->list.array[i]; - if(css->searchSpaceId == ra_SearchSpaceId) - break; - } - - // check CSSs - if(css != NULL) { - AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n"); - AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n"); - } - - sps = initialDownlinkBWP->genericParameters.cyclicPrefix == NULL ? 14 : 12; - monitoringSymbolsWithinSlot = (css->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (css->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - rel15->rnti = mac->ra_rnti; - rel15->BWPSize = NRRIV2BW(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); - rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); // NRRIV2PRBOFFSET(initialDownlinkBWP->genericParameters.locationAndBandwidth, 275); - rel15->SubcarrierSpacing = initialDownlinkBWP->genericParameters.subcarrierSpacing; - rel15->dci_length = nr_dci_size(mac->scg,def_dci_pdu_rel15,rel15->dci_format,NR_RNTI_C,rel15->BWPSize,bwp_id); - - for (int i = 0; i < sps; i++) { - if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) { - rel15->coreset.StartSymbolIndex = i; - break; + // Fetch configuration for searchSpaceZero + // note: The search space with the SearchSpaceId = 0 identifies the search space configured via PBCH (MIB) and in ServingCellConfigCommon (searchSpaceZero). + if (pdcch_ConfigCommon->choice.setup->searchSpaceZero){ + LOG_D(MAC, "[DCI_CONFIG] Configure SearchSpace#0 of the initial BWP\n"); + LOG_W(MAC, "[DCI_CONFIG] This should not be available yet..."); + } + if (ss->searchSpaceType->choice.common->dci_Format0_0_AndFormat1_0){ + // check available SS IDs + if (pdcch_ConfigCommon->choice.setup->ra_SearchSpace){ + if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->ra_SearchSpace){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type1-PDCCH common random access search space\n"); + switch(mac->ra_state){ + case WAIT_RAR: + config_dci_pdu(mac, rel15, dl_config, NR_RNTI_RA, ss_id, NR_DL_DCI_FORMAT_1_0); + fill_dci_search_candidates(ss, rel15); + break; + case WAIT_CONTENTION_RESOLUTION: + rel15->rnti = mac->t_crnti; + break; + default: + break; + } + } } + if (pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){ + if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceSIB1){ + // Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG + LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet..."); + } + } + if (pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){ + if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->searchSpaceOtherSystemInformation){ + // Configure monitoring of PDCCH candidates in Type0-PDCCH common search space on the MCG + LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet..."); + } + } + if (pdcch_ConfigCommon->choice.setup->pagingSearchSpace){ + if (ss->searchSpaceId == *pdcch_ConfigCommon->choice.setup->pagingSearchSpace){ + // Configure monitoring of PDCCH candidates in Type2-PDCCH common search space on the MCG + LOG_W(MAC, "[DCI_CONFIG] This seach space should not be configured yet..."); + } + } + if (phy_cgc){ + if (phy_cgc->cs_RNTI){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n"); + LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet..."); + } + if (phy_cgc->ext1){ + if (phy_cgc->ext1->mcs_C_RNTI){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n"); + LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet..."); + } + } + } + } // end DCI 00 and 01 + // DCI 2_0 + if (ss->searchSpaceType->choice.common->dci_Format2_0){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_0 with CRC scrambled by SFI-RNTI \n"); + LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet..."); + } + // DCI 2_1 + if (ss->searchSpaceType->choice.common->dci_Format2_1){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_1 with CRC scrambled by INT-RNTI \n"); + LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet..."); + } + // DCI 2_2 + if (ss->searchSpaceType->choice.common->dci_Format2_2){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_2 with CRC scrambled by TPC-RNTI \n"); + LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet..."); + } + // DCI 2_3 + if (ss->searchSpaceType->choice.common->dci_Format2_3){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in Type3-PDCCH common search space for DCI format 2_3 with CRC scrambled by TPC-SRS-RNTI \n"); + LOG_W(MAC, "[DCI_CONFIG] This format should not be configured yet..."); } - fill_dci_search_candidates(css, rel15); + break; + case NR_SearchSpace__searchSpaceType_PR_ue_Specific: + // this is an USS + if (ss->searchSpaceType->choice.ue_Specific){ + if(ss->searchSpaceType->choice.ue_Specific->dci_Formats == NR_SearchSpace__searchSpaceType__ue_Specific__dci_Formats_formats0_1_And_1_1){ + // Monitors DCI 01 and 11 scrambled with C-RNTI, or CS-RNTI(s), or SP-CSI-RNTI + if (get_softmodem_params()->phy_test == 1 && mac->crnti > 0) { + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in the user specific search space\n"); + config_dci_pdu(mac, rel15, dl_config, NR_RNTI_C, ss_id, NR_DL_DCI_FORMAT_1_1); + fill_dci_search_candidates(ss, rel15); - } else if (mac->ra_state == WAIT_CONTENTION_RESOLUTION){ - - rel15->rnti = mac->t_crnti; - - } else { - - rel15->rnti = mac->crnti; - rel15->BWPSize = NRRIV2BW(bwp_Common->genericParameters.locationAndBandwidth, 275); - rel15->BWPStart = NRRIV2PRBOFFSET(bwp_Common->genericParameters.locationAndBandwidth, 275); - rel15->SubcarrierSpacing = bwp_Common->genericParameters.subcarrierSpacing; - rel15->dci_length = nr_dci_size(mac->scg,def_dci_pdu_rel15,rel15->dci_format,NR_RNTI_C,rel15->BWPSize,bwp_id); - // get UE-specific search space - for (ss_id = 0; ss_id < FAPI_NR_MAX_SS_PER_CORESET && mac->SSpace[0][0][ss_id] != NULL; ss_id++){ - uss = mac->SSpace[0][0][ss_id]; - if (uss->searchSpaceType->present == NR_SearchSpace__searchSpaceType_PR_ue_Specific) break; - } - AssertFatal(ss_id < FAPI_NR_MAX_SS_PER_CORESET, "couldn't find a UE-specific SS\n"); - sps = bwp_Common->genericParameters.cyclicPrefix == NULL ? 14 : 12; - // for SPS=14 8 MSBs in positions 13 down to 6 - monitoringSymbolsWithinSlot = (uss->monitoringSymbolsWithinSlot->buf[0]<<(sps-8)) | (uss->monitoringSymbolsWithinSlot->buf[1]>>(16-sps)); - for (int i = 0; i < sps; i++) - if ((monitoringSymbolsWithinSlot >> (sps - 1 - i)) & 1) { - rel15->coreset.StartSymbolIndex = i; - break; + #ifdef DEBUG_DCI + LOG_D(MAC, "[DCI_CONFIG] ss %d ue_Specific %p searchSpaceType->present %d dci_Formats %d\n", + ss_id, + ss->searchSpaceType->choice.ue_Specific, + ss->searchSpaceType->present, + ss->searchSpaceType->choice.ue_Specific->dci_Formats); + #endif + } + if (phy_cgc){ + if (phy_cgc->cs_RNTI){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by CS-RNTI...\n"); + LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet..."); + } + if (phy_cgc->sp_CSI_RNTI){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by SP-CSI-RNTI...\n"); + LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet..."); + } + if (phy_cgc->ext1){ + if (phy_cgc->ext1->mcs_C_RNTI){ + LOG_D(MAC, "[DCI_CONFIG] Configure monitoring of PDCCH candidates in user specific search space for dci_Format0_0_AndFormat1_0 with CRC scrambled by MCS-C-RNTI...\n"); + LOG_W(MAC, "[DCI_CONFIG] This RNTI should not be configured yet..."); + } + } + } } - fill_dci_search_candidates(uss, rel15); - } - - // Scrambling RNTI - if (coreset->pdcch_DMRS_ScramblingID) { - rel15->coreset.pdcch_dmrs_scrambling_id = *coreset->pdcch_DMRS_ScramblingID; - rel15->coreset.scrambling_rnti = mac->t_crnti; - } else { - rel15->coreset.pdcch_dmrs_scrambling_id = *scc->physCellId; - rel15->coreset.scrambling_rnti = 0; - } - - if (add_dci){ - dl_config->dl_config_list[dl_config->number_pdus].pdu_type = FAPI_NR_DL_CONFIG_TYPE_DCI; - dl_config->number_pdus = dl_config->number_pdus + 1; + } + break; + default: + AssertFatal(1 == 0, "[DCI_CONFIG] Unrecognized search space type..."); + break; } } } From bc243cee47ae3c9338207539fb2daf17f180d41a Mon Sep 17 00:00:00 2001 From: cig Date: Wed, 22 Jul 2020 16:12:35 +0200 Subject: [PATCH 106/171] Bugfix in DMRS configuration at UE side: - DM-RS type {1,2} was wrongly assigned to {1,2} instead of {0,1} - Num DM-RS CDM groups without data is now taken into account in mthread decoding function - number of DM-RS CDM groups without data for format 1_0 according to 5.1.6.2 3GPP TS 38.214 version 15.9.0 Release 15: -- the UE shall assume the number of DM-RS CDM groups without data is: -- 1 (CDM group 0) for the case of PDSCH with allocation duration of 2 symb -- 2 (CDM group {0,1}) for all other cases. --- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c | 9 +++++++-- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c index 7fd71d038d..3a2cb3f436 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_decoding.c @@ -266,7 +266,7 @@ uint32_t nr_dlsch_decoding(PHY_VARS_NR_UE *phy_vars_ue, double Coderate;// = 0.0; uint8_t dmrs_Type = harq_process->dmrsConfigType; - AssertFatal(dmrs_Type == 1 || dmrs_Type == 2,"Illegal dmrs_type %d\n",dmrs_Type); + AssertFatal(dmrs_Type == 0 || dmrs_Type == 1, "Illegal dmrs_type %d\n", dmrs_Type); uint8_t nb_re_dmrs; if (dmrs_Type==NFAPI_NR_DMRS_TYPE1) { nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups; @@ -811,7 +811,12 @@ uint32_t nr_dlsch_decoding_mthread(PHY_VARS_NR_UE *phy_vars_ue, //nfapi_nr_config_request_t *cfg = &phy_vars_ue->nrUE_config; //uint8_t dmrs_type = cfg->pdsch_config.dmrs_type.value; - uint8_t nb_re_dmrs = 12;//(dmrs_type==1)?6:4; + uint8_t nb_re_dmrs; + if (dmrs_Type == NFAPI_NR_DMRS_TYPE1) + nb_re_dmrs = 6*harq_process->n_dmrs_cdm_groups; + else + nb_re_dmrs = 4*harq_process->n_dmrs_cdm_groups; + uint16_t length_dmrs = get_num_dmrs(dl_config_pdu->dlDmrsSymbPos); uint32_t i,j; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 38f61656d8..8ccabc4287 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2749,7 +2749,12 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc dlsch_config_pdu_1_0->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, dlsch_config_pdu_1_0->number_symbols); - dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 1 : 2; + dlsch_config_pdu_1_0->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; + /* number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214 version 15.9.0 Release 15 */ + if (dlsch_config_pdu_1_0->number_symbols == 2) + dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 1; + else + dlsch_config_pdu_1_0->n_dmrs_cdm_groups = 2; /* VRB_TO_PRB_MAPPING */ dlsch_config_pdu_1_0->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; /* MCS */ @@ -2869,7 +2874,7 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc dlsch_config_pdu_1_1->dlDmrsSymbPos = fill_dmrs_mask(pdsch_config, mac->scc->dmrs_TypeA_Position, dlsch_config_pdu_1_1->number_symbols); - dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 1 : 2; + dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; /* VRB_TO_PRB_MAPPING */ if (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.resource_allocation != 0) dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; From 1f74524d0dc72e357872c25a4431d46f926a17dc Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 23 Jul 2020 10:10:19 +0200 Subject: [PATCH 107/171] fix for prepare dci 0_1 --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index a22d4988df..876f1b5396 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -820,7 +820,7 @@ void fill_dci_pdu_rel15(NR_ServingCellConfigCommon_t *scc, pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d] = dci_size; AssertFatal(pdcch_pdu_rel15->dci_pdu.PayloadSizeBits[d]<=64, "DCI sizes above 64 bits not yet supported"); - if(dci_formats[d]==NR_DL_DCI_FORMAT_1_1) + if(dci_formats[d]==NR_DL_DCI_FORMAT_1_1 || dci_formats[d]==NR_UL_DCI_FORMAT_0_1) prepare_dci(secondaryCellGroup,&dci_pdu_rel15[d],dci_formats[d],bwp_id); /// Payload generation From d8bbfdbddaf719142a3d073bb907f285a800aaa5 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 23 Jul 2020 22:24:55 +0200 Subject: [PATCH 108/171] bugfix in eNB_scheduler.c. Code still to be moved to L1. --- openair2/LAYER2/MAC/eNB_scheduler.c | 19 ++++++++++++++++++- openair2/RRC/LTE/rrc_eNB.c | 4 ++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/MAC/eNB_scheduler.c b/openair2/LAYER2/MAC/eNB_scheduler.c index c46005ee2d..d184c7e439 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler.c +++ b/openair2/LAYER2/MAC/eNB_scheduler.c @@ -547,7 +547,7 @@ copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { ul_req_tmp->ul_config_request_body.number_of_pdus = 0; if (ul_req->ul_config_request_body.number_of_pdus>0) { - LOG_D(PHY, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus); + LOG_D(MAC, "%s() active NOW (frameP:%d subframeP:%d) pdus:%d\n", __FUNCTION__, frameP, subframeP, ul_req->ul_config_request_body.number_of_pdus); } memcpy((void *)ul_req->ul_config_request_body.ul_config_pdu_list, @@ -556,6 +556,11 @@ copy_ulreq(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) { } } +extern int16_t find_dlsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); +extern int16_t find_ulsch(uint16_t rnti, PHY_VARS_eNB *eNB,find_type_t type); +extern void clean_eNb_ulsch(LTE_eNB_ULSCH_t *ulsch); +extern void clean_eNb_dlsch(LTE_eNB_DLSCH_t *dlsch); + void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, @@ -843,6 +848,7 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, } /* Note: This should not be done in the MAC! */ + /* for (int ii=0; iiulsch[ii]; @@ -862,6 +868,17 @@ eNB_dlsch_ulsch_scheduler(module_id_t module_idP, clean_eNb_dlsch(dlsch); } } + */ + + int id; + + // clean ULSCH entries for rnti + id = find_ulsch(rnti,RC.eNB[module_idP][CC_id],SEARCH_EXIST); + if (id>=0) clean_eNb_ulsch(RC.eNB[module_idP][CC_id]->ulsch[id]); + + // clean DLSCH entries for rnti + id = find_dlsch(rnti,RC.eNB[module_idP][CC_id],SEARCH_EXIST); + if (id>=0) clean_eNb_dlsch(RC.eNB[module_idP][CC_id]->dlsch[id][0]); for (int j = 0; j < 10; j++) { nfapi_ul_config_request_body_t *ul_req_tmp = NULL; diff --git a/openair2/RRC/LTE/rrc_eNB.c b/openair2/RRC/LTE/rrc_eNB.c index 35a45714c4..16d5065d37 100644 --- a/openair2/RRC/LTE/rrc_eNB.c +++ b/openair2/RRC/LTE/rrc_eNB.c @@ -1039,11 +1039,11 @@ void release_UE_in_freeList(module_id_t mod_id) { // clean ULSCH entries for rnti id = find_ulsch(rnti,eNB_PHY,SEARCH_EXIST); - if (id>0) clean_eNb_ulsch(eNB_PHY->ulsch[id]); + if (id>=0) clean_eNb_ulsch(eNB_PHY->ulsch[id]); // clean DLSCH entries for rnti id = find_dlsch(rnti,eNB_PHY,SEARCH_EXIST); - if (id>0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]); + if (id>=0) clean_eNb_dlsch(eNB_PHY->dlsch[id][0]); // clean UCI entries for rnti for (i=0; i Date: Fri, 24 Jul 2020 18:03:22 +0200 Subject: [PATCH 109/171] brought cde line arg parsing out of main.py, into a separated module --- ci-scripts/args_parse.py | 229 +++++++++++++++++ ci-scripts/main.py | 385 +++++++++++++++-------------- ci-scripts/py_params.yaml | 1 - ci-scripts/py_params_template.yaml | 97 ++++++++ 4 files changed, 524 insertions(+), 188 deletions(-) create mode 100644 ci-scripts/args_parse.py create mode 100644 ci-scripts/py_params_template.yaml diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py new file mode 100644 index 0000000000..a36f619ee2 --- /dev/null +++ b/ci-scripts/args_parse.py @@ -0,0 +1,229 @@ + +# * 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 +# */ +#--------------------------------------------------------------------- +# Python for CI of OAI-eNB + COTS-UE +# +# Required Python Version +# Python 3.x +# +# Required Python Package +# pexpect +#--------------------------------------------------------------------- + +#----------------------------------------------------------- +# Import Libs +#----------------------------------------------------------- +import sys # arg +import re # reg +import yaml + + +#----------------------------------------------------------- +# Parsing Command Line Arguements +#----------------------------------------------------------- + + +def ArgsParse(argvs,CiTestObj,RAN,HTML,ldpc,HELP): + + + py_param_file_present = False + py_params={} + + while len(argvs) > 1: + myArgv = argvs.pop(1) # 0th is this file's name + + #--help + if re.match('^\-\-help$', myArgv, re.IGNORECASE): + HELP.GenericHelp(CONST.Version) + sys.exit(0) + + #--apply= as parameters file, to replace inline parameters + elif re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE) + py_params_file = matchReg.group(1) + with open(py_params_file,'r') as file: + # The FullLoader parameter handles the conversion from YAML + # scalar values to Python dictionary format + py_params = yaml.load(file,Loader=yaml.FullLoader) + py_param_file_present = True #to be removed once validated + #AssignParams(py_params) #to be uncommented once validated + + #consider inline parameters + elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) + mode = matchReg.group(1) + elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) + else: + matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.ranRepository = matchReg.group(1) + RAN.ranRepository=matchReg.group(1) + HTML.ranRepository=matchReg.group(1) + ldpc.ranRepository=matchReg.group(1) + elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) + else: + matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) + doMerge = matchReg.group(1) + ldpc.ranAllowMerge=matchReg.group(1) + if ((doMerge == 'true') or (doMerge == 'True')): + CiTestObj.ranAllowMerge = True + RAN.ranAllowMerge=True + HTML.ranAllowMerge=True + elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) + else: + matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.ranBranch = matchReg.group(1) + RAN.ranBranch=matchReg.group(1) + HTML.ranBranch=matchReg.group(1) + ldpc.ranBranch=matchReg.group(1) + elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) + else: + matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) + CiTestObj.ranCommitID = matchReg.group(1) + RAN.ranCommitID=matchReg.group(1) + HTML.ranCommitID=matchReg.group(1) + ldpc.ranCommitID=matchReg.group(1) + elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) + else: + matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) + CiTestObj.ranTargetBranch = matchReg.group(1) + RAN.ranTargetBranch=matchReg.group(1) + HTML.ranTargetBranch=matchReg.group(1) + ldpc.ranTargetBranch=matchReg.group(1) + elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) + RAN.eNBIPAddress=matchReg.group(1) + ldpc.eNBIpAddr=matchReg.group(1) + elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB1IPAddress=matchReg.group(1) + elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB2IPAddress=matchReg.group(1) + elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) + RAN.eNBUserName=matchReg.group(1) + ldpc.eNBUserName=matchReg.group(1) + elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB1UserName=matchReg.group(1) + elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB2UserName=matchReg.group(1) + elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) + RAN.eNBPassword=matchReg.group(1) + ldpc.eNBPassWord=matchReg.group(1) + elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB1Password=matchReg.group(1) + elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB2Password=matchReg.group(1) + elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): + if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) + RAN.eNBSourceCodePath=matchReg.group(1) + ldpc.eNBSourceCodePath=matchReg.group(1) + elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB1SourceCodePath=matchReg.group(1) + elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) + RAN.eNB2SourceCodePath=matchReg.group(1) + elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) + EPC.IPAddress=matchReg.group(1) + elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) + EPC.UserName=matchReg.group(1) + elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) + EPC.Password=matchReg.group(1) + elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) + EPC.SourceCodePath=matchReg.group(1) + elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) + if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE): + EPC.Type=matchReg.group(1) + else: + sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)') + elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE) + EPC.ContainerPrefix=matchReg.group(1) + elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.ADBIPAddress = matchReg.group(1) + elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.ADBUserName = matchReg.group(1) + elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) + if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): + if re.match('distributed', matchReg.group(1), re.IGNORECASE): + CiTestObj.ADBCentralized = False + else: + CiTestObj.ADBCentralized = True + else: + sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') + elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.ADBPassword = matchReg.group(1) + elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.testXMLfiles.append(matchReg.group(1)) + HTML.testXMLfiles=matchReg.group(1) + HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1 + elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.UEIPAddress = matchReg.group(1) + elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.UEUserName = matchReg.group(1) + elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.UEPassword = matchReg.group(1) + elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) + CiTestObj.UESourceCodePath = matchReg.group(1) + elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): + matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) + finalStatus = matchReg.group(1) + if ((finalStatus == 'true') or (finalStatus == 'True')): + CiTestObj.finalStatus = True + else: + HELP.GenericHelp(CONST.Version) + sys.exit('Invalid Parameter: ' + myArgv) + + return py_param_file_present, py_params, mode \ No newline at end of file diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 82a1da0390..9fc7b19d58 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3100,11 +3100,9 @@ def CheckClassValidity(xml_class_list,action,id): #assigning parameters to object instance attributes (even if the attributes do not exist !!) def AssignParams(params_dict): - #-- - mode=params_dict['mode'] - #-- + for key,value in params_dict.items(): - setattr(CITestObj, key, value) + setattr(CiTestObj, key, value) setattr(RAN, key, value) setattr(HTML, key, value) setattr(ldpc, key, value) @@ -3330,191 +3328,193 @@ ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU b #----------------------------------------------------------- -# Parameter Check +# Parsing Command Line Arguments #----------------------------------------------------------- -argvs = sys.argv -argc = len(argvs) -cwd = os.getcwd() -py_param_file_present = False -while len(argvs) > 1: - myArgv = argvs.pop(1) # 0th is this file's name +import args_parse +py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,ldpc,HELP) - #--help - if re.match('^\-\-help$', myArgv, re.IGNORECASE): - HELP.GenericHelp(CONST.Version) - sys.exit(0) - - #--apply= as parameters file, to replace inline parameters - elif re.match('^\-\-apply=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-apply=(.+)$', myArgv, re.IGNORECASE) - py_params_file = matchReg.group(1) - with open(py_params_file,'r') as file: - # The FullLoader parameter handles the conversion from YAML - # scalar values to Python dictionary format - py_params = yaml.load(file,Loader=yaml.FullLoader) - py_param_file_present = True #to be removed once validated - #AssignParams(py_params) #to be uncommented once validated - - #consider inline parameters - elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) - mode = matchReg.group(1) - elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ranRepository = matchReg.group(1) - RAN.ranRepository=matchReg.group(1) - HTML.ranRepository=matchReg.group(1) - ldpc.ranRepository=matchReg.group(1) - elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) - doMerge = matchReg.group(1) - ldpc.ranAllowMerge=matchReg.group(1) - if ((doMerge == 'true') or (doMerge == 'True')): - CiTestObj.ranAllowMerge = True - RAN.ranAllowMerge=True - HTML.ranAllowMerge=True - elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ranBranch = matchReg.group(1) - RAN.ranBranch=matchReg.group(1) - HTML.ranBranch=matchReg.group(1) - ldpc.ranBranch=matchReg.group(1) - elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) - CiTestObj.ranCommitID = matchReg.group(1) - RAN.ranCommitID=matchReg.group(1) - HTML.ranCommitID=matchReg.group(1) - ldpc.ranCommitID=matchReg.group(1) - elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) - else: - matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) - CiTestObj.ranTargetBranch = matchReg.group(1) - RAN.ranTargetBranch=matchReg.group(1) - HTML.ranTargetBranch=matchReg.group(1) - ldpc.ranTargetBranch=matchReg.group(1) - elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.eNBIPAddress=matchReg.group(1) - ldpc.eNBIpAddr=matchReg.group(1) - elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB1IPAddress=matchReg.group(1) - elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB2IPAddress=matchReg.group(1) - elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) - RAN.eNBUserName=matchReg.group(1) - ldpc.eNBUserName=matchReg.group(1) - elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB1UserName=matchReg.group(1) - elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB2UserName=matchReg.group(1) - elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) - RAN.eNBPassword=matchReg.group(1) - ldpc.eNBPassWord=matchReg.group(1) - elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB1Password=matchReg.group(1) - elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB2Password=matchReg.group(1) - elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.eNBSourceCodePath=matchReg.group(1) - ldpc.eNBSourceCodePath=matchReg.group(1) - elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB1SourceCodePath=matchReg.group(1) - elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) - RAN.eNB2SourceCodePath=matchReg.group(1) - elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) - EPC.IPAddress=matchReg.group(1) - elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) - EPC.UserName=matchReg.group(1) - elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) - EPC.Password=matchReg.group(1) - elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) - EPC.SourceCodePath=matchReg.group(1) - elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) - if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE): - EPC.Type=matchReg.group(1) - else: - sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)') - elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE) - EPC.ContainerPrefix=matchReg.group(1) - elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ADBIPAddress = matchReg.group(1) - elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ADBUserName = matchReg.group(1) - elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) - if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): - if re.match('distributed', matchReg.group(1), re.IGNORECASE): - CiTestObj.ADBCentralized = False - else: - CiTestObj.ADBCentralized = True - else: - sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') - elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.ADBPassword = matchReg.group(1) - elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.testXMLfiles.append(matchReg.group(1)) - HTML.testXMLfiles=matchReg.group(1) - HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1 - elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UEIPAddress = matchReg.group(1) - elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UEUserName = matchReg.group(1) - elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UEPassword = matchReg.group(1) - elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) - CiTestObj.UESourceCodePath = matchReg.group(1) - elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): - matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) - finalStatus = matchReg.group(1) - if ((finalStatus == 'true') or (finalStatus == 'True')): - CiTestObj.finalStatus = True - else: - HELP.GenericHelp(CONST.Version) - sys.exit('Invalid Parameter: ' + myArgv) +#argvs = sys.argv +#py_param_file_present = False +# +#while len(argvs) > 1: +# myArgv = argvs.pop(1) # 0th is this file's name +# +# #--help +# if re.match('^\-\-help$', myArgv, re.IGNORECASE): +# HELP.GenericHelp(CONST.Version) +# sys.exit(0) +# +# #--apply= as parameters file, to replace inline parameters +# elif re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE) +# py_params_file = matchReg.group(1) +# with open(py_params_file,'r') as file: +# # The FullLoader parameter handles the conversion from YAML +# # scalar values to Python dictionary format +# py_params = yaml.load(file,Loader=yaml.FullLoader) +# py_param_file_present = True #to be removed once validated +# #AssignParams(py_params) #to be uncommented once validated +# +# #consider inline parameters +# elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) +# mode = matchReg.group(1) +# elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) +# else: +# matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.ranRepository = matchReg.group(1) +# RAN.ranRepository=matchReg.group(1) +# HTML.ranRepository=matchReg.group(1) +# ldpc.ranRepository=matchReg.group(1) +# elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) +# else: +# matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) +# doMerge = matchReg.group(1) +# ldpc.ranAllowMerge=matchReg.group(1) +# if ((doMerge == 'true') or (doMerge == 'True')): +# CiTestObj.ranAllowMerge = True +# RAN.ranAllowMerge=True +# HTML.ranAllowMerge=True +# elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) +# else: +# matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.ranBranch = matchReg.group(1) +# RAN.ranBranch=matchReg.group(1) +# HTML.ranBranch=matchReg.group(1) +# ldpc.ranBranch=matchReg.group(1) +# elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) +# else: +# matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) +# CiTestObj.ranCommitID = matchReg.group(1) +# RAN.ranCommitID=matchReg.group(1) +# HTML.ranCommitID=matchReg.group(1) +# ldpc.ranCommitID=matchReg.group(1) +# elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) +# else: +# matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) +# CiTestObj.ranTargetBranch = matchReg.group(1) +# RAN.ranTargetBranch=matchReg.group(1) +# HTML.ranTargetBranch=matchReg.group(1) +# ldpc.ranTargetBranch=matchReg.group(1) +# elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNBIPAddress=matchReg.group(1) +# ldpc.eNBIpAddr=matchReg.group(1) +# elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB1IPAddress=matchReg.group(1) +# elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB2IPAddress=matchReg.group(1) +# elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNBUserName=matchReg.group(1) +# ldpc.eNBUserName=matchReg.group(1) +# elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB1UserName=matchReg.group(1) +# elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB2UserName=matchReg.group(1) +# elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNBPassword=matchReg.group(1) +# ldpc.eNBPassWord=matchReg.group(1) +# elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB1Password=matchReg.group(1) +# elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB2Password=matchReg.group(1) +# elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): +# if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNBSourceCodePath=matchReg.group(1) +# ldpc.eNBSourceCodePath=matchReg.group(1) +# elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB1SourceCodePath=matchReg.group(1) +# elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) +# RAN.eNB2SourceCodePath=matchReg.group(1) +# elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) +# EPC.IPAddress=matchReg.group(1) +# elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) +# EPC.UserName=matchReg.group(1) +# elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) +# EPC.Password=matchReg.group(1) +# elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) +# EPC.SourceCodePath=matchReg.group(1) +# elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) +# if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE): +# EPC.Type=matchReg.group(1) +# else: +# sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)') +# elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE) +# EPC.ContainerPrefix=matchReg.group(1) +# elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.ADBIPAddress = matchReg.group(1) +# elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.ADBUserName = matchReg.group(1) +# elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) +# if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): +# if re.match('distributed', matchReg.group(1), re.IGNORECASE): +# CiTestObj.ADBCentralized = False +# else: +# CiTestObj.ADBCentralized = True +# else: +# sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') +# elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.ADBPassword = matchReg.group(1) +# elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.testXMLfiles.append(matchReg.group(1)) +# HTML.testXMLfiles=matchReg.group(1) +# HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1 +# elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.UEIPAddress = matchReg.group(1) +# elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.UEUserName = matchReg.group(1) +# elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.UEPassword = matchReg.group(1) +# elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) +# CiTestObj.UESourceCodePath = matchReg.group(1) +# elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): +# matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) +# finalStatus = matchReg.group(1) +# if ((finalStatus == 'true') or (finalStatus == 'True')): +# CiTestObj.finalStatus = True +# else: +# HELP.GenericHelp(CONST.Version) +# sys.exit('Invalid Parameter: ' + myArgv) #----------------------------------------------------------- @@ -3522,7 +3522,15 @@ while len(argvs) > 1: #----------------------------------------------------------- #temporary solution for testing: if py_param_file_present == True: - AssignParams(py_params) + AssignParams(py_params) + +#for debug +print(RAN.__dict__) +print(CiTestObj.__dict__) +print(HTML.__dict__) +print(ldpc.__dict__) +#for debug + #----------------------------------------------------------- # COTS UE instanciation @@ -3534,6 +3542,7 @@ COTS_UE=cls_cots_ue.CotsUe('oppo', CiTestObj.UEIPAddress, CiTestObj.UEUserName,C #----------------------------------------------------------- # XML class (action) analysis #----------------------------------------------------------- +cwd = os.getcwd() if re.match('^TerminateeNB$', mode, re.IGNORECASE): if RAN.eNBIPAddress == '' or RAN.eNBUserName == '' or RAN.eNBPassword == '': @@ -3851,6 +3860,8 @@ elif re.match('^TesteNB$', mode, re.IGNORECASE) or re.match('^TestUE$', mode, re else: logging.info('Testsuite passed after ' + str(CiTestObj.FailReportCnt) + ' time(s)') HTML.CreateHtmlTabFooter(True) +elif re.match('^LoadParams$', mode, re.IGNORECASE): + pass else: HELP.GenericHelp(CONST.Version) sys.exit('Invalid mode') diff --git a/ci-scripts/py_params.yaml b/ci-scripts/py_params.yaml index 68471763f7..303d5d1006 100644 --- a/ci-scripts/py_params.yaml +++ b/ci-scripts/py_params.yaml @@ -1,4 +1,3 @@ -mode : a eNBRepository : b ranRepository : c eNB_AllowMerge : diff --git a/ci-scripts/py_params_template.yaml b/ci-scripts/py_params_template.yaml new file mode 100644 index 0000000000..aaf31c1576 --- /dev/null +++ b/ci-scripts/py_params_template.yaml @@ -0,0 +1,97 @@ +eNBRepository : b +ranRepository : c +eNB_AllowMerge : +ranAllowMerge : +eNBBranch : f +ranBranch : g +eNBCommitID : +ranCommitID : i +eNBTargetBranch : j +ranTargetBranch : k + + +RAN: + RAN_inst_0: + name : RAN_1 + nodes : + - type : eNB + IPAddress : 001.1.1 + UserName : toto + Password : qwe + SourceCodePath : l + - type : gNB + IPAddress : 002.2.2 + UserName : tata + Password : asd + SourceCodePath : m + - type : eNB + IPAddress : 003.3.3 + UserName : titi + Password : zxc + SourceCodePath : n + - type : gNB + IPAddress : 004.4.4 + UserName : caca + Password : pepe + SourceCodePath : o + RAN_inst_1: + name : RAN_2 + nodes : + - type : eNB + IPAddress : 101.1.1 + UserName : toto + Password : qwe + SourceCodePath : l + - type : gNB + IPAddress : 102.2.2 + UserName : zaza + Password : asd + SourceCodePath : m + - type : eNB + IPAddress : 103.3.3 + UserName : zizi + Password : zxc + SourceCodePath : n + - type : gNB + IPAddress : 104.4.4 + UserName : aaaa + Password : pepe + SourceCodePath : o + + + +EPC: + EPC_inst_0: + EPCIPAddress : p + EPCUserName : q + EPCPassword : r + EPCSourceCodePath : s + EPCType : t + EPCContainerPrefix : u + +ADB: + ADBIPAddress : v + ADBUserName : w + ADBType : x + ADBPassword : y + + +UE: + UE_inst_0: + name : UE_1 + type : + UEIPAddress : qqq + UEUserName : www + UEPassword : eee + UESourceCodePath : yyy + UE_inst_1: + name : UE_2 + type : + UEIPAddress : bloblob + UEUserName : gwou + UEPassword : zebu + UESourceCodePath : pop + + +XMLTestFile : z +finalStatus : bbb \ No newline at end of file From 457c1b725a13808c8eb5f0f8893f2af7b237bb00 Mon Sep 17 00:00:00 2001 From: cig Date: Thu, 23 Jul 2020 08:21:24 +0200 Subject: [PATCH 110/171] Small fixes @ UE --- openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c | 2 +- openair2/LAYER2/NR_MAC_UE/mac_defs.h | 1 - openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 2 -- openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c | 2 +- 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c index b0f2b99ee6..1f070f5ef9 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c +++ b/openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c @@ -2388,7 +2388,7 @@ unsigned short nr_dlsch_extract_rbs_single(int **rxdataF, for (aarx=0; aarxnb_antennas_rx; aarx++) { - k = frame_parms->first_carrier_offset + 12*start_rb; + k = frame_parms->first_carrier_offset + NR_NB_SC_PER_RB*start_rb; if (high_speed_flag == 1) dl_ch0 = &dl_ch_estimates[aarx][(2*(frame_parms->ofdm_symbol_size))]; diff --git a/openair2/LAYER2/NR_MAC_UE/mac_defs.h b/openair2/LAYER2/NR_MAC_UE/mac_defs.h index 1ccc87770b..e45f6a9b69 100755 --- a/openair2/LAYER2/NR_MAC_UE/mac_defs.h +++ b/openair2/LAYER2/NR_MAC_UE/mac_defs.h @@ -178,7 +178,6 @@ typedef struct { SFN_C_TYPE type0_pdcch_ss_sfn_c; uint32_t type0_pdcch_ss_n_c; uint32_t type0_pdcch_consecutive_slots; - int rnti_type; /* PDUs */ /// Outgoing CCCH pdu for PHY diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 8ccabc4287..f0fac267bb 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -3162,8 +3162,6 @@ void nr_extract_dci_info(NR_UE_MAC_INST_t *mac, #endif break; - mac->rnti_type = rnti_type; - case NR_RNTI_C: // indicating a DL DCI format 1bit diff --git a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c index 664eef966f..e63f93b028 100644 --- a/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_UE_PHY_INTERFACE/NR_IF_Module.c @@ -147,7 +147,7 @@ int nr_ue_dl_indication(nr_downlink_indication_t *dl_info, NR_UL_TIME_ALIGNMENT_ fapi_nr_ul_config_request_t *ul_config = &mac->ul_config_request; if (!dl_info->dci_ind && !dl_info->rx_ind) { - // UL indication to schedule reception DCI reception + // UL indication to schedule DCI reception nr_ue_scheduler(dl_info, NULL); } else { // UL indication after reception of DCI or DL PDU From 90dc9e9555796362fbb34431f58eab28eb60a20e Mon Sep 17 00:00:00 2001 From: cig Date: Sat, 25 Jul 2020 09:49:08 +0200 Subject: [PATCH 111/171] Set RA succeeded and UE mode to PUSCH after correct decoding of Msg2 --- openair1/SCHED_NR_UE/phy_procedures_nr_ue.c | 4 +++- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 8 ++++---- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 5 +++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c index d7c953b105..68715e27a8 100644 --- a/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c +++ b/openair1/SCHED_NR_UE/phy_procedures_nr_ue.c @@ -2269,7 +2269,7 @@ void phy_procedures_nrUE_TX(PHY_VARS_NR_UE *ue, /* RACH */ if (get_softmodem_params()->do_ra==1) { - if ((ue->UE_mode[gNB_id] == PRACH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) { + if ((ue->UE_mode[gNB_id] < PUSCH) && (ue->prach_vars[gNB_id]->prach_Config_enabled == 1)) { nr_ue_prach_procedures(ue, proc, gNB_id, mode); } } @@ -4609,6 +4609,8 @@ void nr_ue_prach_procedures(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, uint8_t if (ue->prach_cnt == 3) ue->prach_cnt = 0; + } else if (nr_prach == 2) { + nr_ra_succeeded(mod_id, ue->CC_id, gNB_id); } // if we're calibrating the PRACH kill the pointer to its resources so that the RA protocol doesn't continue diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 89e3f7cc18..d4f6ab3c91 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -448,7 +448,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, nr_get_RA_window(mac); // Fill in preamble and PRACH resources - if (mac->generate_nr_prach) + if (mac->generate_nr_prach == 1) nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 1, prach_resources, rach_ConfigDedicated); offset = nr_generate_ulsch_pdu((uint8_t *) mac_sdus, // sdus buffer @@ -493,8 +493,8 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, if (mac->RA_window_cnt >= 0 && mac->RA_RAPID_found == 1) { - mac->ra_state = WAIT_CONTENTION_RESOLUTION; mac->RA_window_cnt = -1; + mac->ra_state = RA_SUCCEEDED; LOG_I(MAC, "[MAC][UE %d][RAPROC] Frame %d: nr_tti_tx %d: RAR successfully received \n", mod_id, frame, nr_tti_tx); } else if (mac->RA_window_cnt == 0 && !mac->RA_RAPID_found) { @@ -571,7 +571,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, // mac->RA_tx_subframe = nr_tti_tx; // Fill in preamble and PRACH resources - if (mac->generate_nr_prach) + if (mac->generate_nr_prach == 1) nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated); } else { @@ -585,7 +585,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, mac->RA_window_cnt); // Fill in preamble and PRACH resources - if (mac->generate_nr_prach) + if (mac->generate_nr_prach == 1) nr_get_prach_resources(mod_id, CC_id, gNB_id, nr_tti_tx, 0, prach_resources, rach_ConfigDedicated); } diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index f0fac267bb..e422b1aed7 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -959,6 +959,7 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s config_index = rach_ConfigGeneric->prach_ConfigurationIndex; mac->RA_offset = 2; // to compensate the rx frame offset at the gNB + mac->generate_nr_prach = 0; // Reset flag for PRACH generation if (is_nr_UL_slot(scc, slotP)) { @@ -1080,8 +1081,8 @@ void nr_ue_prach_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t s } } } - } else { - mac->generate_nr_prach = 0; + } else if (mac->ra_state == RA_SUCCEEDED){ + mac->generate_nr_prach = 2; } mac->scheduled_response.ul_config = ul_config; } From d81f8b91205c6c2aa2840f4ff195428f0358ba29 Mon Sep 17 00:00:00 2001 From: hardy Date: Mon, 27 Jul 2020 14:08:21 +0200 Subject: [PATCH 112/171] fixed CONST. missing in front of constant, leading to execution error --- ci-scripts/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 9fc7b19d58..4ea2884c3b 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -2643,7 +2643,7 @@ class OaiCiTest(): else: statMsg = 'UE did NOT SHOW "TRIED TO PUSH MBMS DATA" message(s)' logging.debug('\u001B[1;30;41m ' + statMsg + ' \u001B[0m') - global_status = OAI_UE_PROCESS_NO_MBMS_MSGS + global_status = CONST.OAI_UE_PROCESS_NO_MBMS_MSGS HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + statMsg + '\n' if foundSegFault: logging.debug('\u001B[1;37;41m UE ended with a Segmentation Fault! \u001B[0m') From 427b223136ce00cd933f86628729acf81c231c83 Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 27 Jul 2020 16:08:31 +0200 Subject: [PATCH 113/171] small fiwes --- cmake_targets/build_oai | 1 + common/utils/ocp_itti/intertask_interface.cpp | 2 +- common/utils/threadPool/thread-pool.c | 5 +++-- executables/nr-uesoftmodem.c | 7 ++----- openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c | 2 +- openair1/PHY/NR_TRANSPORT/nr_prach.c | 2 +- openair1/PHY/TOOLS/readme.md | 12 ++++++++++++ openair1/PHY/phy_vars.h | 8 ++++---- openair1/PHY/phy_vars_nr_ue.h | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair2/ENB_APP/flexran_agent_extern.h | 2 -- openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c | 2 +- targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c | 4 ++-- targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp | 1 - targets/ARCH/rfsimulator/simulator.c | 12 ++++++++++-- 15 files changed, 40 insertions(+), 24 deletions(-) create mode 100644 openair1/PHY/TOOLS/readme.md diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 88b8811575..e0093c909c 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -580,6 +580,7 @@ function main() { cmake_file=$DIR/$build_dir/CMakeLists.txt echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file + echo "project (OpenAirInterface)" >> $cmake_file echo "set ( CMAKE_BUILD_TYPE $CMAKE_BUILD_TYPE )" >> $cmake_file echo "set ( CFLAGS_PROCESSOR_USER \"$CFLAGS_PROCESSOR_USER\" )" >> $cmake_file echo "set ( UE_EXPANSION $UE_EXPANSION )" >> $cmake_file diff --git a/common/utils/ocp_itti/intertask_interface.cpp b/common/utils/ocp_itti/intertask_interface.cpp index 22933fdd5b..1680410ebb 100644 --- a/common/utils/ocp_itti/intertask_interface.cpp +++ b/common/utils/ocp_itti/intertask_interface.cpp @@ -80,7 +80,7 @@ task_list_t tasks[TASK_MAX]; void *itti_malloc(task_id_t origin_task_id, task_id_t destination_task_id, ssize_t size) { void *ptr = NULL; - AssertFatal ((ptr=malloc (size)) != NULL, "Memory allocation of %zu bytes failed (%d -> %d)!\n", + AssertFatal ((ptr=calloc (size, 1)) != NULL, "Memory allocation of %zu bytes failed (%d -> %d)!\n", size, origin_task_id, destination_task_id); return ptr; } diff --git a/common/utils/threadPool/thread-pool.c b/common/utils/threadPool/thread-pool.c index cbb2dbe3d9..e1446f15d7 100644 --- a/common/utils/threadPool/thread-pool.c +++ b/common/utils/threadPool/thread-pool.c @@ -111,9 +111,10 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { pool->activated=true; initNotifiedFIFO(&pool->incomingFifo); char *saveptr, * curptr; + char *parms_cpy=strdup(params); pool->nbThreads=0; pool->restrictRNTI=false; - curptr=strtok_r(params,",",&saveptr); + curptr=strtok_r(parms_cpy,",",&saveptr); struct one_thread * ptr; while ( curptr!=NULL ) { int c=toupper(curptr[0]); @@ -145,7 +146,7 @@ void initTpool(char *params,tpool_t *pool, bool performanceMeas) { curptr=strtok_r(NULL,",",&saveptr); } - + free(parms_cpy); if (pool->activated && pool->nbThreads==0) { printf("No servers created in the thread pool, exit\n"); exit(1); diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 6d3bbc9038..e4c6d7b439 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -76,12 +76,9 @@ unsigned short config_frames[4] = {2,9,11,13}; #include #include -//#include "stats.h" -// current status is that every UE has a DL scope for a SINGLE eNB (eNB_id=0) -#include "PHY/TOOLS/nr_phy_scope.h" -// at eNB 0, an UL scope for every UE -//FD_lte_phy_scope_enb *form_enb[MAX_NUM_CCs][NUMBER_OF_UE_MAX]; +/* Callbacks, globals and object handlers */ +#include "PHY/TOOLS/nr_phy_scope.h" #include #include "executables/softmodem-common.h" #include "executables/thread-common.h" diff --git a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c index e4083863f0..ab7c2b9091 100644 --- a/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c +++ b/openair1/PHY/LTE_UE_TRANSPORT/prach_ue.c @@ -55,7 +55,7 @@ int32_t generate_prach( PHY_VARS_UE *ue, uint8_t eNB_id, uint8_t subframe, uint1 uint8_t preamble_index = ue->prach_resources[eNB_id]->ra_PreambleIndex; uint8_t tdd_mapindex = ue->prach_resources[eNB_id]->ra_TDD_map_index; int16_t *prachF = ue->prach_vars[eNB_id]->prachF; - static int16_t prach_tmp[45600*2] __attribute__((aligned(32))); + static int16_t prach_tmp[45600*4] __attribute__((aligned(32))); int16_t *prach = prach_tmp; int16_t *prach2; int16_t amp = ue->prach_vars[eNB_id]->amp; diff --git a/openair1/PHY/NR_TRANSPORT/nr_prach.c b/openair1/PHY/NR_TRANSPORT/nr_prach.c index 2640a86240..d36dd6772b 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_prach.c +++ b/openair1/PHY/NR_TRANSPORT/nr_prach.c @@ -540,7 +540,7 @@ void rx_nr_prach(PHY_VARS_gNB *gNB, uint16_t rootSequenceIndex; int numrootSequenceIndex; uint8_t restricted_set; - uint8_t n_ra_prb; + uint8_t n_ra_prb=0xFF; int16_t *prachF=NULL; int nb_rx; diff --git a/openair1/PHY/TOOLS/readme.md b/openair1/PHY/TOOLS/readme.md new file mode 100644 index 0000000000..f6671acc6d --- /dev/null +++ b/openair1/PHY/TOOLS/readme.md @@ -0,0 +1,12 @@ + +To use the scope, run the xNB or the UE with option "-d" + +Usage in gdb +In gdb, when you break, you can refresh immediatly the scope view by calling the display function. +The first paramter is the graph context, nevertheless we keep the last value for a dirty call in gdb (so you can use '0') + +Example with no variable known +phy_scope_nrUE(0, PHY_vars_UE_g[0][0], 0, 0, 0) + +or +phy_scope_gNB(0, phy_vars_gnb, phy_vars_ru, UE_id) diff --git a/openair1/PHY/phy_vars.h b/openair1/PHY/phy_vars.h index a74d148479..5e2be8bd8f 100644 --- a/openair1/PHY/phy_vars.h +++ b/openair1/PHY/phy_vars.h @@ -59,10 +59,10 @@ const short conjugate2[8]__attribute__((aligned(16))) = {1,-1,1,-1,1,-1,1,-1}; unsigned char NB_RU=0; #ifndef OPENAIR2 -unsigned char NB_eNB_INST=0; -uint16_t NB_UE_INST=0; -unsigned char NB_RN_INST=0; -unsigned char NB_INST=0; +//unsigned char NB_eNB_INST=0; +//uint16_t NB_UE_INST=0; +//unsigned char NB_RN_INST=0; +//unsigned char NB_INST=0; #endif int number_of_cards; diff --git a/openair1/PHY/phy_vars_nr_ue.h b/openair1/PHY/phy_vars_nr_ue.h index 1843d8d5bc..baa64561f0 100644 --- a/openair1/PHY/phy_vars_nr_ue.h +++ b/openair1/PHY/phy_vars_nr_ue.h @@ -138,4 +138,4 @@ uint8_t scrambling_lut[65536*16] __attribute__((aligned(32))); uint8_t max_ldpc_iterations=4; uint8_t max_turbo_iterations=4; -#endif /*__PHY_VARS_H__ */ +#endif diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 992c908c5d..94e356951a 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -424,7 +424,7 @@ void phy_procedures_gNB_uespec_RX(PHY_VARS_gNB *gNB, int frame_rx, int slot_rx) for (int ULSCH_id=0;ULSCH_idulsch[ULSCH_id][0]; int harq_pid; - int no_sig; + //int no_sig; NR_UL_gNB_HARQ_t *ulsch_harq; if ((ulsch) && diff --git a/openair2/ENB_APP/flexran_agent_extern.h b/openair2/ENB_APP/flexran_agent_extern.h index 5f17cf4841..2a5930e1a8 100644 --- a/openair2/ENB_APP/flexran_agent_extern.h +++ b/openair2/ENB_APP/flexran_agent_extern.h @@ -44,8 +44,6 @@ AGENT_PHY_xface *flexran_agent_get_phy_xface(mid_t mod_id); extern AGENT_MAC_xface *agent_mac_xface[NUM_MAX_ENB]; #define flexran_agent_get_mac_xface(mod_id) (agent_mac_xface[mod_id]) -/* Control module interface for the communication of the RRC Control Module with the agent */ - /* Control module interface for the communication of the RRC Control Module with the agent */ // AGENT_RRC_xface *flexran_agent_get_rrc_xface(mid_t mod_id); extern AGENT_RRC_xface *agent_rrc_xface[NUM_MAX_ENB]; diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c index 56ae14f98b..840aafa943 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ra_procedures.c @@ -360,7 +360,7 @@ uint8_t nr_ue_get_rach(NR_PRACH_RESOURCES_t *prach_resources, uint8_t sdu_lcids[NB_RB_MAX] = {0}; uint16_t sdu_lengths[NB_RB_MAX] = {0}; - int TBS_bytes = 848, header_length_total, num_sdus, offset, preambleTransMax, mac_ce_len; + int TBS_bytes = 848, header_length_total=0, num_sdus, offset, preambleTransMax, mac_ce_len; AssertFatal(CC_id == 0,"Transmission on secondary CCs is not supported yet\n"); diff --git a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c index c72e7d4130..1d3c280f0e 100644 --- a/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c +++ b/targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c @@ -288,7 +288,7 @@ int ethernet_tune(openair0_device *device, /******************* interface level options *************************/ case MTU_SIZE: /* change MTU of the eth interface */ ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); + strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)-1); ifr.ifr_mtu =value; if (ioctl(eth->sockfdd,SIOCSIFMTU,(caddr_t)&ifr) < 0 ) perror ("[ETHERNET] Can't set the MTU"); @@ -298,7 +298,7 @@ int ethernet_tune(openair0_device *device, case TX_Q_LEN: /* change TX queue length of eth interface */ ifr.ifr_addr.sa_family = AF_INET; - strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)); + strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name)-1); ifr.ifr_qlen =value; if (ioctl(eth->sockfdd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 ) perror ("[ETHERNET] Can't set the txqueuelen"); diff --git a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp index 1377086e8f..6e94717a6f 100644 --- a/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp +++ b/targets/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp @@ -976,7 +976,6 @@ extern "C" { double usrp_master_clock; if (device_adds[0].get("type") == "b200") { - printf("Found USRP b200\n"); device->type = USRP_B200_DEV; usrp_master_clock = 30.72e6; args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock); diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index b7b435f2d9..9f9e316da8 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -148,15 +148,18 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { // Legacy changes directlty the variable channel_model->path_loss_dB place to place // while calling new_channel_desc_scm() with path losses = 0 static bool init_done=false; + if (!init_done) { uint64_t rand; FILE *h=fopen("/dev/random","r"); - fread(&rand,sizeof(rand),1,h); + if ( 1 != fread(&rand,sizeof(rand),1,h) ) + LOG_W(HW, "Simulator can't read /dev/random\n"); fclose(h); randominit(rand); tableNor(rand); init_done=true; } + ptr->channel_model=new_channel_desc_scm(bridge->tx_num_channels,bridge->rx_num_channels, bridge->channelmod, bridge->sample_rate, @@ -379,6 +382,7 @@ static int rfsimulator_write_internal(rfsimulator_state_t *t, openair0_timestamp if (t->lastWroteTS > timestamp+nsamps) LOG_E(HW,"Not supported to send Tx out of order (same in USRP) %lu, %lu\n", t->lastWroteTS, timestamp); + t->lastWroteTS=timestamp+nsamps; if (!alreadyLocked) @@ -480,6 +484,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi b->trashingPacket=true; } else if ( b->lastReceivedTS < b->th.timestamp) { int nbAnt= b->th.nbAnt; + if ( b->th.timestamp-b->lastReceivedTS < CirSize ) { for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ ) { for (int a=0; a < nbAnt; a++) { @@ -490,8 +495,10 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi } else { memset(b->circularBuf, 0, sampleToByte(CirSize,1)); } + if (b->lastReceivedTS != 0 && b->th.timestamp-b->lastReceivedTS > 50 ) LOG_W(HW,"UEsock: %d gap of: %ld in reception\n", fd, b->th.timestamp-b->lastReceivedTS ); + b->lastReceivedTS=b->th.timestamp; } else if ( b->lastReceivedTS > b->th.timestamp && b->th.size == 1 ) { @@ -510,7 +517,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi LOG_E(HW,"UEsock: %d Tx/Rx shift too large Tx:%lu, Rx:%lu\n", fd, t->lastWroteTS, b->lastReceivedTS); pthread_mutex_unlock(&Sockmutex); - b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize]; + b->transferPtr=(char *)&b->circularBuf[(b->lastReceivedTS*b->th.nbAnt)%CirSize]; b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt); } @@ -653,6 +660,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo else { // no channel modeling sample_t *out=(sample_t *)samplesVoid[a]; const int64_t base=t->nextTimestamp*nbAnt+a; + for ( int i=0; i < nsamps; i++ ) { const int idx=(i*nbAnt+base)%CirSize; out[i].r+=ptr->circularBuf[idx].r; From 7eb2ab66c56cdec882c07ee194b001959b6e265d Mon Sep 17 00:00:00 2001 From: frtabu Date: Tue, 28 Jul 2020 01:33:16 +0200 Subject: [PATCH 114/171] add telnet commands to show and modify channel simulation parameters --- cmake_targets/CMakeLists.txt | 4 +- cmake_targets/build_oai | 2 +- executables/nr-softmodem.c | 2 +- executables/nr-uesoftmodem.c | 5 +- openair1/PHY/TOOLS/nr_phy_scope.c | 16 ++- openair1/SIMULATION/TOOLS/random_channel.c | 123 +++++++++++++++++++-- openair1/SIMULATION/TOOLS/sim.h | 9 +- targets/ARCH/rfsimulator/simulator.c | 12 +- 8 files changed, 148 insertions(+), 25 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index d5b90d3454..92b6b64f0f 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2473,8 +2473,8 @@ add_library(uescope MODULE ${XFORMS_SOURCE} ${XFORMS_SOURCE_SOFTMODEM} ${XFORMS_ target_link_libraries(enbscope ${XFORMS_LIBRARIES}) target_link_libraries(uescope ${XFORMS_LIBRARIES}) -add_library(gnbscope MODULE ${XFORMS_SOURCE_NR}) -target_link_libraries(gnbscope ${XFORMS_LIBRARIES}) +add_library(nrscope MODULE ${XFORMS_SOURCE_NR}) +target_link_libraries(nrscope ${XFORMS_LIBRARIES}) add_library(rfsimulator MODULE diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 88b8811575..e2753d9248 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -67,7 +67,7 @@ UE_TIMING_TRACE="False" USRP_REC_PLAY="False" BUILD_ECLIPSE=0 NR="False" -OPTIONAL_LIBRARIES="telnetsrv enbscope uescope msc" +OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope msc" trap handle_ctrl_c INT function print_help() { diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index 8f68485d29..95d57a535a 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -968,7 +968,7 @@ if(!IS_SOFTMODEM_NOS1) p.argv=argv; p.gNB=RC.gNB[0]; p.ru=RC.ru[0]; - load_softscope("gnb",&p); + load_softscope("nr",&p); } if (nfapi_mode != 1 && nfapi_mode != 2) { diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index b36a041a70..64cbb9495c 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -152,9 +152,6 @@ char ref[128] = "internal"; char channels[128] = "0"; -static char *parallel_config = NULL; -static char *worker_config = NULL; - int rx_input_level_dBm; //static int online_log_messages=0; @@ -764,7 +761,7 @@ int main( int argc, char **argv ) { mlockall(MCL_CURRENT | MCL_FUTURE); if(IS_SOFTMODEM_DOFORMS) { - load_softscope("gnb",PHY_vars_UE_g[0][0]); + load_softscope("nr",PHY_vars_UE_g[0][0]); } number_of_cards = 1; diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index fa86f690b2..5aff1ac48a 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -26,6 +26,7 @@ #include #include "nr_phy_scope.h" #include "executables/nr-softmodem-common.h" +#include "executables/softmodem-common.h" #include #define TPUT_WINDOW_LENGTH 100 @@ -416,7 +417,7 @@ static void *scope_thread_gNB(void *arg) { return NULL; } -void gnbscope_autoinit(scopeParms_t *p) { +void gNBinitScope(scopeParms_t *p) { static scopeParms_t parms; memcpy(&parms,p,sizeof(parms)); pthread_t forms_thread; @@ -763,11 +764,20 @@ static void *nrUEscopeThread(void *arg) { pthread_exit((void *)arg); } -void nruescope_autoinit(PHY_VARS_NR_UE *ue) { +void nrUEinitScope(PHY_VARS_NR_UE *ue) { pthread_t forms_thread; threadCreate(&forms_thread, nrUEscopeThread, ue, "scope", -1, OAI_PRIORITY_RT_LOW); } + +void nrscope_autoinit(void *dataptr) { + AssertFatal( (IS_SOFTMODEM_GNB_BIT||IS_SOFTMODEM_5GUE_BIT),"Scope cannot find NRUE or GNB context"); + + if (IS_SOFTMODEM_GNB_BIT) + gNBinitScope(dataptr); + else + nrUEinitScope(dataptr); +} // Kept to put back the functionality soon #if 0 //FD_stats_form *form_stats=NULL,*form_stats_l2=NULL; @@ -795,6 +805,8 @@ static void reset_stats_gNB(FL_OBJECT *button, } } + + static FD_stats_form *create_form_stats_form(int ID) { FL_OBJECT *obj; FD_stats_form *fdui = calloc(( sizeof *fdui ),1); diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 41d8551e75..0cc0ba5501 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -45,8 +45,10 @@ static mapping channelmod_names[] = { }; static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt); static telnetshell_cmddef_t channelmod_cmdarray[] = { - {"show","",channelmod_show_cmd}, + {"show","",channelmod_show_cmd}, + {"modify"," ",channelmod_modify_cmd}, {"","",NULL}, }; @@ -56,7 +58,8 @@ static telnetshell_vardef_t channelmod_vardef[] = { static double snr_dB=25; static double sinr_dB=0; - +static unsigned int max_chan; +static channel_desc_t** defined_channels; void fill_channel_desc(channel_desc_t *chan_desc, uint8_t nb_tx, uint8_t nb_rx, @@ -281,10 +284,22 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, int32_t channel_offset, double path_loss_dB) { channel_desc_t *chan_desc = (channel_desc_t *)malloc(sizeof(channel_desc_t)); + for(int i=0; ichan_idx=i; + break; + } + else { + AssertFatal(i<(max_chan-1), + "No more channel descriptors available, increase channelmod.max_chan parameter above %u\n",max_chan); + } + } uint16_t i,j; double sum_amps; double aoa,ricean_factor,Td,maxDoppler; int channel_length,nb_taps; + chan_desc->modelid = channel_model; chan_desc->nb_tx = nb_tx; chan_desc->nb_rx = nb_rx; chan_desc->sampling_rate = sampling_rate; @@ -1295,6 +1310,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, void free_channel_desc_scm(channel_desc_t *ch) { // Must be made cleanly, a lot of leaks... + defined_channels[ch->chan_idx]=NULL; free(ch); } @@ -1408,11 +1424,11 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { desc->ch[aarx+(aatx*desc->nb_rx)][k].y = 0.0; for (l=0; lnb_taps; l++) { - if ((k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET) == 0) + if ((k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset) == 0) s = 1.0; else - s = sin(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET))/ - (M_PI*(k - (desc->delays[l]*desc->sampling_rate) - NB_SAMPLES_CHANNEL_OFFSET)); + s = sin(M_PI*(k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset))/ + (M_PI*(k - (desc->delays[l]*desc->sampling_rate) - desc->channel_offset)); desc->ch[aarx+(aatx*desc->nb_rx)][k].x += s*desc->a[l][aarx+(aatx*desc->nb_rx)].x; desc->ch[aarx+(aatx*desc->nb_rx)][k].y += s*desc->a[l][aarx+(aatx*desc->nb_rx)].y; @@ -1491,13 +1507,99 @@ double N_RB2channel_bandwidth(uint16_t N_RB) { return(channel_bandwidth); } +static void display_channelmodel_help( telnet_printfunc_t prnt) { + +} + + +static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) { + prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate); + prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n", + cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No")); + prnt("max Doppler: %lf path loss: %lf rchannel offset: %i forget factor; %lf\n", + cd->max_Doppler, cd->path_loss_dB, cd->channel_offset, cd->forgetting_factor); + prnt("Initial phase: %lf nb_path: %i \n", + cd->ip, cd->nb_paths); + for (int i=0; inb_taps ; i++) { + prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]); + } +} + static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { - for(int i=0; channelmod_names[i].name != NULL ; i++) { - prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i )); - } + char *subcmd=NULL; + int s = sscanf(buff,"%ms\n",&subcmd); - return 0; + if (s>0) { + if ( strcmp(subcmd,"predef") == 0) { + for (int i=0; channelmod_names[i].name != NULL ; i++) { + prnt(" %i %s\n", i, map_int_to_str(channelmod_names,i )); + } + } else if ( strcmp(subcmd,"current") == 0) { + for (int i=0; i < max_chan ; i++) { + if (defined_channels[i] != NULL) { + prnt("model %i %s: \n----------------\n", i, map_int_to_str(channelmod_names,defined_channels[i]->modelid)); + display_channelmodel(defined_channels[i],debug,prnt); + } + } + } else { + display_channelmodel_help(prnt); + } + free(subcmd); + } + return CMDSTATUS_FOUND; +} + + + +static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) { + char *param=NULL, *value=NULL; + int cd_id= -1; + int s = sscanf(buff,"%i %ms %ms \n",&cd_id,¶m, &value); + if (cd_id<0 || cd_id >= max_chan) { + prnt("ERROR, %i: Channel model id outof range (0-%i)\n",cd_id,max_chan-1); + return CMDSTATUS_FOUND; + } + if (defined_channels[cd_id]==NULL) { + prnt("ERROR, %i: Channel model has not been set\n",cd_id); + return CMDSTATUS_FOUND; + } + + if (s==3) { + if ( strcmp(param,"riceanf") == 0) { + double dbl = atof(value); + if (dbl <0 || dbl > 1) + prnt("ricean factor range: 0 to 1, %lf is outof range\n",dbl); + else + defined_channels[cd_id]->ricean_factor=dbl; + } else if ( strcmp(param,"aoa") == 0) { + double dbl = atof(value); + if (dbl <0 || dbl >6.28) + prnt("angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl); + else + defined_channels[cd_id]->aoa=dbl; + } else if ( strcmp(param,"ploss") == 0) { + double dbl = atof(value); + defined_channels[cd_id]->path_loss_dB=dbl; + } else if ( strcmp(param,"offset") == 0) { + int i = atoi(value); + defined_channels[cd_id]->channel_offset=i; + } else if ( strcmp(param,"forgetf") == 0) { + double dbl = atof(value); + if (dbl <0 || dbl > 1) + prnt("forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl); + else + defined_channels[cd_id]->forgetting_factor=dbl; + } else { + + } + display_channelmodel(defined_channels[cd_id],debug,prnt); + free(param); + free(value); + + } + + return CMDSTATUS_FOUND; } int modelid_fromname(char *modelname) { @@ -1519,6 +1621,9 @@ void init_channelmod(void) { paramdef_t channelmod_params[] = CHANNELMOD_PARAMS_DESC; int ret = config_get( channelmod_params,sizeof(channelmod_params)/sizeof(paramdef_t),CHANNELMOD_SECTION); AssertFatal(ret >= 0, "configuration couldn't be performed"); + defined_channels=calloc(max_chan,sizeof( channel_desc_t*)); + AssertFatal(defined_channels!=NULL, "couldn't allocate %u channel descriptors\n",max_chan); + /* look for telnet server, if it is loaded, add the channel modeling commands to it */ add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 6071e1e743..2e067e4ae8 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -92,6 +92,10 @@ typedef struct { time_stats_t interp_time; time_stats_t interp_freq; time_stats_t convolution; + /// index in the channel descriptors array + unsigned int chan_idx; + /// id of the channel modeling algorithm + int modelid; } channel_desc_t; typedef struct { @@ -214,8 +218,9 @@ typedef enum { #define CONFIG_HLP_SNR "Set average SNR in dB (for --siml1 option)\n" #define CHANNELMOD_SECTION "channelmod" #define CHANNELMOD_PARAMS_DESC { \ - {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB , defdblval:25, TYPE_DOUBLE, 0},\ - {"sinr_dB", NULL , 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\ + {"s" , CONFIG_HLP_SNR, PARAMFLAG_CMDLINE_NOPREFIXENABLED, dblptr:&snr_dB, defdblval:25, TYPE_DOUBLE, 0},\ + {"sinr_dB", NULL, 0 , dblptr:&sinr_dB, defdblval:0 , TYPE_DOUBLE, 0},\ + {"max_chan, CONFIG_HLP_MAX_CHAN", 0, uptr:&max_chan, defintval:10, TYPE_UINT, 0},\ } #include "platform_constants.h" diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index b7b435f2d9..ff53ca8c46 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -78,9 +78,11 @@ extern RAN_CONTEXT_t RC; #define RFSIMULATOR_PARAMS_DESC {\ {"serveraddr", "\n", 0, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\ {"serverport", "\n", 0, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\ - {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0},\ + {RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\ {"IQfile", "\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ - {"modelname", "\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 }\ + {"modelname", "\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ + {"ploss", "\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ + {"forgetfact", "\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 }\ }; pthread_mutex_t Sockmutex; @@ -114,6 +116,8 @@ typedef struct { double sample_rate; double tx_bw; int channelmod; + double chan_pathloss; + double chan_forgetfact; } rfsimulator_state_t; @@ -161,9 +165,9 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { bridge->channelmod, bridge->sample_rate, bridge->tx_bw, - 0.0, // forgetting_factor + bridge->chan_forgetfact, // forgetting_factor 0, // maybe used for TA - 0); // path_loss in dB + bridge->chan_pathloss); // path_loss in dB random_channel(ptr->channel_model,false); } } From 828bab2fd6bfb619c169bae7cb68fd3e16968f3f Mon Sep 17 00:00:00 2001 From: "dong.zhanyi" Date: Tue, 28 Jul 2020 07:34:05 +0800 Subject: [PATCH 115/171] fixed the bug no supporting CellId more than 256 --- nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h index fea64e3f3e..c8624e9e91 100644 --- a/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h +++ b/nfapi/open-nFAPI/nfapi/public_inc/nfapi_nr_interface_scf.h @@ -364,7 +364,7 @@ typedef struct //table 3-22 typedef struct { - nfapi_uint8_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007 + nfapi_uint16_tlv_t phy_cell_id;//Physical Cell ID, 𝑁_{𝐼𝐷}^{𝑐𝑒𝑙𝑙} [38.211, sec 7.4.2.1] Value: 0 ->1007 nfapi_uint8_tlv_t frame_duplex_type;//Frame duplex type Value: 0 = FDD 1 = TDD } nfapi_nr_cell_config_t; From eceb1ed21f26567582cc14730ebc5d0434228571 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Tue, 28 Jul 2020 10:40:15 +0200 Subject: [PATCH 116/171] fixed air_interface variable for ocp-enb option --- ci-scripts/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 4ea2884c3b..bb4a87099d 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3160,7 +3160,7 @@ def GetParametersFromXML(action): elif (air_interface.lower() in ['nr','lte']): CiTestObj.air_interface = air_interface.lower() +'-softmodem' else : - CiTestObj.air_interface = air_interface.lower() +'ocp-enb' + CiTestObj.air_interface = 'ocp-enb' RAN.air_interface(CiTestObj.air_interface) if action == 'Terminate_eNB': @@ -3178,7 +3178,7 @@ def GetParametersFromXML(action): elif (air_interface.lower() in ['nr','lte']): CiTestObj.air_interface = air_interface.lower() +'-softmodem' else : - CiTestObj.air_interface = air_interface.lower() +'ocp-enb' + CiTestObj.air_interface = 'ocp-enb' RAN.air_interface=CiTestObj.air_interface if action == 'Attach_UE': @@ -3216,7 +3216,7 @@ def GetParametersFromXML(action): elif (air_interface.lower() in ['nr','lte']): CiTestObj.air_interface = air_interface.lower() +'-softmodem' else : - CiTestObj.air_interface = air_interface.lower() +'ocp-enb' + CiTestObj.air_interface = 'ocp-enb' RAN.air_interface=CiTestObj.air_interface if action == 'Terminate_OAI_UE': From 8c9501b6a691d458f8a57ae335e528af814d2276 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Tue, 28 Jul 2020 14:17:27 +0200 Subject: [PATCH 117/171] fixing args_parse function arguments list --- ci-scripts/args_parse.py | 4 ++-- ci-scripts/main.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py index a36f619ee2..b51fbc500d 100644 --- a/ci-scripts/args_parse.py +++ b/ci-scripts/args_parse.py @@ -41,7 +41,7 @@ import yaml #----------------------------------------------------------- -def ArgsParse(argvs,CiTestObj,RAN,HTML,ldpc,HELP): +def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): py_param_file_present = False @@ -226,4 +226,4 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,ldpc,HELP): HELP.GenericHelp(CONST.Version) sys.exit('Invalid Parameter: ' + myArgv) - return py_param_file_present, py_params, mode \ No newline at end of file + return py_param_file_present, py_params, mode diff --git a/ci-scripts/main.py b/ci-scripts/main.py index bb4a87099d..693406efff 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3332,7 +3332,7 @@ ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU b #----------------------------------------------------------- import args_parse -py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,ldpc,HELP) +py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,HELP) #argvs = sys.argv #py_param_file_present = False From d3b415d6ed14d60d3dad6d266d8f90179d964e2a Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Tue, 28 Jul 2020 14:22:46 +0200 Subject: [PATCH 118/171] commented out printing of object attributes (debug) --- ci-scripts/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 693406efff..5b1b31fafd 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3525,10 +3525,10 @@ if py_param_file_present == True: AssignParams(py_params) #for debug -print(RAN.__dict__) -print(CiTestObj.__dict__) -print(HTML.__dict__) -print(ldpc.__dict__) +#print(RAN.__dict__) +#print(CiTestObj.__dict__) +#print(HTML.__dict__) +#print(ldpc.__dict__) #for debug From 31a0d28ad9bc3ef2d7024b7c16bed49b20b96623 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 28 Jul 2020 15:22:46 +0200 Subject: [PATCH 119/171] CI: fix a few typos Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 13 +++++++++---- ci-scripts/ran.py | 2 +- cmake_targets/build_oai | 2 +- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 5b1b31fafd..21676719a0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -1,4 +1,4 @@ - +#/* # * 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. @@ -1598,7 +1598,7 @@ class OaiCiTest(): return result def Iperf_analyzeV2TCPOutput(self, lock, UE_IPAddress, device_id, statusQueue, iperf_real_options): - SSH.command('awk -f /tmp/tcp_iperf_stats.awk /tmp/CI-eNB/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) + SSH.command('awk -f /tmp/tcp_iperf_stats.awk ' + EPC.SourceCodePath + '/scripts/iperf_' + self.testCase_id + '_' + device_id + '.log', '\$', 5) result = re.search('Avg Bitrate : (?P[0-9\.]+ Mbits\/sec) Max Bitrate : (?P[0-9\.]+ Mbits\/sec) Min Bitrate : (?P[0-9\.]+ Mbits\/sec)', SSH.getBefore()) if result is not None: avgbitrate = result.group('average') @@ -3161,7 +3161,7 @@ def GetParametersFromXML(action): CiTestObj.air_interface = air_interface.lower() +'-softmodem' else : CiTestObj.air_interface = 'ocp-enb' - RAN.air_interface(CiTestObj.air_interface) + RAN.air_interface=CiTestObj.air_interface if action == 'Terminate_eNB': RAN.eNB_instance=test.findtext('eNB_instance') @@ -3304,7 +3304,12 @@ def receive_signal(signum, frame): #loading xml action list from yaml import yaml -with open('xml_class_list.yml','r') as file: +xml_class_list_file='' +if (os.path.isfile('xml_class_list.yml')): + xml_class_list_file='xml_class_list.yml' +if (os.path.isfile('ci-scripts/xml_class_list.yml')): + xml_class_list_file='ci-scripts/xml_class_list.yml' +with open(xml_class_list_file,'r') as file: # The FullLoader parameter handles the conversion from YAML # scalar values to Python the dictionary format xml_class_list = yaml.load(file,Loader=yaml.FullLoader) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 23a004e4ce..b1d26b8af3 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -536,7 +536,7 @@ class RANManagement(): # Make a copy and adapt to EPC / eNB IP addresses mySSH.command('cp ' + full_config_file + ' ' + ci_full_config_file, '\$', 5) if self.epcObj is not None: - localMmeIpAddr = self.epcObj.GetMmeIPAddress() + localMmeIpAddr = self.epcObj.MmeIPAddress mySSH.command('sed -i -e \'s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); diff --git a/cmake_targets/build_oai b/cmake_targets/build_oai index 469c840b4d..4c8399f4a9 100755 --- a/cmake_targets/build_oai +++ b/cmake_targets/build_oai @@ -830,7 +830,7 @@ function main() { #################################################### # Build RF device and transport protocol libraries # #################################################### - if [ "$eNB" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then + if [ "$eNB" = "1" -o "$eNBocp" = "1" -o "$UE" = "1" -o "$gNB" = "1" -o "$nrUE" = "1" -o "$HWLAT" = "1" ] ; then # build RF device libraries if [ "$HW" != "None" ] ; then From 5dd3e3353d028b2ff54fd3d2f61a734dd2be7511 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 28 Jul 2020 15:25:00 +0200 Subject: [PATCH 120/171] CI: using ninja for OCP build Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_ocp_usrp210_build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml index 8110c7f1b6..33a0fc205e 100644 --- a/ci-scripts/xml_files/enb_ocp_usrp210_build.xml +++ b/ci-scripts/xml_files/enb_ocp_usrp210_build.xml @@ -32,7 +32,7 @@ Build_eNB Build eNB OCP (USRP) - -w USRP -c --eNBocp + -w USRP -c --eNBocp --ninja From b8edd71244886c4293d90615ea73bd3ea2b96c84 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 28 Jul 2020 16:03:28 +0200 Subject: [PATCH 121/171] CI: adding retries on OCP test Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml index 5326973cc2..854fb8cb19 100644 --- a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml @@ -24,6 +24,7 @@ test-05-tm1 Test-05MHz-TM1 tasks + 4 030201 040101 From 5c2df00101cb0bdf83b3d04f373fb93588bd77e9 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 28 Jul 2020 16:28:36 +0200 Subject: [PATCH 122/171] CI: fix terminate Signed-off-by: Raphael Defosseux --- ci-scripts/ran.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index b1d26b8af3..833e2784d1 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -710,12 +710,12 @@ class RANManagement(): result = re.search('(-softmodem|ocp)', mySSH.getBefore()) if result is not None: mySSH.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) - mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem .ocp-enb || true', '\$', 5) + mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem ocp-enb || true', '\$', 5) time.sleep(10) mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5) result = re.search('(-softmodem|ocp)', mySSH.getBefore()) if result is not None: - mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem .ocp-enb || true', '\$', 5) + mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGKILL -r .*-softmodem ocp-enb || true', '\$', 5) time.sleep(5) mySSH.command('rm -f my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.close() From ca21ad8b365fc6bcaf0606fa86a859ae160cd2a4 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Tue, 28 Jul 2020 17:02:28 +0200 Subject: [PATCH 123/171] cleaned-removed commented-out legacy code --- ci-scripts/epc.py | 32 -------- ci-scripts/html.py | 55 ------------- ci-scripts/main.py | 187 --------------------------------------------- ci-scripts/ran.py | 137 --------------------------------- 4 files changed, 411 deletions(-) diff --git a/ci-scripts/epc.py b/ci-scripts/epc.py index 14bbcd0540..25bbbba091 100644 --- a/ci-scripts/epc.py +++ b/ci-scripts/epc.py @@ -66,38 +66,6 @@ class EPCManagement(): self.MmeIPAddress = '' self.containerPrefix = 'prod' -#----------------------------------------------------------- -# Setter and Getters on Public Members -#----------------------------------------------------------- - -# def SetIPAddress(self, ipaddress): -# self.IPAddress = ipaddress -# def GetIPAddress(self): -# return self.IPAddress -# def SetUserName(self, username): -# self.UserName = username -# def GetUserName(self): -# return self.UserName -# def SetPassword(self, password): -# self.Password = password -# def GetPassword(self): -# return self.Password -# def SetSourceCodePath(self, sourcecodepath): -# self.SourceCodePath = sourcecodepath -# def GetSourceCodePath(self): -# return self.SourceCodePath -# def SetType(self, kind): -# self.Type = kind -# def GetType(self): -# return self.Type -# def SetHtmlObj(self, obj): -# self.htmlObj = obj -# def SetTestCase_id(self, idx): -# self.testCase_id = idx -# def GetMmeIPAddress(self): -# return self.MmeIPAddress -# def SetContainerPrefix(self, prefix): -# self.containerPrefix = prefix #----------------------------------------------------------- # EPC management functions diff --git a/ci-scripts/html.py b/ci-scripts/html.py index b7b3c31fad..8f2d38cced 100644 --- a/ci-scripts/html.py +++ b/ci-scripts/html.py @@ -90,61 +90,6 @@ class HTMLManagement(): self.htmlUEConnected = 1 -# def SethtmlUEFailureMsg(self,huefa): -# self.htmlUEFailureMsg = huefa -# def GethtmlUEFailureMsg(self): -# return self.htmlUEFailureMsg -# def SetHmleNBFailureMsg(self, msg): -# self.htmleNBFailureMsg = msg -# def Setdesc(self, dsc): -# self.desc = dsc -# def SetstartTime(self, sttime): -# self.startTime = sttime -# def SettestCase_id(self, tcid): -# self.testCase_id = tcid -# def GettestCase_id(self): -# return self.testCase_id -# def SetranRepository(self, repository): -# self.ranRepository = repository -# def SetranAllowMerge(self, merge): -# self.ranAllowMerge = merge -# def SetranBranch(self, branch): -# self.ranBranch = branch -# def SetranCommitID(self, commitid): -# self.ranCommitID = commitid -# def SetranTargetBranch(self, tbranch): -# self.ranTargetBranch = tbranch -# def SethtmlNb_Smartphones(self, nbUEs): -# self.htmlNb_Smartphones = nbUEs -# def SethtmlNb_CATM_Modules(self, nbUEs): -# self.htmlNb_CATM_Modules = nbUEs -# def SetnbTestXMLfiles(self, nb): -# self.nbTestXMLfiles = nb -# def GetnbTestXMLfiles(self): -# return self.nbTestXMLfiles -# def SettestXMLfiles(self, xmlFile): -# self.testXMLfiles.append(xmlFile) -# def SethtmlTabRefs(self, tabRef): -# self.htmlTabRefs.append(tabRef) -# def SethtmlTabNames(self, tabName): -# self.htmlTabNames.append(tabName) -# def SethtmlTabIcons(self, tabIcon): -# self.htmlTabIcons.append(tabIcon) -# def SetOsVersion(self, version, idx): -# self.OsVersion[idx] = version -# def SetKernelVersion(self, version, idx): -# self.KernelVersion[idx] = version -# def SetUhdVersion(self, version, idx): -# self.UhdVersion[idx] = version -# def SetUsrpBoard(self, version, idx): -# self.UsrpBoard[idx] = version -# def SetCpuNb(self, nb, idx): -# self.CpuNb[idx] = nb -# def SetCpuModel(self, model, idx): -# self.CpuModel[idx] = model -# def SetCpuMHz(self, freq, idx): -# self.CpuMHz[idx] = freq - #----------------------------------------------------------- # HTML structure creation functions diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 21676719a0..5b9b98988b 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3084,12 +3084,6 @@ class OaiCiTest(): def CheckClassValidity(xml_class_list,action,id): -# if action !='COTS_UE_Airplane' and action!='Build_PhySim' and action!='Run_PhySim' and action != 'Build_eNB' and action != 'WaitEndBuild_eNB' and action != 'Initialize_eNB' and action != 'Terminate_eNB' and -# action != 'Initialize_UE' and action != 'Terminate_UE' and action != 'Attach_UE' and action != 'Detach_UE' and action != 'Build_OAI_UE' and action != 'Initialize_OAI_UE' and action != 'Terminate_OAI_UE' and -# action != 'DataDisable_UE' and action != 'DataEnable_UE' and action != 'CheckStatusUE' and action != 'Ping' and action != 'Iperf' and action != 'Reboot_UE' and action != 'Initialize_FlexranCtrl' and -# action != 'Terminate_FlexranCtrl' and action != 'Initialize_HSS' and action != 'Terminate_HSS' and action != 'Initialize_MME' and action != 'Terminate_MME' and action != 'Initialize_SPGW' and -# action != 'Terminate_SPGW' and action != 'Initialize_CatM_module' and action != 'Terminate_CatM_module' and action != 'Attach_CatM_module' and action != 'Detach_CatM_module' and -# action != 'Ping_CatM_module' and action != 'IdleSleep' and action != 'Perform_X2_Handover': if action not in xml_class_list: logging.debug('ERROR: test-case ' + id + ' has unlisted class ' + action + ' ##CHECK xml_class_list.yml') resp=False @@ -3339,187 +3333,6 @@ ldpc=cls_physim.PhySim() #create an instance for LDPC test using GPU or CPU b import args_parse py_param_file_present, py_params, mode = args_parse.ArgsParse(sys.argv,CiTestObj,RAN,HTML,EPC,ldpc,HELP) -#argvs = sys.argv -#py_param_file_present = False -# -#while len(argvs) > 1: -# myArgv = argvs.pop(1) # 0th is this file's name -# -# #--help -# if re.match('^\-\-help$', myArgv, re.IGNORECASE): -# HELP.GenericHelp(CONST.Version) -# sys.exit(0) -# -# #--apply= as parameters file, to replace inline parameters -# elif re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-Apply=(.+)$', myArgv, re.IGNORECASE) -# py_params_file = matchReg.group(1) -# with open(py_params_file,'r') as file: -# # The FullLoader parameter handles the conversion from YAML -# # scalar values to Python dictionary format -# py_params = yaml.load(file,Loader=yaml.FullLoader) -# py_param_file_present = True #to be removed once validated -# #AssignParams(py_params) #to be uncommented once validated -# -# #consider inline parameters -# elif re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-mode=(.+)$', myArgv, re.IGNORECASE) -# mode = matchReg.group(1) -# elif re.match('^\-\-eNBRepository=(.+)$|^\-\-ranRepository(.+)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBRepository=(.+)$', myArgv, re.IGNORECASE) -# else: -# matchReg = re.match('^\-\-ranRepository=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.ranRepository = matchReg.group(1) -# RAN.ranRepository=matchReg.group(1) -# HTML.ranRepository=matchReg.group(1) -# ldpc.ranRepository=matchReg.group(1) -# elif re.match('^\-\-eNB_AllowMerge=(.+)$|^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB_AllowMerge=(.+)$', myArgv, re.IGNORECASE) -# else: -# matchReg = re.match('^\-\-ranAllowMerge=(.+)$', myArgv, re.IGNORECASE) -# doMerge = matchReg.group(1) -# ldpc.ranAllowMerge=matchReg.group(1) -# if ((doMerge == 'true') or (doMerge == 'True')): -# CiTestObj.ranAllowMerge = True -# RAN.ranAllowMerge=True -# HTML.ranAllowMerge=True -# elif re.match('^\-\-eNBBranch=(.+)$|^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBBranch=(.+)$', myArgv, re.IGNORECASE) -# else: -# matchReg = re.match('^\-\-ranBranch=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.ranBranch = matchReg.group(1) -# RAN.ranBranch=matchReg.group(1) -# HTML.ranBranch=matchReg.group(1) -# ldpc.ranBranch=matchReg.group(1) -# elif re.match('^\-\-eNBCommitID=(.*)$|^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBCommitID=(.*)$', myArgv, re.IGNORECASE) -# else: -# matchReg = re.match('^\-\-ranCommitID=(.*)$', myArgv, re.IGNORECASE) -# CiTestObj.ranCommitID = matchReg.group(1) -# RAN.ranCommitID=matchReg.group(1) -# HTML.ranCommitID=matchReg.group(1) -# ldpc.ranCommitID=matchReg.group(1) -# elif re.match('^\-\-eNBTargetBranch=(.*)$|^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBTargetBranch=(.*)$', myArgv, re.IGNORECASE) -# else: -# matchReg = re.match('^\-\-ranTargetBranch=(.*)$', myArgv, re.IGNORECASE) -# CiTestObj.ranTargetBranch = matchReg.group(1) -# RAN.ranTargetBranch=matchReg.group(1) -# HTML.ranTargetBranch=matchReg.group(1) -# ldpc.ranTargetBranch=matchReg.group(1) -# elif re.match('^\-\-eNBIPAddress=(.+)$|^\-\-eNB[1-2]IPAddress=(.+)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBIPAddress=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNBIPAddress=matchReg.group(1) -# ldpc.eNBIpAddr=matchReg.group(1) -# elif re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB1IPAddress=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB1IPAddress=matchReg.group(1) -# elif re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB2IPAddress=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB2IPAddress=matchReg.group(1) -# elif re.match('^\-\-eNBUserName=(.+)$|^\-\-eNB[1-2]UserName=(.+)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBUserName=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNBUserName=matchReg.group(1) -# ldpc.eNBUserName=matchReg.group(1) -# elif re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB1UserName=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB1UserName=matchReg.group(1) -# elif re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB2UserName=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB2UserName=matchReg.group(1) -# elif re.match('^\-\-eNBPassword=(.+)$|^\-\-eNB[1-2]Password=(.+)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBPassword=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNBPassword=matchReg.group(1) -# ldpc.eNBPassWord=matchReg.group(1) -# elif re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB1Password=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB1Password=matchReg.group(1) -# elif re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB2Password=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB2Password=matchReg.group(1) -# elif re.match('^\-\-eNBSourceCodePath=(.+)$|^\-\-eNB[1-2]SourceCodePath=(.+)$', myArgv, re.IGNORECASE): -# if re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNBSourceCodePath=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNBSourceCodePath=matchReg.group(1) -# ldpc.eNBSourceCodePath=matchReg.group(1) -# elif re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB1SourceCodePath=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB1SourceCodePath=matchReg.group(1) -# elif re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-eNB2SourceCodePath=(.+)$', myArgv, re.IGNORECASE) -# RAN.eNB2SourceCodePath=matchReg.group(1) -# elif re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-EPCIPAddress=(.+)$', myArgv, re.IGNORECASE) -# EPC.IPAddress=matchReg.group(1) -# elif re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-EPCUserName=(.+)$', myArgv, re.IGNORECASE) -# EPC.UserName=matchReg.group(1) -# elif re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-EPCPassword=(.+)$', myArgv, re.IGNORECASE) -# EPC.Password=matchReg.group(1) -# elif re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-EPCSourceCodePath=(.+)$', myArgv, re.IGNORECASE) -# EPC.SourceCodePath=matchReg.group(1) -# elif re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-EPCType=(.+)$', myArgv, re.IGNORECASE) -# if re.match('OAI', matchReg.group(1), re.IGNORECASE) or re.match('ltebox', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-CUPS', matchReg.group(1), re.IGNORECASE) or re.match('OAI-Rel14-Docker', matchReg.group(1), re.IGNORECASE): -# EPC.Type=matchReg.group(1) -# else: -# sys.exit('Invalid EPC Type: ' + matchReg.group(1) + ' -- (should be OAI or ltebox or OAI-Rel14-CUPS or OAI-Rel14-Docker)') -# elif re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-EPCContainerPrefix=(.+)$', myArgv, re.IGNORECASE) -# EPC.ContainerPrefix=matchReg.group(1) -# elif re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-ADBIPAddress=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.ADBIPAddress = matchReg.group(1) -# elif re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-ADBUserName=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.ADBUserName = matchReg.group(1) -# elif re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-ADBType=(.+)$', myArgv, re.IGNORECASE) -# if re.match('centralized', matchReg.group(1), re.IGNORECASE) or re.match('distributed', matchReg.group(1), re.IGNORECASE): -# if re.match('distributed', matchReg.group(1), re.IGNORECASE): -# CiTestObj.ADBCentralized = False -# else: -# CiTestObj.ADBCentralized = True -# else: -# sys.exit('Invalid ADB Type: ' + matchReg.group(1) + ' -- (should be centralized or distributed)') -# elif re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-ADBPassword=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.ADBPassword = matchReg.group(1) -# elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.testXMLfiles.append(matchReg.group(1)) -# HTML.testXMLfiles=matchReg.group(1) -# HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1 -# elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.UEIPAddress = matchReg.group(1) -# elif re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-UEUserName=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.UEUserName = matchReg.group(1) -# elif re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-UEPassword=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.UEPassword = matchReg.group(1) -# elif re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-UESourceCodePath=(.+)$', myArgv, re.IGNORECASE) -# CiTestObj.UESourceCodePath = matchReg.group(1) -# elif re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE): -# matchReg = re.match('^\-\-finalStatus=(.+)$', myArgv, re.IGNORECASE) -# finalStatus = matchReg.group(1) -# if ((finalStatus == 'true') or (finalStatus == 'True')): -# CiTestObj.finalStatus = True -# else: -# HELP.GenericHelp(CONST.Version) -# sys.exit('Invalid Parameter: ' + myArgv) #----------------------------------------------------------- diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 833e2784d1..39ecb00979 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -93,143 +93,6 @@ class RANManagement(): -#----------------------------------------------------------- -# Setters and Getters on Public members -#----------------------------------------------------------- - -# def SetHtmlObj(self, obj): -# self.htmlObj = obj -# def SetEpcObj(self, obj): -# self.epcObj = obj -# -# def SetflexranCtrlInstalled(self,fxrctin): -# self.flexranCtrlInstalled = fxrctin -# def GetflexranCtrlInstalled(self): -# return self.flexranCtrlInstalled -# def SetflexranCtrlStarted(self,fxrctst): -# self.flexranCtrlStarted = fxrctst -# def GetflexranCtrlStarted(self): -# return self.flexranCtrlStarted -# def SetpStatus(self, pSt): -# self.pStatus = pSt -# def SetranRepository(self, repository): -# self.ranRepository = repository -# def GetranRepository(self): -# return self.ranRepository -# def SetranBranch(self, branch): -# self.ranBranch = branch -# def GetranBranch(self): -# return self.ranBranch -# def SetranCommitID(self, commitid): -# self.ranCommitID = commitid -# def GetranCommitID(self): -# return self.ranCommitID -# def SeteNB_serverId(self, enbsrvid): -# self.eNB_serverId = enbsrvid -# def GeteNB_serverId(self): -# return self.eNB_serverId -# def SeteNBIPAddress(self, enbip): -# self.eNBIPAddress = enbip -# def GeteNBIPAddress(self): -# return self.eNBIPAddress -# def SeteNBUserName(self, enbusr): -# self.eNBUserName = enbusr -# def GeteNBUserName(self): -# return self.eNBUserName -# def SeteNBPassword(self, enbpw): -# self.eNBPassword = enbpw -# def GeteNBPassword(self): -# return self.eNBPassword -# def SeteNBSourceCodePath(self, enbcodepath): -# self.eNBSourceCodePath = enbcodepath -# def GeteNBSourceCodePath(self): -# return self.eNBSourceCodePath -# def SetranAllowMerge(self, merge): -# self.ranAllowMerge = merge -# def GetranAllowMerge(self): -# return self.ranAllowMerge -# def SetranTargetBranch(self, tbranch): -# self.ranTargetBranch = tbranch -# def GetranTargetBranch(self): -# return self.ranTargetBranch -# def SetBuild_eNB_args(self, enbbuildarg): -# self.Build_eNB_args = enbbuildarg -# def GetBuild_eNB_args(self): -# return self.Build_eNB_args -# def SetInitialize_eNB_args(self, initenbarg): -# self.Initialize_eNB_args = initenbarg -# def GetInitialize_eNB_args(self): -# return self.Initialize_eNB_args -# def SetbackgroundBuild(self, bkbuild): -# self.backgroundBuild = bkbuild -# def GetbackgroundBuild(self): -# return self.backgroundBuild -# def SetbackgroundBuildTestId(self, bkbuildid): -# self.backgroundBuildTestId = bkbuildid -# def GetbackgroundBuildTestId(self): -# return self.backgroundBuildTestId -# def SetBuild_eNB_forced_workspace_cleanup(self, fcdwspclean): -# self.Build_eNB_forced_workspace_cleanup = fcdwspclean -# def GetBuild_eNB_forced_workspace_cleanup(self): -# return self.Build_eNB_forced_workspace_cleanup -# def Setair_interface(self, airif): -# self.air_interface = airif -# def Getair_interface(self): -# return self.air_interface -# def SeteNB_instance(self, enbinst): -# self.eNB_instance = enbinst -# def GeteNB_instance(self): -# return self.eNB_instance -# -# def SeteNBLogFile(self, enblog, idx): -# self.eNBLogFiles[idx] = enblog -# def GeteNBLogFile(self, idx): -# return self.eNBLogFiles[idx] -# -# def GeteNBmbmsEnable(self, idx): -# return self.eNBmbmsEnables[idx] -# -# def SeteNB1IPAddress(self,enb1ip): -# self.eNB1IPAddress = enb1ip -# def GeteNB1IPAddress(self): -# return self.eNB1IPAddress -# def SeteNB1UserName(self, enb1usr): -# self.eNB1UserName = enb1usr -# def GeteNB1UserName(self): -# return self.eNB1UserName -# def SeteNB1Password(self, enb1pw): -# self.eNB1Password = enb1pw -# def GeteNB1Password(self): -# return self.eNB1Password -# def SeteNB1SourceCodePath(self, enb1codepath): -# self.eNB1SourceCodePath = enb1codepath -# def GeteNB1SourceCodePath(self): -# return self.eNB1SourceCodePath -# -# def SeteNB2IPAddress(self, enb2ip): -# self.eNB2IPAddress = enb2ip -# def GeteNB2IPAddress(self): -# return self.eNB2IPAddress -# def SeteNB2UserName(self, enb2usr): -# self.eNB2UserName = enb2usr -# def GeteNB2UserName(self): -# return self.eNB2UserName -# def SeteNB2Password(self, enb2pw): -# self.eNB2Password = enb2pw -# def GeteNB2Password(self): -# return self.eNB2Password -# def SeteNB2SourceCodePath(self, enb2codepath): -# self.eNB2SourceCodePath = enb2codepath -# def GeteNB2SourceCodePath(self): -# return self.eNB2SourceCodePath -# -# def SetprematureExit(self, premex): -# self.prematureExit = premex -# def GetprematureExit(self): -# return self.prematureExit - - - #----------------------------------------------------------- # RAN management functions #----------------------------------------------------------- From 71c66ec58320a9124b5ac01f6a71f1aca88defd1 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 28 Jul 2020 17:08:09 +0200 Subject: [PATCH 124/171] CI: fix HTML tab name Signed-off-by: Raphael Defosseux --- ci-scripts/args_parse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/args_parse.py b/ci-scripts/args_parse.py index b51fbc500d..1249f52172 100644 --- a/ci-scripts/args_parse.py +++ b/ci-scripts/args_parse.py @@ -203,7 +203,7 @@ def ArgsParse(argvs,CiTestObj,RAN,HTML,EPC,ldpc,HELP): elif re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-XMLTestFile=(.+)$', myArgv, re.IGNORECASE) CiTestObj.testXMLfiles.append(matchReg.group(1)) - HTML.testXMLfiles=matchReg.group(1) + HTML.testXMLfiles.append(matchReg.group(1)) HTML.nbTestXMLfiles=HTML.nbTestXMLfiles+1 elif re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE): matchReg = re.match('^\-\-UEIPAddress=(.+)$', myArgv, re.IGNORECASE) From f61f9520dba252eae01b7aab690fcf8fe797c28f Mon Sep 17 00:00:00 2001 From: frtabu Date: Tue, 28 Jul 2020 20:08:48 +0200 Subject: [PATCH 125/171] implement queued commands in telnet server --- common/utils/telnetsrv/telnetsrv.c | 21 ++++++++- common/utils/telnetsrv/telnetsrv.h | 16 +++++-- openair1/SIMULATION/TOOLS/random_channel.c | 55 ++++++++++++++-------- targets/ARCH/rfsimulator/simulator.c | 6 ++- 4 files changed, 72 insertions(+), 26 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 06a5d350c7..831d6032c8 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -53,6 +53,7 @@ #include #include "common/utils/load_module_shlib.h" #include "common/config/config_userapi.h" +#include "common/utils/threadPool/thread-pool.h" #include "executables/softmodem-common.h" #include @@ -512,7 +513,17 @@ int process_command(char *buf) { } else { for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) { if (strncasecmp(cmd, telnetparams.CmdParsers[i].cmd[k].cmdname,sizeof(telnetparams.CmdParsers[i].cmd[k].cmdname)) == 0) { - telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf); + if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) { + notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL); + telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg); + cmddata->cmdfunc=telnetparams.CmdParsers[i].cmd[k].cmdfunc; + cmddata->prnt=client_printf; + cmddata->debug=telnetparams.telnetdbg; + cmddata->cmdbuff=strdup(cmdb); + pushNotifiedFIFO(telnetparams.CmdParsers[i].cmd[k].qptr, msg); + } else { + telnetparams.CmdParsers[i].cmd[k].cmdfunc(cmdb, telnetparams.telnetdbg, client_printf); + } rt= CMDSTATUS_FOUND; } } /* for k */ @@ -758,6 +769,7 @@ int telnetsrv_autoinit(void) { */ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd) { int i; + notifiedFIFO_t *afifo=NULL; if( modulename == NULL || var == NULL || cmd == NULL) { fprintf(stderr,"[TELNETSRV] Telnet server, add_telnetcmd: invalid parameters\n"); @@ -769,6 +781,13 @@ int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmdde strncpy(telnetparams.CmdParsers[i].module,modulename,sizeof(telnetparams.CmdParsers[i].module)-1); telnetparams.CmdParsers[i].cmd = cmd; telnetparams.CmdParsers[i].var = var; + if (cmd->cmdflags & TELNETSRV_CMDFLAG_PUSHINTPOOLQ) { + if (afifo == NULL) { + afifo = malloc(sizeof(notifiedFIFO_t)); + initNotifiedFIFO(afifo); + } + cmd->qptr = afifo; + } printf("[TELNETSRV] Telnet server: module %i = %s added to shell\n", i,telnetparams.CmdParsers[i].module); break; diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index debb9f02ec..32ec2b9666 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -54,12 +54,24 @@ typedef void(*telnet_printfunc_t)(const char* format, ...); typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt); +#define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue typedef struct cmddef { char cmdname[TELNET_CMD_MAXSIZE]; char helpstr[TELNET_HELPSTR_SIZE]; cmdfunc_t cmdfunc; + unsigned int cmdflags; + void *qptr; } telnetshell_cmddef_t; +/*----------------------------------------------------------------------------*/ +/* structure used to send a command via a message queue to enable */ +/* executing a command in a thread different from the telnet server thread */ +typedef struct telnetsrv_qmsg { + cmdfunc_t cmdfunc; + telnet_printfunc_t prnt; + int debug; + char *cmdbuff; +} telnetsrv_qmsg_t; /*----------------------------------------------------------------------------*/ /*structure to be used when adding a module to the telnet server */ /* This is the first parameter of the add_telnetcmd function, which can be used */ @@ -111,9 +123,6 @@ typedef struct { } telnetsrv_params_t; - -typedef int(*addcmdfunc_t)(char*, telnetshell_vardef_t*, telnetshell_cmddef_t*); - typedef void(*settelnetmodule_t)(char *name, void *ptr); /*-------------------------------------------------------------------------------------------*/ @@ -133,6 +142,7 @@ VT escape sequence definition, for smarter display.... /*---------------------------------------------------------------------------------------------*/ #define TELNET_ADDCMD_FNAME "add_telnetcmd" +#define TELNET_ADDQUEUEDCMD_FNAME "add_telnetqueuedcmd" typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); #ifdef TELNETSERVERCODE int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 0cc0ba5501..af266a6600 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -46,7 +46,9 @@ static mapping channelmod_names[] = { static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt); static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt); static telnetshell_cmddef_t channelmod_cmdarray[] = { + {"help","",channelmod_print_help}, {"show","",channelmod_show_cmd}, {"modify"," ",channelmod_modify_cmd}, {"","",NULL}, @@ -286,7 +288,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, channel_desc_t *chan_desc = (channel_desc_t *)malloc(sizeof(channel_desc_t)); for(int i=0; ichan_idx=i; break; } @@ -438,7 +440,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } break; - + case EPA: chan_desc->nb_taps = 7; chan_desc->Td = .410; @@ -1504,11 +1506,18 @@ double N_RB2channel_bandwidth(uint16_t N_RB) { LOG_E(PHY,"Unknown N_PRB\n"); return(-1); } - return(channel_bandwidth); -} -static void display_channelmodel_help( telnet_printfunc_t prnt) { +} + +static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt ) { + prnt("channelmod commands can be used to display or modify channel models parameters\n"); + prnt("channelmod show predef: display predefined model algorithms available in oai\n"); + prnt("channelmod show current: display the currently used models in the running executable\n"); + prnt("channelmod modify : set the specified parameters in a current model to the given value\n"); + prnt(" specifies the model, the show current model command can be used to list the current models indexes\n"); + prnt(" can be one of \"riceanf\", \"aoa\", \"randaoa\", \"ploss\", \"offset\", \"forgetf\"\n"); + return CMDSTATUS_FOUND; } @@ -1522,10 +1531,10 @@ static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_ cd->ip, cd->nb_paths); for (int i=0; inb_taps ; i++) { prnt("taps: %i lin. ampli. : %lf delay: %lf \n",i,cd->amps[i], cd->delays[i]); - } + } } - - + + static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { char *subcmd=NULL; int s = sscanf(buff,"%ms\n",&subcmd); @@ -1543,14 +1552,14 @@ static int channelmod_show_cmd(char *buff, int debug, telnet_printfunc_t prnt) { } } } else { - display_channelmodel_help(prnt); + channelmod_print_help(buff, debug, prnt); } free(subcmd); } return CMDSTATUS_FOUND; } - + static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) { char *param=NULL, *value=NULL; @@ -1569,15 +1578,21 @@ static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) if ( strcmp(param,"riceanf") == 0) { double dbl = atof(value); if (dbl <0 || dbl > 1) - prnt("ricean factor range: 0 to 1, %lf is outof range\n",dbl); + prnt("ERROR: ricean factor range: 0 to 1, %lf is outof range\n",dbl); else defined_channels[cd_id]->ricean_factor=dbl; } else if ( strcmp(param,"aoa") == 0) { double dbl = atof(value); if (dbl <0 || dbl >6.28) - prnt("angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl); + prnt("ERROR: angle of arrival range: 0 to 2*Pi, %lf is outof range\n",dbl); else defined_channels[cd_id]->aoa=dbl; + } else if ( strcmp(param,"randaoa") == 0) { + int i = atoi(value); + if (i!=0 && i!=1) + prnt("ERROR: randaoa is a boolean, must be 0 or 1\n"); + else + defined_channels[cd_id]->random_aoa=i; } else if ( strcmp(param,"ploss") == 0) { double dbl = atof(value); defined_channels[cd_id]->path_loss_dB=dbl; @@ -1587,21 +1602,21 @@ static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) } else if ( strcmp(param,"forgetf") == 0) { double dbl = atof(value); if (dbl <0 || dbl > 1) - prnt("forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl); + prnt("ERROR: forgetting factor range: 0 to 1 (disable variation), %lf is outof range\n",dbl); else defined_channels[cd_id]->forgetting_factor=dbl; } else { - + prnt("ERROR: %s, unknown channel parameter\n",param); + return CMDSTATUS_FOUND; } - display_channelmodel(defined_channels[cd_id],debug,prnt); - free(param); + display_channelmodel(defined_channels[cd_id],debug,prnt); + free(param); free(value); - + random_channel(defined_channels[cd_id],false); } - - return CMDSTATUS_FOUND; + return CMDSTATUS_FOUND; } - + int modelid_fromname(char *modelname) { int modelid=map_str_to_int(channelmod_names,modelname); AssertFatal(modelid>0, diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index ff53ca8c46..4b0c0a35e4 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -82,7 +82,8 @@ extern RAN_CONTEXT_t RC; {"IQfile", "\n", 0, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\ {"modelname", "\n", 0, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\ {"ploss", "\n", 0, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\ - {"forgetfact", "\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 }\ + {"forgetfact", "\n", 0, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\ + {"offset", "\n", 0, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ }; pthread_mutex_t Sockmutex; @@ -118,6 +119,7 @@ typedef struct { int channelmod; double chan_pathloss; double chan_forgetfact; + int chan_offset; } rfsimulator_state_t; @@ -166,7 +168,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { bridge->sample_rate, bridge->tx_bw, bridge->chan_forgetfact, // forgetting_factor - 0, // maybe used for TA + bridge->chan_offset, // maybe used for TA bridge->chan_pathloss); // path_loss in dB random_channel(ptr->channel_model,false); } From f5d1dbb731f4f260a1a8dcdc0ca8d4051c054cab Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 29 Jul 2020 01:34:52 +0200 Subject: [PATCH 126/171] add telnet command to rfsimulator --- common/utils/telnetsrv/telnetsrv.c | 10 ++++++ common/utils/telnetsrv/telnetsrv.h | 3 +- targets/ARCH/rfsimulator/simulator.c | 54 ++++++++++++++++++++++++++-- 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 831d6032c8..1a96a50b21 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -684,6 +684,16 @@ void run_telnetsrv(void) { return; } +void poll_telnetcmdq(void *qid) { + notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid); + + if (msg != NULL) { + telnetsrv_qmsg_t *msgdata=NotifiedFifoData(msg); + msgdata->cmdfunc(msgdata->cmdbuff,msgdata->debug,msgdata->prnt); + free(msgdata->cmdbuff); + delNotifiedFIFO_elt(msg); + } +} /*------------------------------------------------------------------------------------------------*/ /* load the commands delivered with the telnet server * diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index 32ec2b9666..4aceb64079 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -142,8 +142,9 @@ VT escape sequence definition, for smarter display.... /*---------------------------------------------------------------------------------------------*/ #define TELNET_ADDCMD_FNAME "add_telnetcmd" -#define TELNET_ADDQUEUEDCMD_FNAME "add_telnetqueuedcmd" +#define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq" typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); +typedef void(*poll_telnetcmdq_func_t)(void *qid); #ifdef TELNETSERVERCODE int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); void set_sched(pthread_t tid, int pid,int priority); diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 4b0c0a35e4..9ad05f3a88 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include "common_lib.h" #include @@ -86,6 +87,17 @@ extern RAN_CONTEXT_t RC; {"offset", "\n", 0, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\ }; + + +static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static telnetshell_cmddef_t rfsimu_cmdarray[] = { + {"setmodel","",rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, + {"","",NULL}, +}; + +static telnetshell_vardef_t rfsimu_vardef[] = { + {"",0,NULL} +}; pthread_mutex_t Sockmutex; typedef struct complex16 sample_t; // 2*16 bits complex number @@ -120,6 +132,8 @@ typedef struct { double chan_pathloss; double chan_forgetfact; int chan_offset; + void *telnetcmd_qid; + poll_telnetcmdq_func_t poll_telnetcmdq; } rfsimulator_state_t; @@ -157,7 +171,8 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { if (!init_done) { uint64_t rand; FILE *h=fopen("/dev/random","r"); - fread(&rand,sizeof(rand),1,h); + int st=fread(&rand,sizeof(rand),1,h); + AssertFatal(st != -1, "Error reading random int %s\n",strerror(errno)); fclose(h); randominit(rand); tableNor(rand); @@ -296,6 +311,28 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { rfsimulator->typeStamp = UE_MAGICDL_FDD; } +static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) { + char *modelname=NULL; + int s = sscanf(buff,"%ms\n",&modelname); + int channelmod=modelid_fromname(modelname); + for (int i=0; ibuf[i].conn_sock > 0) { + channel_desc_t *cm = rfsimulator->buf[i].channel_model; + + rfsimulator->buf[i].channel_model=new_channel_desc_scm(cm->nb_tx,cm->nb_rx, + channelmod, + cm->sampling_rate, + cm->channel_bandwidth, + cm->forgetting_factor, // forgetting_factor + cm->channel_offset, // maybe used for TA + cm-> path_loss_dB); // path_loss in dB + free_channel_desc_scm(cm); + random_channel(ptr->channel_model,false); + } */ + } + return CMDSTATUS_FOUND; +} + int server_start(openair0_device *device) { rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; t->typeStamp=ENB_MAGICDL_FDD; @@ -646,7 +683,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo // it seems legacy behavior is: never in UL, each frame in DL if (reGenerateChannel) random_channel(ptr->channel_model,0); - + t->poll_telnetcmdq(t->telnetcmd_qid); for (int a=0; achannel_model != NULL ) // apply a channel model rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], @@ -740,5 +777,18 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { rfsimulator->tx_bw=openair0_cfg->tx_bw; //randominit(0); set_taus_seed(0); + /* look for telnet server, if it is loaded, add the channel modeling commands to it */ + add_telnetcmd_func_t addcmd = (add_telnetcmd_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_ADDCMD_FNAME); + + if (addcmd != NULL) { + rfsimulator->poll_telnetcmdq = (poll_telnetcmdq_func_t)get_shlibmodule_fptr("telnetsrv", TELNET_POLLCMDQ_FNAME); + addcmd("rfsimu",rfsimu_vardef,rfsimu_cmdarray); + for(int i=0; rfsimu_cmdarray[i].cmdfunc != NULL; i++) { + if ( rfsimu_cmdarray[i].qptr != NULL) { + rfsimulator->telnetcmd_qid = rfsimu_cmdarray[i].qptr; + break; + } + } + } return 0; } From 9c2696e5e2883788159e6c32de07d7a50622192b Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Tue, 28 Jul 2020 16:39:46 +0200 Subject: [PATCH 127/171] fix to have the sony 5g connect in NSA mode c_SRS was 61, which does not fit for 106 PRBs as it seems. Value 0 works. Maybe not the right thing to do though (see 38.211 6.4.1.4.3, table 6.4.1.4.3-1). Also it seems necessary to pass desired LTE/NR bands when requesting LTE UE capabilities. Today this is hardcoded, to be done better at some point. We should get the bands from the eNB configuration and the eNB/gNB X2 exchanges. --- openair2/RRC/LTE/MESSAGES/asn1_msg.c | 46 +++++++++++++++++++++++++--- openair2/RRC/NR/rrc_gNB_reconfig.c | 2 +- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/openair2/RRC/LTE/MESSAGES/asn1_msg.c b/openair2/RRC/LTE/MESSAGES/asn1_msg.c index 9ede543003..c537c536b2 100644 --- a/openair2/RRC/LTE/MESSAGES/asn1_msg.c +++ b/openair2/RRC/LTE/MESSAGES/asn1_msg.c @@ -3198,6 +3198,42 @@ uint8_t do_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, ASN_SEQUENCE_ADD(&dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8.ue_CapabilityRequest.list, &rat); + /* request NR configuration */ + LTE_UECapabilityEnquiry_r8_IEs_t *r8 = &dl_dcch_msg.message.choice.c1.choice.ueCapabilityEnquiry.criticalExtensions.choice.c1.choice.ueCapabilityEnquiry_r8; + LTE_UECapabilityEnquiry_v8a0_IEs_t r8_a0; + LTE_UECapabilityEnquiry_v1180_IEs_t r11_80; + LTE_UECapabilityEnquiry_v1310_IEs_t r13_10; + LTE_UECapabilityEnquiry_v1430_IEs_t r14_30; + LTE_UECapabilityEnquiry_v1510_IEs_t r15_10; + + memset(&r8_a0, 0, sizeof(r8_a0)); + memset(&r11_80, 0, sizeof(r11_80)); + memset(&r13_10, 0, sizeof(r13_10)); + memset(&r14_30, 0, sizeof(r14_30)); + memset(&r15_10, 0, sizeof(r15_10)); + + r8->nonCriticalExtension = &r8_a0; + r8_a0.nonCriticalExtension = &r11_80; + r11_80.nonCriticalExtension = &r13_10; + r13_10.nonCriticalExtension = &r14_30; + r14_30.nonCriticalExtension = &r15_10; + + /* TODO: no hardcoded values here */ + + OCTET_STRING_t req_freq; + unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 + + //unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 }; +// unsigned char req_freq_buf[21] = { +//0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a +// }; + + req_freq.buf = req_freq_buf; + req_freq.size = 5; +// req_freq.size = 21; + + r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) { xer_fprint(stdout, &asn_DEF_LTE_DL_DCCH_Message, (void *)&dl_dcch_msg); } @@ -3276,17 +3312,17 @@ uint8_t do_NR_UECapabilityEnquiry( const protocol_ctxt_t *const ctxt_pP, /* TODO: no hardcoded values here */ OCTET_STRING_t req_freq; - //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 + unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x02, 0x68 }; // bands 7 & nr78 //unsigned char req_freq_buf[5] = { 0x00, 0x20, 0x1a, 0x08, 0x18 }; // bands 7 & nr260 //unsigned char req_freq_buf[13] = { 0x00, 0xc0, 0x18, 0x01, 0x01, 0x30, 0x4b, 0x04, 0x0e, 0x08, 0x24, 0x04, 0xd0 }; - unsigned char req_freq_buf[21] = { -0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a - }; +// unsigned char req_freq_buf[21] = { +//0x01, 0x60, 0x18, 0x05, 0x80, 0xc0, 0x04, 0x04, 0xc1, 0x2c, 0x10, 0x08, 0x20, 0x30, 0x40, 0xe0, 0x82, 0x40, 0x28, 0x80, 0x9a +// }; req_freq.buf = req_freq_buf; req_freq.size = 5; - req_freq.size = 21; +// req_freq.size = 21; r15_10.requestedFreqBandsNR_MRDC_r15 = &req_freq; diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index a7aa38dfe3..6ea6f3b3b3 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -917,7 +917,7 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco srs_res0->resourceMapping.repetitionFactor=NR_SRS_Resource__resourceMapping__repetitionFactor_n1; srs_res0->freqDomainPosition=0; srs_res0->freqDomainShift=0; - srs_res0->freqHopping.c_SRS = 61; + srs_res0->freqHopping.c_SRS = 0; srs_res0->freqHopping.b_SRS=0; srs_res0->freqHopping.b_hop=0; srs_res0->groupOrSequenceHopping=NR_SRS_Resource__groupOrSequenceHopping_neither; From d4bd2cdc63e9a6c28c29f9a1b7f1cb0c6eeab4be Mon Sep 17 00:00:00 2001 From: frtabu Date: Wed, 29 Jul 2020 20:27:04 +0200 Subject: [PATCH 128/171] implement modifying channel model algo while running, complete function freeing a model --- common/utils/telnetsrv/telnetsrv.c | 14 ++-- common/utils/telnetsrv/telnetsrv.h | 5 +- openair1/SIMULATION/TOOLS/random_channel.c | 98 ++++++++++++++-------- openair1/SIMULATION/TOOLS/sim.h | 27 +++++- targets/ARCH/rfsimulator/simulator.c | 53 +++++++----- 5 files changed, 135 insertions(+), 62 deletions(-) diff --git a/common/utils/telnetsrv/telnetsrv.c b/common/utils/telnetsrv/telnetsrv.c index 1a96a50b21..03f7af99bc 100644 --- a/common/utils/telnetsrv/telnetsrv.c +++ b/common/utils/telnetsrv/telnetsrv.c @@ -508,7 +508,7 @@ int process_command(char *buf) { } rt= CMDSTATUS_FOUND; - } else if (strncasecmp(cmd,"get",3) == 0 || strncasecmp(cmd,"set",3) == 0) { + } else if (strcasecmp(cmd,"get") == 0 || strcasecmp(cmd,"set") == 0) { rt= setgetvar(i,cmd[0],cmdb); } else { for (k=0 ; telnetparams.CmdParsers[i].cmd[k].cmdfunc != NULL ; k++) { @@ -516,7 +516,7 @@ int process_command(char *buf) { if (telnetparams.CmdParsers[i].cmd[k].qptr != NULL) { notifiedFIFO_elt_t *msg =newNotifiedFIFO_elt(sizeof(telnetsrv_qmsg_t),0,NULL,NULL); telnetsrv_qmsg_t *cmddata=NotifiedFifoData(msg); - cmddata->cmdfunc=telnetparams.CmdParsers[i].cmd[k].cmdfunc; + cmddata->cmdfunc=(qcmdfunc_t)telnetparams.CmdParsers[i].cmd[k].cmdfunc; cmddata->prnt=client_printf; cmddata->debug=telnetparams.telnetdbg; cmddata->cmdbuff=strdup(cmdb); @@ -684,12 +684,12 @@ void run_telnetsrv(void) { return; } -void poll_telnetcmdq(void *qid) { +void poll_telnetcmdq(void *qid, void *arg) { notifiedFIFO_elt_t *msg = pollNotifiedFIFO((notifiedFIFO_t *)qid); if (msg != NULL) { telnetsrv_qmsg_t *msgdata=NotifiedFifoData(msg); - msgdata->cmdfunc(msgdata->cmdbuff,msgdata->debug,msgdata->prnt); + msgdata->cmdfunc(msgdata->cmdbuff,msgdata->debug,msgdata->prnt,arg); free(msgdata->cmdbuff); delNotifiedFIFO_elt(msg); } @@ -826,8 +826,10 @@ int telnetsrv_checkbuildver(char *mainexec_buildversion, char **shlib_buildvers } int telnetsrv_getfarray(loader_shlibfunc_t **farray) { - *farray=malloc(sizeof(loader_shlibfunc_t)); + *farray=malloc(sizeof(loader_shlibfunc_t)*2); (*farray)[0].fname=TELNET_ADDCMD_FNAME; (*farray)[0].fptr=(int (*)(void) )add_telnetcmd; - return 1; + (*farray)[1].fname=TELNET_POLLCMDQ_FNAME; + (*farray)[1].fptr=(int (*)(void) )poll_telnetcmdq; + return ( 2); } diff --git a/common/utils/telnetsrv/telnetsrv.h b/common/utils/telnetsrv/telnetsrv.h index 4aceb64079..b66641d5c8 100644 --- a/common/utils/telnetsrv/telnetsrv.h +++ b/common/utils/telnetsrv/telnetsrv.h @@ -53,6 +53,7 @@ /* to add a set of new command to the telnet server shell */ typedef void(*telnet_printfunc_t)(const char* format, ...); typedef int(*cmdfunc_t)(char*, int, telnet_printfunc_t prnt); +typedef int(*qcmdfunc_t)(char*, int, telnet_printfunc_t prnt,void *arg); #define TELNETSRV_CMDFLAG_PUSHINTPOOLQ (1<<0) // ask the telnet server to push the command in a thread pool queue typedef struct cmddef { @@ -67,7 +68,7 @@ typedef struct cmddef { /* structure used to send a command via a message queue to enable */ /* executing a command in a thread different from the telnet server thread */ typedef struct telnetsrv_qmsg { - cmdfunc_t cmdfunc; + qcmdfunc_t cmdfunc; telnet_printfunc_t prnt; int debug; char *cmdbuff; @@ -144,7 +145,7 @@ VT escape sequence definition, for smarter display.... #define TELNET_ADDCMD_FNAME "add_telnetcmd" #define TELNET_POLLCMDQ_FNAME "poll_telnetcmdq" typedef int(*add_telnetcmd_func_t)(char *, telnetshell_vardef_t *, telnetshell_cmddef_t *); -typedef void(*poll_telnetcmdq_func_t)(void *qid); +typedef void(*poll_telnetcmdq_func_t)(void *qid,void *arg); #ifdef TELNETSERVERCODE int add_telnetcmd(char *modulename, telnetshell_vardef_t *var, telnetshell_cmddef_t *cmd); void set_sched(pthread_t tid, int pid,int priority); diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index af266a6600..f97b9dfb78 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -68,7 +68,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, uint8_t nb_taps, uint8_t channel_length, double *amps, - double *delays, + double *delays, struct complex **R_sqrt, double Td, double sampling_rate, @@ -93,6 +93,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, if (delays==NULL) { chan_desc->delays = (double *) malloc(nb_taps*sizeof(double)); + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_DELAY ; delta_tau = Td/nb_taps; for (i=0; iR_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_NTAPS ; for (i = 0; iR_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); - + chan_desc->R_sqrt[i] = (struct complex *) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); for (j = 0; jR_sqrt[i][j].x = 1.0; chan_desc->R_sqrt[i][j].y = 0.0; @@ -145,7 +145,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, } } else { chan_desc->R_sqrt = (struct complex **) calloc(nb_taps,sizeof(struct complex *)); - + for (i = 0; iR_sqrt[i] = (struct complex*) calloc(nb_tx*nb_rx*nb_tx*nb_rx,sizeof(struct complex)); //chan_desc->R_sqrt = (struct complex*)&R_sqrt[i][0]; @@ -175,7 +175,7 @@ void fill_channel_desc(channel_desc_t *chan_desc, double mbsfn_delays[] = {0,.03,.15,.31,.37,1.09,12.490,12.52,12.64,12.80,12.86,13.58,27.49,27.52,27.64,27.80,27.86,28.58}; double mbsfn_amps_dB[] = {0,-1.5,-1.4,-3.6,-0.6,-7.0,-10,-11.5,-11.4,-13.6,-10.6,-17.0,-20,-21.5,-21.4,-23.6,-20.6,-27}; -double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250}; +double scm_c_delays[] = {0, 0.0125, 0.0250, 0.3625, 0.3750, 0.3875, 0.2500, 0.2625, 0.2750, 1.0375, 1.0500, 1.0625, 2.7250, 2.7375, 2.7500, 4.6000, 4.6125, 4.6250}; double scm_c_amps_dB[] = {0.00, -2.22, -3.98, -1.86, -4.08, -5.84, -1.08, -3.30, -5.06, -9.08, -11.30, -13.06, -15.14, -17.36, -19.12, -20.64, -22.85, -24.62}; double epa_delays[] = { 0,.03,.07,.09,.11,.19,.41}; @@ -282,10 +282,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, SCM_t channel_model, double sampling_rate, double channel_bandwidth, - double forgetting_factor, + double forgetting_factor, int32_t channel_offset, double path_loss_dB) { - channel_desc_t *chan_desc = (channel_desc_t *)malloc(sizeof(channel_desc_t)); + channel_desc_t *chan_desc = (channel_desc_t *)calloc(1,sizeof(channel_desc_t)); for(int i=0; ichannel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -368,9 +368,10 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, for (i = 0; i<6; i++) chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; } else { + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); - + for (j = 0; jR_sqrt[i][j].x = 1.0; chan_desc->R_sqrt[i][j].y = 0.0; @@ -389,7 +390,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*scm_c_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -427,6 +428,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, for (i = 0; i<6; i++) chan_desc->R_sqrt[i] = (struct complex *) &R12_sqrt[i][0]; } else { + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -447,7 +449,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -466,7 +468,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, for (i = 0; ich[i] = (struct complex *) malloc(chan_desc->channel_length * sizeof(struct complex)); - + for (i = 0; ichF[i] = (struct complex *) malloc(1200 * sizeof(struct complex)); @@ -480,7 +482,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; } else { chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -501,7 +503,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -547,7 +549,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, LOG_W(OCM,"correlation matrix only implemented for nb_tx==2 and nb_rx==2, using identity\n"); } }*/ - break; + break; case EPA_high: chan_desc->nb_taps = 7; @@ -555,7 +557,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -609,7 +611,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*epa_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -663,7 +665,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*eva_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -696,8 +698,8 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; } else { chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); - - for (i = 0; i<6; i++) { + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; + for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); for (j = 0; jchannel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*etu_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -750,7 +752,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->R_sqrt[i] = (struct complex *) &R22_sqrt[i][0]; } else { chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex **)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6 ; for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -771,7 +773,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->channel_length = (int) (2*chan_desc->sampling_rate*chan_desc->Td + 1 + 2/(M_PI*M_PI)*log(4*M_PI*chan_desc->sampling_rate*chan_desc->Td)); sum_amps = 0; chan_desc->amps = (double *) malloc(chan_desc->nb_taps*sizeof(double)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_AMPS ; for (i = 0; inb_taps; i++) { chan_desc->amps[i] = pow(10,.1*mbsfn_amps_dB[i]); sum_amps += chan_desc->amps[i]; @@ -798,7 +800,7 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->a[i] = (struct complex *) malloc(nb_tx*nb_rx * sizeof(struct complex)); chan_desc->R_sqrt = (struct complex **) malloc(6*sizeof(struct complex *)); - + chan_desc->free_flags=chan_desc->free_flags|CHANMODEL_FREE_RSQRT_6; for (i = 0; i<6; i++) { chan_desc->R_sqrt[i] = (struct complex *) malloc(nb_tx*nb_rx*nb_tx*nb_rx * sizeof(struct complex)); @@ -1309,11 +1311,37 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, chan_desc->nb_paths = 10; return(chan_desc); } - + void free_channel_desc_scm(channel_desc_t *ch) { // Must be made cleanly, a lot of leaks... - defined_channels[ch->chan_idx]=NULL; - free(ch); + defined_channels[ch->chan_idx]=NULL; + if(ch->free_flags&CHANMODEL_FREE_AMPS) + free(ch->amps); + for (int i = 0; inb_tx*ch->nb_rx; i++) { + free(ch->ch[i]); + free(ch->chF[i]); + } + + for (int i = 0; inb_taps; i++) { + free(ch->a[i]); + } + if(ch->free_flags&CHANMODEL_FREE_DELAY) + free(ch->delays); + if(ch->free_flags&CHANMODEL_FREE_RSQRT_6) + for (int i = 0; i<6; i++) + free(ch->R_sqrt[i]); + if(ch->free_flags&CHANMODEL_FREE_RSQRT_NTAPS) + for (int i = 0; inb_taps;i++) + free(ch->R_sqrt[i]); + free(ch->R_sqrt); + free(ch->ch); + free(ch->chF); + free(ch->a); + free(ch); +} + +void set_channeldesc_owner(channel_desc_t *cdesc, uint32_t module_id) { + cdesc->module_id=module_id; } int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { @@ -1454,7 +1482,7 @@ int random_channel(channel_desc_t *desc, uint8_t abstraction_flag) { return (0); } - + double N_RB2sampling_rate(uint16_t N_RB) { double sampling_rate; @@ -1522,6 +1550,10 @@ static int channelmod_print_help(char *buff, int debug, telnet_printfunc_t prnt static void display_channelmodel(channel_desc_t *cd,int debug, telnet_printfunc_t prnt) { + char *module_id_str[]=MODULEID_STR_INIT; + if (cd->module_id != 0) { + prnt("model owner: %s\n",module_id_str[cd->module_id]); + } prnt("nb_tx: %i nb_rx: %i taps: %i bandwidth: %lf sampling: %lf\n",cd->nb_tx, cd->nb_rx, cd->nb_taps, cd->channel_bandwidth, cd->sampling_rate); prnt("channel length: %i Max path delay: %lf ricean fact.: %lf angle of arrival: %lf (randomized:%s)\n", cd->channel_length, cd->Td, cd->ricean_factor, cd->aoa, (cd->random_aoa?"Yes":"No")); @@ -1617,10 +1649,10 @@ static int channelmod_modify_cmd(char *buff, int debug, telnet_printfunc_t prnt) return CMDSTATUS_FOUND; } -int modelid_fromname(char *modelname) { - int modelid=map_str_to_int(channelmod_names,modelname); - AssertFatal(modelid>0, - "random_channel.c: Error channel model %s unknown\n",modelname); +int modelid_fromname(char *modelname) { + int modelid=map_str_to_int(channelmod_names,modelname); + if (modelid < 0) + LOG_E(OCM,"random_channel.c: Error channel model %s unknown\n",modelname); return modelid; } diff --git a/openair1/SIMULATION/TOOLS/sim.h b/openair1/SIMULATION/TOOLS/sim.h index 2e067e4ae8..cc06e2f85c 100644 --- a/openair1/SIMULATION/TOOLS/sim.h +++ b/openair1/SIMULATION/TOOLS/sim.h @@ -40,6 +40,16 @@ The present clause specifies several numerical functions for testing of digital #define NB_SAMPLES_CHANNEL_OFFSET 4 +typedef enum { + UNSPECIFIED_MODID=0, + RFSIMU_MODULEID=1 +} channelmod_moduleid_t; +#define MODULEID_STR_INIT {"","rfsimulator"} + +#define CHANMODEL_FREE_DELAY 1<<0 +#define CHANMODEL_FREE_RSQRT_6 1<<1 +#define CHANMODEL_FREE_RSQRT_NTAPS 1<<2 +#define CHANMODEL_FREE_AMPS 1<<3 typedef struct { ///Number of tx antennas uint8_t nb_tx; @@ -96,6 +106,10 @@ typedef struct { unsigned int chan_idx; /// id of the channel modeling algorithm int modelid; + /// identifies channel descriptor owner (the module which created this descriptor) + channelmod_moduleid_t module_id; + /// flags to properly trigger memory free + unsigned int free_flags; } channel_desc_t; typedef struct { @@ -278,9 +292,18 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, double forgetting_factor, int32_t channel_offset, double path_loss_dB); +/** +\brief free memory allocated for a model descriptor +\param ch points to the model, which cannot be used after calling this fuction +*/ +void free_channel_desc_scm(channel_desc_t *ch); - - +/** +\brief This set the ownerid of a model descriptor, can be later used to check what module created a channel model +\param cdesc points to the model descriptor +\param module_id identifies the channel model. should be define as a macro in simu.h +*/ +void set_channeldesc_owner(channel_desc_t *cdesc, channelmod_moduleid_t module_id); /** \fn void random_channel(channel_desc_t *desc) \brief This routine generates a random channel response (time domain) according to a tapped delay line model. \param desc Pointer to the channel descriptor diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 9ad05f3a88..36c90304b7 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -89,9 +89,9 @@ extern RAN_CONTEXT_t RC; -static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt); +static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg); static telnetshell_cmddef_t rfsimu_cmdarray[] = { - {"setmodel","",rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, + {"setmodel","",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ}, {"","",NULL}, }; @@ -185,6 +185,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { bridge->chan_forgetfact, // forgetting_factor bridge->chan_offset, // maybe used for TA bridge->chan_pathloss); // path_loss in dB + set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID); random_channel(ptr->channel_model,false); } } @@ -311,25 +312,38 @@ void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) { rfsimulator->typeStamp = UE_MAGICDL_FDD; } -static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt) { +static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg) { char *modelname=NULL; int s = sscanf(buff,"%ms\n",&modelname); - int channelmod=modelid_fromname(modelname); - for (int i=0; ibuf[i].conn_sock > 0) { - channel_desc_t *cm = rfsimulator->buf[i].channel_model; - - rfsimulator->buf[i].channel_model=new_channel_desc_scm(cm->nb_tx,cm->nb_rx, - channelmod, - cm->sampling_rate, - cm->channel_bandwidth, - cm->forgetting_factor, // forgetting_factor - cm->channel_offset, // maybe used for TA - cm-> path_loss_dB); // path_loss in dB - free_channel_desc_scm(cm); - random_channel(ptr->channel_model,false); - } */ + if (s == 1) { + int channelmod=modelid_fromname(modelname); + if (channelmod<0) + prnt("ERROR: model %s unknown\n",modelname); + else { + rfsimulator_state_t *t = (rfsimulator_state_t *)arg; + for (int i=0; ibuf[i]; + if (b->conn_sock >= 0 ) { + channel_desc_t *newmodel=new_channel_desc_scm(t->tx_num_channels,t->rx_num_channels, + channelmod, + t->sample_rate, + t->tx_bw, + t->chan_forgetfact, // forgetting_factor + t->chan_offset, // maybe used for TA + t->chan_pathloss); // path_loss in dB + set_channeldesc_owner(newmodel, RFSIMU_MODULEID); + random_channel(newmodel,false); + channel_desc_t *oldmodel=b->channel_model; + b->channel_model=newmodel; + free_channel_desc_scm(oldmodel); + prnt("New model %s applied to channel connected to sock %d\n",modelname,i); + } + } + } + } else { + prnt("ERROR: no model specified\n"); } + free(modelname); return CMDSTATUS_FOUND; } @@ -683,7 +697,8 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo // it seems legacy behavior is: never in UL, each frame in DL if (reGenerateChannel) random_channel(ptr->channel_model,0); - t->poll_telnetcmdq(t->telnetcmd_qid); + if (t->poll_telnetcmdq) + t->poll_telnetcmdq(t->telnetcmd_qid,t); for (int a=0; achannel_model != NULL ) // apply a channel model rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], From 2612f2639dd40841b5b69d6a5e4d6ba7ebbb2319 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 30 Jul 2020 10:38:36 +0200 Subject: [PATCH 129/171] CI: fix a few remaining getters Signed-off-by: Raphael Defosseux --- ci-scripts/ran.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 94d4f857b7..8f254975eb 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -348,9 +348,9 @@ class RANManagement(): # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB result = re.search('T_stdout', str(self.Initialize_eNB_args)) if (result is not None) and (self.epcObj is not None): - localEpcIpAddr = self.epcObj.GetIPAddress() - localEpcUserName = self.epcObj.GetUserName() - localEpcPassword = self.epcObj.GetPassword() + localEpcIpAddr = self.epcObj.IPAddress + localEpcUserName = self.epcObj.UserName + localEpcPassword = self.epcObj.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) mySSH.command('ip addr show | awk -f /tmp/active_net_interfaces.awk | egrep -v "lo|tun"', '\$', 5) result = re.search('interfaceToUse=(?P[a-zA-Z0-9\-\_]+)done', mySSH.getBefore()) @@ -457,9 +457,9 @@ class RANManagement(): # In case of T tracer recording, we need to kill tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) if (result is not None) and (self.epcObj is not None): - localEpcIpAddr = self.epcObj.GetIPAddress() - localEpcUserName = self.epcObj.GetUserName() - localEpcPassword = self.epcObj.GetPassword() + localEpcIpAddr = self.epcObj.IPAddress + localEpcUserName = self.epcObj.UserName + localEpcPassword = self.epcObj.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) logging.debug('\u001B[1m Stopping tshark \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) @@ -588,9 +588,9 @@ class RANManagement(): # If tracer options is on, stopping tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) if (result is not None) and (self.epcObj is not None): - localEpcIpAddr = self.epcObj.GetIPAddress() - localEpcUserName = self.epcObj.GetUserName() - localEpcPassword = self.epcObj.GetPassword() + localEpcIpAddr = self.epcObj.IPAddress + localEpcUserName = self.epcObj.UserName + localEpcPassword = self.epcObj.Password mySSH.open(localEpcIpAddr, localEpcUserName, localEpcPassword) logging.debug('\u001B[1m Stopping tshark \u001B[0m') mySSH.command('echo ' + localEpcPassword + ' | sudo -S killall --signal SIGKILL tshark', '\$', 5) From 5e62d39c9d57e55450febd588289b22d0e64f84f Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 30 Jul 2020 14:06:31 +0200 Subject: [PATCH 130/171] CI: fix the air_interface support on RAN and OAI-UE sides -- separate member now. Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 102 +++++++++++------- ci-scripts/ran.py | 33 +++--- ci-scripts/xml_files/fr1_multi_node_build.xml | 12 ++- ci-scripts/xml_files/gnb_usrp_build.xml | 2 +- ci-scripts/xml_files/nr_ue_usrp_build.xml | 2 +- 5 files changed, 88 insertions(+), 63 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index aaceac600e..660f068c2c 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -119,6 +119,7 @@ class OaiCiTest(): self.Build_OAI_UE_args = '' self.Initialize_OAI_UE_args = '' self.clean_repository = True + self.air_interface='' self.expectedNbOfConnectedUEs = 0 def BuildOAIUE(self): @@ -128,10 +129,10 @@ class OaiCiTest(): SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) result = re.search('--nrUE', self.Build_OAI_UE_args) if result is not None: - RAN.air_interface='nr' + self.air_interface='nr-uesoftmodem' ue_prefix = 'NR ' else: - RAN.air_interface='lte' + self.air_interface='lte-uesoftmodem' ue_prefix = '' result = re.search('([a-zA-Z0-9\:\-\.\/])+\.git', self.ranRepository) if result is not None: @@ -171,7 +172,7 @@ class OaiCiTest(): mismatch = True if not mismatch: SSH.close() - HTML.CreateHtmlTestRow(RAN.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) + HTML.CreateHtmlTestRow(self.Build_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK) return SSH.command('echo ' + self.UEPassword + ' | sudo -S git clean -x -d -ff', '\$', 30) @@ -197,7 +198,7 @@ class OaiCiTest(): SSH.command('ls ran_build/build', '\$', 3) SSH.command('ls ran_build/build', '\$', 3) buildStatus = True - result = re.search(RAN.air_interface + '-uesoftmodem', SSH.getBefore()) + result = re.search(self.air_interface, SSH.getBefore()) if result is None: buildStatus = False SSH.command('mkdir -p build_log_' + self.testCase_id, '\$', 5) @@ -322,7 +323,7 @@ class OaiCiTest(): if self.UEIPAddress == '' or self.UEUserName == '' or self.UEPassword == '' or self.UESourceCodePath == '': HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') - if RAN.air_interface == 'lte': + if self.air_interface == 'lte-uesoftmodem': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: check_eNB = True @@ -351,7 +352,7 @@ class OaiCiTest(): # Initialize_OAI_UE_args usually start with -C and followed by the location in repository SSH.command('source oaienv', '\$', 5) SSH.command('cd cmake_targets/ran_build/build', '\$', 5) - if RAN.air_interface == 'lte': + if self.air_interface == 'lte-uesoftmodem': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) # We may have to regenerate the .u* files if result is None: @@ -373,7 +374,7 @@ class OaiCiTest(): copyin_res = SSH.copyin(RAN.eNBIPAddress, RAN.eNBUserName, RAN.eNBPassword, RAN.eNBSourceCodePath + '/cmake_targets/reconfig.raw', '.') if (copyin_res == 0): SSH.copyout(self.UEIPAddress, self.UEUserName, self.UEPassword, './reconfig.raw', self.UESourceCodePath + '/cmake_targets/ran_build/build') - SSH.command('echo "ulimit -c unlimited && ./'+ RAN.air_interface +'-uesoftmodem ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) + SSH.command('echo "ulimit -c unlimited && ./'+ self.air_interface +' ' + self.Initialize_OAI_UE_args + '" > ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) SSH.command('chmod 775 ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) self.UELogFile = 'ue_' + self.testCase_id + '.log' @@ -404,7 +405,7 @@ class OaiCiTest(): doLoop = False continue SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync"', '\$', 4) - if RAN.air_interface == 'nr': + if self.air_interface == 'nr-uesoftmodem': result = re.search('Starting sync detection', SSH.getBefore()) else: result = re.search('got sync', SSH.getBefore()) @@ -429,7 +430,7 @@ class OaiCiTest(): # That is the case for LTE # In NR case, it's a positive message that will show if synchronization occurs doLoop = True - if RAN.air_interface == 'nr': + if self.air_interface == 'nr-uesoftmodem': loopCounter = 10 else: # We are now checking if sync w/ eNB DOES NOT OCCUR @@ -438,7 +439,7 @@ class OaiCiTest(): while (doLoop): loopCounter = loopCounter - 1 if (loopCounter == 0): - if RAN.air_interface == 'nr': + if self.air_interface == 'nr-uesoftmodem': # Here we do have great chances that UE did NOT cell-sync w/ gNB doLoop = False fullSyncStatus = False @@ -457,7 +458,7 @@ class OaiCiTest(): fullSyncStatus = True continue SSH.command('stdbuf -o0 cat ue_' + self.testCase_id + '.log | egrep --text --color=never -i "wait|sync|Frequency"', '\$', 4) - if RAN.air_interface == 'nr': + if self.air_interface == 'nr-uesoftmodem': # Positive messaging --> result = re.search('Measured Carrier Frequency', SSH.getBefore()) if result is not None: @@ -486,12 +487,12 @@ class OaiCiTest(): if fullSyncStatus and gotSyncStatus: doInterfaceCheck = False - if RAN.air_interface == 'lte': + if self.air_interface == 'lte-uesoftmodem': result = re.search('--no-L2-connect', str(self.Initialize_OAI_UE_args)) if result is None: doInterfaceCheck = True # For the moment, only in explicit noS1 without kernel module (ie w/ tunnel interface) - if RAN.air_interface == 'nr': + if self.air_interface == 'nr-uesoftmodem': result = re.search('--noS1 --nokrnmod 1', str(self.Initialize_OAI_UE_args)) if result is not None: doInterfaceCheck = True @@ -531,7 +532,7 @@ class OaiCiTest(): self.UEDevicesStatus = [] self.UEDevicesStatus.append(CONST.UE_STATUS_DETACHED) else: - if RAN.air_interface == 'lte': + if self.air_interface == 'lte-uesoftmodem': if RAN.eNBmbmsEnables[0]: HTML.htmlUEFailureMsg='oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' else: @@ -1086,7 +1087,10 @@ class OaiCiTest(): sys.exit('Insufficient Parameter') SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) if self.ADBCentralized: - SSH.command('adb devices', '\$', 15) + if self.ADBIPAddress == '192.168.18.196': + SSH.command('/home/oaici/remi/android-sdk-linux/platform-tools/adb devices', '\$', 15) + else: + SSH.command('adb devices', '\$', 15) #self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) SSH.close() @@ -2414,8 +2418,8 @@ class OaiCiTest(): def CheckOAIUEProcess(self, status_queue): try: SSH.open(self.UEIPAddress, self.UEUserName, self.UEPassword) - SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + RAN.air_interface + '-uesoftmodem | grep -v grep', '\$', 5) - result = re.search(RAN.air_interface + '-uesoftmodem', SSH.getBefore()) + SSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + ' | grep -v grep', '\$', 5) + result = re.search(self.air_interface, SSH.getBefore()) if result is None: logging.debug('\u001B[1;37;41m OAI UE Process Not Found! \u001B[0m') status_queue.put(CONST.OAI_UE_PROCESS_FAILED) @@ -2772,7 +2776,7 @@ class OaiCiTest(): logging.debug('\u001B[1m' + ueAction + ' Failed \u001B[0m') HTML.htmlUEFailureMsg='' + ueAction + ' Failed\n' + HTML.htmlUEFailureMsg HTML.CreateHtmlTestRow('N/A', 'KO', logStatus, 'UE') - if RAN.air_interface == 'lte': + if self.air_interface == 'lte-uesoftmodem': # In case of sniffing on commercial eNBs we have random results # Not an error then if (logStatus != CONST.OAI_UE_PROCESS_COULD_NOT_SYNC) or (ueAction != 'Sniffing'): @@ -2811,7 +2815,7 @@ class OaiCiTest(): self.desc = 'Automatic Termination of eNB' HTML.desc='Automatic Termination of eNB' self.ShowTestID() - RAN.eNB_instance='0' + RAN.eNB_instance=0 RAN.TerminateeNB() if RAN.flexranCtrlInstalled and RAN.flexranCtrlStarted: self.testCase_id = 'AUTO-KILL-flexran-ctl' @@ -3118,9 +3122,11 @@ def GetParametersFromXML(action): RAN.Build_eNB_forced_workspace_cleanup=True else: RAN.Build_eNB_forced_workspace_cleanup=False - RAN.eNB_instance=test.findtext('eNB_instance') - if (RAN.eNB_instance is None): - RAN.eNB_instance='0' + eNB_instance=test.findtext('eNB_instance') + if (eNB_instance is None): + RAN.eNB_instance=0 + else: + RAN.eNB_instance=int(eNB_instance) RAN.eNB_serverId=test.findtext('eNB_serverId') if (RAN.eNB_serverId is None): RAN.eNB_serverId='0' @@ -3135,18 +3141,22 @@ def GetParametersFromXML(action): if action == 'WaitEndBuild_eNB': RAN.Build_eNB_args=test.findtext('Build_eNB_args') - RAN.eNB_instance=test.findtext('eNB_instance') - if (RAN.eNB_instance is None): + eNB_instance=test.findtext('eNB_instance') + if (eNB_instance is None): RAN.eNB_instance='0' + else: + RAN.eNB_instance=int(eNB_instance) RAN.eNB_serverId=test.findtext('eNB_serverId') if (RAN.eNB_serverId is None): RAN.eNB_serverId='0' if action == 'Initialize_eNB': RAN.Initialize_eNB_args=test.findtext('Initialize_eNB_args') - RAN.eNB_instance=test.findtext('eNB_instance') - if (RAN.eNB_instance is None): - RAN.eNB_instance='0' + eNB_instance=test.findtext('eNB_instance') + if (eNB_instance is None): + RAN.eNB_instance=0 + else: + RAN.eNB_instance=int(eNB_instance) RAN.eNB_serverId=test.findtext('eNB_serverId') if (RAN.eNB_serverId is None): RAN.eNB_serverId='0' @@ -3154,17 +3164,18 @@ def GetParametersFromXML(action): #local variable air_interface air_interface = test.findtext('air_interface') if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): - CiTestObj.air_interface = 'lte-softmodem' + RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem' elif (air_interface.lower() in ['nr','lte']): - CiTestObj.air_interface = air_interface.lower() +'-softmodem' + RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem' else : - CiTestObj.air_interface = 'ocp-enb' - RAN.air_interface=CiTestObj.air_interface + RAN.air_interface[RAN.eNB_instance] = 'ocp-enb' if action == 'Terminate_eNB': - RAN.eNB_instance=test.findtext('eNB_instance') + eNB_instance=test.findtext('eNB_instance') if (RAN.eNB_instance is None): - RAN.eNB_instance='0' + RAN.eNB_instance=0 + else: + RAN.eNB_instance=int(eNB_instance) RAN.eNB_serverId=test.findtext('eNB_serverId') if (RAN.eNB_serverId is None): RAN.eNB_serverId='0' @@ -3172,12 +3183,11 @@ def GetParametersFromXML(action): #local variable air_interface air_interface = test.findtext('air_interface') if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): - CiTestObj.air_interface = 'lte-softmodem' + RAN.air_interface[RAN.eNB_instance] = 'lte-softmodem' elif (air_interface.lower() in ['nr','lte']): - CiTestObj.air_interface = air_interface.lower() +'-softmodem' + RAN.air_interface[RAN.eNB_instance] = air_interface.lower() +'-softmodem' else : - CiTestObj.air_interface = 'ocp-enb' - RAN.air_interface=CiTestObj.air_interface + RAN.air_interface[RAN.eNB_instance] = 'ocp-enb' if action == 'Attach_UE': nbMaxUEtoAttach = test.findtext('nbMaxUEtoAttach') @@ -3210,17 +3220,27 @@ def GetParametersFromXML(action): #local variable air_interface air_interface = test.findtext('air_interface') if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): - CiTestObj.air_interface = 'lte-softmodem' + CiTestObj.air_interface = 'lte-uesoftmodem' elif (air_interface.lower() in ['nr','lte']): - CiTestObj.air_interface = air_interface.lower() +'-softmodem' + CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem' else : - CiTestObj.air_interface = 'ocp-enb' - RAN.air_interface=CiTestObj.air_interface + #CiTestObj.air_interface = 'ocp-enb' + logging.error('OCP UE -- NOT SUPPORTED') if action == 'Terminate_OAI_UE': RAN.eNB_instance=test.findtext('UE_instance') if (CiTestObj.UE_instance is None): CiTestObj.UE_instance = '0' + + #local variable air_interface + air_interface = test.findtext('air_interface') + if (air_interface is None) or (air_interface.lower() not in ['nr','lte','ocp']): + CiTestObj.air_interface = 'lte-uesoftmodem' + elif (air_interface.lower() in ['nr','lte']): + CiTestObj.air_interface = air_interface.lower() +'-uesoftmodem' + else : + #CiTestObj.air_interface = 'ocp-enb' + logging.error('OCP UE -- NOT SUPPORTED') if action == 'Ping' or action == 'Ping_CatM_module': CiTestObj.ping_args = test.findtext('ping_args') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 8f254975eb..054b92a181 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -77,8 +77,8 @@ class RANManagement(): self.backgroundBuildTestId = ['', '', ''] self.Build_eNB_forced_workspace_cleanup = False self.Initialize_eNB_args = '' - self.air_interface = '' #changed from 'lte' to '' may lead to side effects in main - self.eNB_instance = '' + self.air_interface = ['', '', ''] #changed from 'lte' to '' may lead to side effects in main + self.eNB_instance = 0 self.eNB_serverId = '' self.eNBLogFiles = ['', '', ''] self.eNBOptions = ['', '', ''] @@ -125,13 +125,13 @@ class RANManagement(): # Check if we build an 5G-NR gNB or an LTE eNB or an OCP eNB result = re.search('--eNBocp', self.Build_eNB_args) if result is not None: - self.air_interface='ocp-enb' + self.air_interface[self.eNB_instance] = 'ocp-enb' else: result = re.search('--gNB', self.Build_eNB_args) if result is not None: - self.air_interface = 'nr-softmodem' + self.air_interface[self.eNB_instance] = 'nr-softmodem' else: - self.air_interface = 'lte-softmodem' + self.air_interface[self.eNB_instance] = 'lte-softmodem' # Worakround for some servers, we need to erase completely the workspace if self.Build_eNB_forced_workspace_cleanup: @@ -205,7 +205,9 @@ class RANManagement(): if self.backgroundBuild: mySSH.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5) mySSH.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5) - mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5) + #mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5) + mySSH.command('echo ' + lPassWord + ' | sudo -S ls', '\$', 5) + mySSH.command('echo $USER; nohup sudo ./my-lte-softmodem-build.sh' + ' > ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ' + ' 2>&1 &', lUserName, 5) mySSH.close() if self.htmlObj is not None: self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) @@ -261,7 +263,7 @@ class RANManagement(): #check if we have the build corresponding to the air interface keywords (nr-softmode, lte-softmodem, ocp-enb) logging.info('CHECK Build with IP='+lIpAddr+' SourcePath='+lSourcePath) - result = re.search(self.air_interface, mySSH.getBefore()) + result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore()) if result is None: buildStatus = False #if not, build failed else: @@ -304,11 +306,11 @@ class RANManagement(): #generate logging info depending on buildStatus and air interface if buildStatus: - logging.info('\u001B[1m Building OAI ' + self.air_interface + ' Pass\u001B[0m') + logging.info('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Pass\u001B[0m') if self.htmlObj is not None: self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) else: - logging.error('\u001B[1m Building OAI ' + self.air_interface + ' Failed\u001B[0m') + logging.error('\u001B[1m Building OAI ' + self.air_interface[self.eNB_instance] + ' Failed\u001B[0m') if self.htmlObj is not None: self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'KO', CONST.ALL_PROCESSES_OK) self.htmlObj.CreateHtmlTabFooter(False) @@ -426,7 +428,8 @@ class RANManagement(): if self.air_interface == 'nr': mySSH.command('if [ -e rbconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm rbconfig.raw; fi', '\$', 5) mySSH.command('if [ -e reconfig.raw ]; then echo ' + lPassWord + ' | sudo -S rm reconfig.raw; fi', '\$', 5) - mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface + '-softmodem -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + # NOTE: WE SHALL do a check if the executable is present (in case build went wrong) + mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) mySSH.command('hostnamectl','\$', 5) @@ -535,8 +538,8 @@ class RANManagement(): lPassWord = self.eNBPassword mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) - mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface + ' | grep -v grep', '\$', 5) - result = re.search(self.air_interface, mySSH.getBefore()) + mySSH.command('stdbuf -o0 ps -aux | grep --color=never ' + self.air_interface[self.eNB_instance] + ' | grep -v grep', '\$', 5) + result = re.search(self.air_interface[self.eNB_instance], mySSH.getBefore()) if result is None: logging.debug('\u001B[1;37;41m eNB Process Not Found! \u001B[0m') status_queue.put(CONST.ENB_PROCESS_FAILED) @@ -568,7 +571,7 @@ class RANManagement(): mySSH = SSH.SSHConnection() mySSH.open(lIpAddr, lUserName, lPassWord) mySSH.command('cd ' + lSourcePath + '/cmake_targets', '\$', 5) - if (self.air_interface == 'lte-softmodem') or (self.air_interface == 'ocp-enb'): + if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): nodeB_prefix = 'e' else: nodeB_prefix = 'g' @@ -831,11 +834,11 @@ class RANManagement(): mbmsRequestMsg += 1 enb_log_file.close() logging.debug(' File analysis completed') - if (self.air_interface == 'lte-softmodem') or (self.air_interface == 'ocp-enb'): + if (self.air_interface[self.eNB_instance] == 'lte-softmodem') or (self.air_interface[self.eNB_instance] == 'ocp-enb'): nodeB_prefix = 'e' else: nodeB_prefix = 'g' - if self.air_interface == 'nr-softmodem': + if self.air_interface[self.eNB_instance] == 'nr-softmodem': if ulschReceiveOK > 0: statMsg = nodeB_prefix + 'NB showed ' + str(ulschReceiveOK) + ' "ULSCH received ok" message(s)' logging.debug('\u001B[1;30;43m ' + statMsg + ' \u001B[0m') diff --git a/ci-scripts/xml_files/fr1_multi_node_build.xml b/ci-scripts/xml_files/fr1_multi_node_build.xml index 0b7dce29d8..7b4eacef3a 100644 --- a/ci-scripts/xml_files/fr1_multi_node_build.xml +++ b/ci-scripts/xml_files/fr1_multi_node_build.xml @@ -33,27 +33,29 @@ Build_eNB Build eNB - -w USRP -c --eNB + -w USRP -c --eNB --ninja 0 0 + True - + WaitEndBuild_eNB Wait for end of Build eNB 0 0 - + Build_eNB Build gNB - -w USRP -c --gNB + -w USRP -c --gNB --ninja 1 1 + True - + WaitEndBuild_eNB Wait for end of Build gNB 1 diff --git a/ci-scripts/xml_files/gnb_usrp_build.xml b/ci-scripts/xml_files/gnb_usrp_build.xml index 97d6ef06f6..e2662180c5 100644 --- a/ci-scripts/xml_files/gnb_usrp_build.xml +++ b/ci-scripts/xml_files/gnb_usrp_build.xml @@ -34,7 +34,7 @@ TesteNB Build_eNB Build gNB (USRP) - --gNB -w USRP + --gNB -w USRP --ninja True diff --git a/ci-scripts/xml_files/nr_ue_usrp_build.xml b/ci-scripts/xml_files/nr_ue_usrp_build.xml index c3c842b85a..bc04efdb4b 100644 --- a/ci-scripts/xml_files/nr_ue_usrp_build.xml +++ b/ci-scripts/xml_files/nr_ue_usrp_build.xml @@ -34,7 +34,7 @@ TestUE Build_OAI_UE Build NR UE (USRP) - --nrUE -w USRP + --nrUE -w USRP --ninja false From e55f2aea0c629a52ed5551d36d1b8e53a466c35c Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Thu, 30 Jul 2020 16:21:51 +0200 Subject: [PATCH 131/171] CI: adding support for FR1 run of both eNB and gNB Signed-off-by: Raphael Defosseux --- .../enb.band7.tm1.fr1.25PRB.usrpb210.conf | 283 +++++++++++++++++ .../gnb.band78.tm1.fr1.106PRB.usrpb210.conf | 291 ++++++++++++++++++ ci-scripts/main.py | 18 +- ci-scripts/ran.py | 2 + ci-scripts/xml_files/fr1_multi_node_test.xml | 77 +++++ 5 files changed, 664 insertions(+), 7 deletions(-) create mode 100755 ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf create mode 100755 ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf create mode 100644 ci-scripts/xml_files/fr1_multi_node_test.xml diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf new file mode 100755 index 0000000000..085c5d0ab3 --- /dev/null +++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf @@ -0,0 +1,283 @@ +Active_eNBs = ( "eNB-Eurecom-LTEBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +eNBs = +( + { + # real_time choice in {hard, rt-preempt, no} + real_time = "no"; + ////////// Identification parameters: + eNB_ID = 0xe01; + cell_type = "CELL_MACRO_ENB"; + eNB_name = "eNB-Eurecom-LTEBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ( + { mcc = 222; mnc = 01; mnc_length = 2; } + ); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + component_carriers = ( + { + node_function = "eNodeB_3GPP"; + node_timing = "synch_to_ext_device"; + node_synch_ref = 0; + nb_antenna_portsi = 1; + ue_TransmissionMode = 1; + frame_type = "FDD"; + tdd_config = 3; + tdd_config_s = 0; + prefix_type = "NORMAL"; + eutra_band = 7; + downlink_frequency = 2680000000L; + uplink_frequency_offset = -120000000; + + Nid_cell = 0; + N_RB_DL = 25; + Nid_cell_mbsfn = 0; + nb_antennas_tx = 1; + nb_antennas_rx = 1; + prach_root = 0; + tx_gain = 90; + rx_gain = 115; + pbch_repetition = "FALSE"; + + prach_config_index = 0; + prach_high_speed = "DISABLE"; + prach_zero_correlation = 1; + prach_freq_offset = 2; + + pucch_delta_shift = 1; + pucch_nRB_CQI = 0; + pucch_nCS_AN = 0; + pucch_n1_AN = 0; + pdsch_referenceSignalPower = -29; + pdsch_p_b = 0; + pusch_n_SB = 1; + pusch_enable64QAM = "DISABLE"; + pusch_hoppingMode = "interSubFrame"; + pusch_hoppingOffset = 0; + pusch_groupHoppingEnabled = "ENABLE"; + pusch_groupAssignment = 0; + pusch_sequenceHoppingEnabled = "DISABLE"; + pusch_nDMRS1 = 1; + phich_duration = "NORMAL"; + phich_resource = "ONESIXTH"; + srs_enable = "DISABLE"; +/* + srs_BandwidthConfig =; + srs_SubframeConfig =; + srs_ackNackST =; + srs_MaxUpPts =; +*/ + + pusch_p0_Nominal = -96; + pusch_alpha = "AL1"; + pucch_p0_Nominal = -96; + msg3_delta_Preamble = 6; + pucch_deltaF_Format1 = "deltaF2"; + pucch_deltaF_Format1b = "deltaF3"; + pucch_deltaF_Format2 = "deltaF0"; + pucch_deltaF_Format2a = "deltaF0"; + pucch_deltaF_Format2b = "deltaF0"; + + rach_numberOfRA_Preambles = 64; + rach_preamblesGroupAConfig = "DISABLE"; +/* + rach_sizeOfRA_PreamblesGroupA = ; + rach_messageSizeGroupA = ; + rach_messagePowerOffsetGroupB = ; +*/ + rach_powerRampingStep = 4; + rach_preambleInitialReceivedTargetPower = -108; + rach_preambleTransMax = 10; + rach_raResponseWindowSize = 10; + rach_macContentionResolutionTimer = 48; + rach_maxHARQ_Msg3Tx = 4; + + pcch_default_PagingCycle = 128; + pcch_nB = "oneT"; + bcch_modificationPeriodCoeff = 2; + ue_TimersAndConstants_t300 = 1000; + ue_TimersAndConstants_t301 = 1000; + ue_TimersAndConstants_t310 = 1000; + ue_TimersAndConstants_t311 = 10000; + ue_TimersAndConstants_n310 = 20; + ue_TimersAndConstants_n311 = 1; + + //Parameters for SIB18 + rxPool_sc_CP_Len = "normal"; + rxPool_sc_Period = "sf40"; + rxPool_data_CP_Len = "normal"; + rxPool_ResourceConfig_prb_Num = 20; + rxPool_ResourceConfig_prb_Start = 5; + rxPool_ResourceConfig_prb_End = 44; + rxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + rxPool_ResourceConfig_offsetIndicator_choice = 0; + rxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "00000000000000000000"; + rxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + rxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; +/* + rxPool_dataHoppingConfig_hoppingParameter = 0; + rxPool_dataHoppingConfig_numSubbands = "ns1"; + rxPool_dataHoppingConfig_rbOffset = 0; + rxPool_commTxResourceUC-ReqAllowed = "TRUE"; +*/ + // Parameters for SIB19 + discRxPool_cp_Len = "normal" + discRxPool_discPeriod = "rf32" + discRxPool_numRetx = 1; + discRxPool_numRepetition = 2; + discRxPool_ResourceConfig_prb_Num = 5; + discRxPool_ResourceConfig_prb_Start = 3; + discRxPool_ResourceConfig_prb_End = 21; + discRxPool_ResourceConfig_offsetIndicator_present = "prSmall"; + discRxPool_ResourceConfig_offsetIndicator_choice = 0; + discRxPool_ResourceConfig_subframeBitmap_present = "prBs40"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_buf = "f0ffffffff"; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_size = 5; + discRxPool_ResourceConfig_subframeBitmap_choice_bs_bits_unused = 0; + + } + ); + + srb1_parameters : + { + # timer_poll_retransmit = (ms) [5, 10, 15, 20,... 250, 300, 350, ... 500] + timer_poll_retransmit = 80; + + # timer_reordering = (ms) [0,5, ... 100, 110, 120, ... ,200] + timer_reordering = 35; + + # timer_reordering = (ms) [0,5, ... 250, 300, 350, ... ,500] + timer_status_prohibit = 0; + + # poll_pdu = [4, 8, 16, 32 , 64, 128, 256, infinity(>10000)] + poll_pdu = 4; + + # poll_byte = (kB) [25,50,75,100,125,250,375,500,750,1000,1250,1500,2000,3000,infinity(>10000)] + poll_byte = 99999; + + # max_retx_threshold = [1, 2, 3, 4 , 6, 8, 16, 32] + max_retx_threshold = 4; + } + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + enable_measurement_reports = "yes"; + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + + NETWORK_INTERFACES : + { + ENB_INTERFACE_NAME_FOR_S1_MME = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1_MME = "CI_ENB_IP_ADDR"; + + ENB_INTERFACE_NAME_FOR_S1U = "eth1"; + ENB_IPV4_ADDRESS_FOR_S1U = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_S1U = 2152; # Spec 2152 + + ENB_IPV4_ADDRESS_FOR_X2C = "CI_ENB_IP_ADDR"; + ENB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="debug"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + phy_test_mode = 0; + puSch10xSnr = 160; + puCch10xSnr = 160; + } +); + +THREAD_STRUCT = ( + { + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + worker_config = "ENABLE"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 118; + eNB_instances = [0]; + } +); + +log_config : + { + global_log_level ="info"; + global_log_verbosity ="high"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="high"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="high"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf new file mode 100755 index 0000000000..af72787752 --- /dev/null +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -0,0 +1,291 @@ +Active_gNBs = ( "gNB-Eurecom-5GNRBox"); +# Asn1_verbosity, choice in: none, info, annoying +Asn1_verbosity = "none"; + +gNBs = +( + { + ////////// Identification parameters: + gNB_ID = 0xe00; + + cell_type = "CELL_MACRO_GNB"; + gNB_name = "gNB-Eurecom-5GNRBox"; + + // Tracking area code, 0x0000 and 0xfffe are reserved values + tracking_area_code = 1; + plmn_list = ({mcc = 222; mnc = 01; mnc_length = 2;}); + + tr_s_preference = "local_mac" + + ////////// Physical parameters: + + ssb_SubcarrierOffset = 31; //0; + pdsch_AntennaPorts = 1; + + servingCellConfigCommon = ( + { + #spCellConfigCommon + + physCellId = 0; + +# downlinkConfigCommon + #frequencyInfoDL + # this is 3600 MHz + 84 PRBs@30kHz SCS (same as initial BWP) + absoluteFrequencySSB = 641272; //641032; #641968; 641968=start of ssb at 3600MHz + 82 RBs 641032=center of SSB at center of cell + dl_frequencyBand = 78; + # this is 3600 MHz + dl_absoluteFrequencyPointA = 640000; + #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=84,L=13 (275*(L-1))+RBstart + initialDLBWPlocationAndBandwidth = 6366; //28875; //6366; #6407; #3384; +# subcarrierSpacing +# 0=kHz15, 1=kHz30, 2=kHz60, 3=kHz120 + initialDLBWPsubcarrierSpacing = 1; + #pdcch-ConfigCommon + initialDLBWPcontrolResourceSetZero = 0; + initialDLBWPsearchSpaceZero = 0; + #pdsch-ConfigCommon + #pdschTimeDomainAllocationList (up to 16 entries) + initialDLBWPk0_0 = 0; + #initialULBWPmappingType + #0=typeA,1=typeB + initialDLBWPmappingType_0 = 0; + #this is SS=1,L=13 + initialDLBWPstartSymbolAndLength_0 = 40; + + initialDLBWPk0_1 = 0; + initialDLBWPmappingType_1 = 0; + #this is SS=2,L=12 + initialDLBWPstartSymbolAndLength_1 = 53; + + initialDLBWPk0_2 = 0; + initialDLBWPmappingType_2 = 0; + #this is SS=1,L=12 + initialDLBWPstartSymbolAndLength_2 = 54; + + initialDLBWPk0_3 = 0; + initialDLBWPmappingType_3 = 0; + #this is SS=1,L=4 //5 (4 is for 43, 5 is for 57) + initialDLBWPstartSymbolAndLength_3 = 57; //43; //57; + #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 = 6366; //28875; //6366; #6407; #3384; +# 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 = -118; +#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; +#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; //15; +#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, + # pusch-ConfigCommon (up to 16 elements) + initialULBWPk2_0 = 2; + initialULBWPmappingType_0 = 1 + # this is SS=0 L=11 + initialULBWPstartSymbolAndLength_0 = 55; + + initialULBWPk2_1 = 2; + initialULBWPmappingType_1 = 1; + # this is SS=0 L=12 + initialULBWPstartSymbolAndLength_1 = 69; + + initialULBWPk2_2 = 7; + initialULBWPmappingType_2 = 1; + # this is SS=10 L=4 + initialULBWPstartSymbolAndLength_2 = 52; + + msg3_DeltaPreamble = 1; + p0_NominalWithGrant =-90; + +# 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; #0x80; + +# 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; //8; //7; + nrofDownlinkSymbols = 6; //0; //6; + nrofUplinkSlots = 2; + nrofUplinkSymbols = 4; //0; //4; + + ssPBCH_BlockPower = 10; + } + + ); + + + # ------- SCTP definitions + SCTP : + { + # Number of streams to use in input/output + SCTP_INSTREAMS = 2; + SCTP_OUTSTREAMS = 2; + }; + + + ////////// MME parameters: + mme_ip_address = ( { ipv4 = "CI_MME_IP_ADDR"; + ipv6 = "192:168:30::17"; + active = "yes"; + preference = "ipv4"; + } + ); + + ///X2 + enable_x2 = "yes"; + t_reloc_prep = 1000; /* unit: millisecond */ + tx2_reloc_overall = 2000; /* unit: millisecond */ + target_enb_x2_ip_address = ( + { ipv4 = "CI_FR1_CTL_ENB_IP_ADDR"; + ipv6 = "192:168:30::17"; + preference = "ipv4"; + } + ); + + NETWORK_INTERFACES : + { + + GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "CI_GNB_IP_ADDR"; + GNB_INTERFACE_NAME_FOR_S1U = "eth0"; + GNB_IPV4_ADDRESS_FOR_S1U = "CI_GNB_IP_ADDR"; + GNB_PORT_FOR_S1U = 2152; # Spec 2152 + GNB_IPV4_ADDRESS_FOR_X2C = "CI_GNB_IP_ADDR"; + GNB_PORT_FOR_X2C = 36422; # Spec 36422 + }; + } +); + +MACRLCs = ( + { + num_cc = 1; + tr_s_preference = "local_L1"; + tr_n_preference = "local_RRC"; + } +); + +L1s = ( + { + num_cc = 1; + tr_n_preference = "local_mac"; + } +); + +RUs = ( + { + local_rf = "yes" + nb_tx = 1 + nb_rx = 1 + att_tx = 0 + att_rx = 0; + bands = [7]; + max_pdschReferenceSignalPower = -27; + max_rxgain = 114; + eNB_instances = [0]; + clock_src = "internal"; + } +); + +THREAD_STRUCT = ( + { + #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" + //parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + parallel_config = "PARALLEL_SINGLE_THREAD"; + #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" + worker_config = "WORKER_ENABLE"; + } +); + + log_config : + { + global_log_level ="info"; + global_log_verbosity ="medium"; + hw_log_level ="info"; + hw_log_verbosity ="medium"; + phy_log_level ="info"; + phy_log_verbosity ="medium"; + mac_log_level ="info"; + mac_log_verbosity ="high"; + rlc_log_level ="info"; + rlc_log_verbosity ="medium"; + pdcp_log_level ="info"; + pdcp_log_verbosity ="medium"; + rrc_log_level ="info"; + rrc_log_verbosity ="medium"; + }; + diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 660f068c2c..bec0489dd0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -113,7 +113,7 @@ class OaiCiTest(): self.UEIPAddress = '' self.UEUserName = '' self.UEPassword = '' - self.UE_instance = '' + self.UE_instance = 0 self.UESourceCodePath = '' self.UELogFile = '' self.Build_OAI_UE_args = '' @@ -3172,7 +3172,7 @@ def GetParametersFromXML(action): if action == 'Terminate_eNB': eNB_instance=test.findtext('eNB_instance') - if (RAN.eNB_instance is None): + if (eNB_instance is None): RAN.eNB_instance=0 else: RAN.eNB_instance=int(eNB_instance) @@ -3213,9 +3213,11 @@ def GetParametersFromXML(action): if action == 'Initialize_OAI_UE': CiTestObj.Initialize_OAI_UE_args = test.findtext('Initialize_OAI_UE_args') - CiTestObj.UE_instance = test.findtext('UE_instance') - if (CiTestObj.UE_instance is None): - CiTestObj.UE_instance = '0' + UE_instance = test.findtext('UE_instance') + if (UE_instance is None): + CiTestObj.UE_instance = 0 + else: + CiTestObj.UE_instance = UE_instance #local variable air_interface air_interface = test.findtext('air_interface') @@ -3228,9 +3230,11 @@ def GetParametersFromXML(action): logging.error('OCP UE -- NOT SUPPORTED') if action == 'Terminate_OAI_UE': - RAN.eNB_instance=test.findtext('UE_instance') - if (CiTestObj.UE_instance is None): + UE_instance=test.findtext('UE_instance') + if (UE_instance is None): CiTestObj.UE_instance = '0' + else: + CiTestObj.UE_instance = int(UE_instance) #local variable air_interface air_interface = test.findtext('air_interface') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 054b92a181..ab72739bd2 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -404,9 +404,11 @@ class RANManagement(): localMmeIpAddr = self.epcObj.MmeIPAddress mySSH.command('sed -i -e \'s/CI_MME_IP_ADDR/' + localMmeIpAddr + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_ENB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); + mySSH.command('sed -i -e \'s/CI_GNB_IP_ADDR/' + lIpAddr + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_RCC_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_RRU1_IP_ADDR/' + self.eNB1IPAddress + '/\' ' + ci_full_config_file, '\$', 2); mySSH.command('sed -i -e \'s/CI_RRU2_IP_ADDR/' + self.eNB2IPAddress + '/\' ' + ci_full_config_file, '\$', 2); + mySSH.command('sed -i -e \'s/CI_FR1_CTL_ENB_IP_ADDR/' + self.eNBIPAddress + '/\' ' + ci_full_config_file, '\$', 2); if self.flexranCtrlInstalled and self.flexranCtrlStarted: mySSH.command('sed -i -e \'s/FLEXRAN_ENABLED.*;/FLEXRAN_ENABLED = "yes";/\' ' + ci_full_config_file, '\$', 2); else: diff --git a/ci-scripts/xml_files/fr1_multi_node_test.xml b/ci-scripts/xml_files/fr1_multi_node_test.xml new file mode 100644 index 0000000000..31a703793f --- /dev/null +++ b/ci-scripts/xml_files/fr1_multi_node_test.xml @@ -0,0 +1,77 @@ + + + test-fr1-tm1 + Test-FR1-TM1 + tasks + 1 + + 030000 + 040000 + 000001 + 070000 + 070001 + + + + + + Initialize_eNB + Initialize eNB + -O ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf + 0 + 0 + lte + + + + Initialize_eNB + Initialize gNB + -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf + 1 + 1 + nr + + + + IdleSleep + Sleep + 30 + + + + Terminate_eNB + Terminate eNB + 0 + 0 + + + + Terminate_eNB + Terminate eNB + 1 + 1 + + + + From 765ba2eba3311e70ea42b89d88c79fe34861e6ff Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 31 Jul 2020 09:51:01 +0200 Subject: [PATCH 132/171] CI: last typo Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index bec0489dd0..7499b53ce0 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -3143,7 +3143,7 @@ def GetParametersFromXML(action): RAN.Build_eNB_args=test.findtext('Build_eNB_args') eNB_instance=test.findtext('eNB_instance') if (eNB_instance is None): - RAN.eNB_instance='0' + RAN.eNB_instance=0 else: RAN.eNB_instance=int(eNB_instance) RAN.eNB_serverId=test.findtext('eNB_serverId') @@ -3395,7 +3395,7 @@ if re.match('^TerminateeNB$', mode, re.IGNORECASE): HELP.GenericHelp(CONST.Version) sys.exit('Insufficient Parameter') RAN.eNB_serverId='0' - RAN.eNB_instance='0' + RAN.eNB_instance=0 RAN.eNBSourceCodePath='/tmp/' RAN.TerminateeNB() elif re.match('^TerminateUE$', mode, re.IGNORECASE): From f00ddc79726439a68a3b79a92c2b0761b905a25d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 31 Jul 2020 10:20:38 +0200 Subject: [PATCH 133/171] CI: add OCP pipeline trigger to master pipeline Signed-off-by: Raphael Defosseux --- ci-scripts/Jenkinsfile-gitlab | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/ci-scripts/Jenkinsfile-gitlab b/ci-scripts/Jenkinsfile-gitlab index 8dfa5c4ec4..c3b997a4e8 100644 --- a/ci-scripts/Jenkinsfile-gitlab +++ b/ci-scripts/Jenkinsfile-gitlab @@ -66,7 +66,8 @@ pipeline { "Test-IF4p5-TDD-Band38-Multi-RRU", "Test-eNB-OAI-UE-FDD-Band7", "Test-Mono-FDD-Band13-X2-HO", - "Test-TDD-Band78-gNB-NR-UE" + "Test-TDD-Band78-gNB-NR-UE", + "Test-OCP-FDD-Band7" ]) ansiColor('xterm') } @@ -683,6 +684,25 @@ pipeline { } } } + stage ("Test OAI OCP-eNB - FDD - Band 7 - B210") { + steps { + script { + triggerSlaveJob ('OCPeNB-FDD-Band7-B210', 'Test-OCP-FDD-Band7') + } + } + post { + always { + script { + finalizeSlaveJob('OCPeNB-FDD-Band7-B210') + } + } + failure { + script { + currentBuild.result = 'FAILURE' + } + } + } + } } post { always { From a6cd5b2d34a198e1f261e7042c0389b8d75d8d1c Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 31 Jul 2020 11:54:29 +0200 Subject: [PATCH 134/171] CI: no more usage of 'daemon' for launch soft-modem executables Signed-off-by: Raphael Defosseux --- ci-scripts/main.py | 4 +--- ci-scripts/ran.py | 11 ++--------- doc/TESTING_GNB_W_COTS_UE.md | 6 +++--- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 7499b53ce0..32742f3e88 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -387,9 +387,7 @@ class OaiCiTest(): while (doOutterLoop): SSH.command('cd ' + self.UESourceCodePath + '/cmake_targets/ran_build/build', '\$', 5) SSH.command('echo ' + self.UEPassword + ' | sudo -S rm -Rf ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log', '\$', 5) - #use nohup instead of daemon - #SSH.command('echo ' + self.UEPassword + ' | sudo -S -E daemon --inherit --unsafe --name=ue' + str(self.UE_instance) + '_daemon --chdir=' + self.UESourceCodePath + '/cmake_targets/ran_build/build -o ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh', '\$', 5) - SSH.command('echo $USER; nohup sudo ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5) + SSH.command('echo $USER; nohup sudo -E ./my-lte-uesoftmodem-run' + str(self.UE_instance) + '.sh' + ' > ' + self.UESourceCodePath + '/cmake_targets/ue_' + self.testCase_id + '.log ' + ' 2>&1 &', self.UEUserName, 5) time.sleep(6) SSH.command('cd ../..', '\$', 5) doLoop = True diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index ab72739bd2..936eeb3227 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -205,9 +205,8 @@ class RANManagement(): if self.backgroundBuild: mySSH.command('echo "./build_oai ' + self.Build_eNB_args + '" > ./my-lte-softmodem-build.sh', '\$', 5) mySSH.command('chmod 775 ./my-lte-softmodem-build.sh', '\$', 5) - #mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=build_enb_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ./my-lte-softmodem-build.sh', '\$', 5) mySSH.command('echo ' + lPassWord + ' | sudo -S ls', '\$', 5) - mySSH.command('echo $USER; nohup sudo ./my-lte-softmodem-build.sh' + ' > ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ' + ' 2>&1 &', lUserName, 5) + mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-build.sh' + ' > ' + lSourcePath + '/cmake_targets/compile_oai_enb.log ' + ' 2>&1 &', lUserName, 5) mySSH.close() if self.htmlObj is not None: self.htmlObj.CreateHtmlTestRow(self.Build_eNB_args, 'OK', CONST.ALL_PROCESSES_OK) @@ -434,12 +433,7 @@ class RANManagement(): mySSH.command('echo "ulimit -c unlimited && ./ran_build/build/' + self.air_interface[self.eNB_instance] + ' -O ' + lSourcePath + '/' + ci_full_config_file + extra_options + '" > ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.command('chmod 775 ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) mySSH.command('echo ' + lPassWord + ' | sudo -S rm -Rf enb_' + self.testCase_id + '.log', '\$', 5) - mySSH.command('hostnamectl','\$', 5) - result = re.search('CentOS Linux 7', mySSH.getBefore()) - if result is not None: - mySSH.command('echo $USER; nohup sudo ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10) - else: - mySSH.command('echo ' + lPassWord + ' | sudo -S -E daemon --inherit --unsafe --name=enb' + str(self.eNB_instance) + '_daemon --chdir=' + lSourcePath + '/cmake_targets -o ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh', '\$', 5) + mySSH.command('echo $USER; nohup sudo -E ./my-lte-softmodem-run' + str(self.eNB_instance) + '.sh > ' + lSourcePath + '/cmake_targets/enb_' + self.testCase_id + '.log 2>&1 &', lUserName, 10) self.eNBLogFiles[int(self.eNB_instance)] = 'enb_' + self.testCase_id + '.log' if extra_options != '': self.eNBOptions[int(self.eNB_instance)] = extra_options @@ -580,7 +574,6 @@ class RANManagement(): mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5) result = re.search('(-softmodem|ocp)', mySSH.getBefore()) if result is not None: - mySSH.command('echo ' + lPassWord + ' | sudo -S daemon --name=enb' + str(self.eNB_instance) + '_daemon --stop', '\$', 5) mySSH.command('echo ' + lPassWord + ' | sudo -S killall --signal SIGINT -r .*-softmodem ocp-enb || true', '\$', 5) time.sleep(10) mySSH.command('stdbuf -o0 ps -aux | grep --color=never -e softmodem -e ocp-enb | grep -v grep', '\$', 5) diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index e507050239..51fdf25f77 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -146,11 +146,11 @@ These files have to be updated manually to set the IP addresses and frequency. { GNB_INTERFACE_NAME_FOR_S1_MME = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1_MME = "**YOUR_ENB_IP_ADDR**"; + GNB_IPV4_ADDRESS_FOR_S1_MME = "**YOUR_GNB_IP_ADDR**"; GNB_INTERFACE_NAME_FOR_S1U = "eth0"; - GNB_IPV4_ADDRESS_FOR_S1U = "**YOUR_ENB_IP_ADDR**"; + GNB_IPV4_ADDRESS_FOR_S1U = "**YOUR_GNB_IP_ADDR**"; GNB_PORT_FOR_S1U = 2152; # Spec 2152 - GNB_IPV4_ADDRESS_FOR_X2C = "**YOUR_ENB_IP_ADDR**"; + GNB_IPV4_ADDRESS_FOR_X2C = "**YOUR_GNB_IP_ADDR**"; GNB_PORT_FOR_X2C = 36422; # Spec 36422 }; From 3ec2a46fd37c33bfba0509036e3719a47dccc761 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 31 Jul 2020 14:40:52 +0200 Subject: [PATCH 135/171] CI: fix clock management in FR1 conf files Signed-off-by: Raphael Defosseux --- .../conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf | 3 ++- .../conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf index 085c5d0ab3..5b2c90a714 100755 --- a/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf +++ b/ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf @@ -27,7 +27,7 @@ eNBs = node_function = "eNodeB_3GPP"; node_timing = "synch_to_ext_device"; node_synch_ref = 0; - nb_antenna_portsi = 1; + nb_antenna_ports = 1; ue_TransmissionMode = 1; frame_type = "FDD"; tdd_config = 3; @@ -261,6 +261,7 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 118; eNB_instances = [0]; + clock_src = "external"; } ); diff --git a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf index af72787752..92af74c300 100755 --- a/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf +++ b/ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf @@ -98,7 +98,7 @@ gNBs = prach_msg1_FDM = 0; prach_msg1_FrequencyStart = 0; zeroCorrelationZoneConfig = 13; - preambleReceivedTargetPower = -118; + preambleReceivedTargetPower = -100; #preamblTransMax (0...10) = (3,4,5,6,7,8,10,20,50,100,200) preambleTransMax = 6; #powerRampingStep @@ -183,7 +183,7 @@ gNBs = nrofUplinkSlots = 2; nrofUplinkSymbols = 4; //0; //4; - ssPBCH_BlockPower = 10; + ssPBCH_BlockPower = -25; } ); @@ -257,15 +257,15 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - clock_src = "internal"; + clock_src = "external"; } ); THREAD_STRUCT = ( { #three config for level of parallelism "PARALLEL_SINGLE_THREAD", "PARALLEL_RU_L1_SPLIT", or "PARALLEL_RU_L1_TRX_SPLIT" - //parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; - parallel_config = "PARALLEL_SINGLE_THREAD"; + parallel_config = "PARALLEL_RU_L1_TRX_SPLIT"; + //parallel_config = "PARALLEL_SINGLE_THREAD"; #two option for worker "WORKER_DISABLE" or "WORKER_ENABLE" worker_config = "WORKER_ENABLE"; } From a12266b94f69c2b8158f37d269b1826cb1f630b1 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 31 Jul 2020 14:43:05 +0200 Subject: [PATCH 136/171] DOC: point now to CI-used conf files Signed-off-by: Raphael Defosseux --- doc/TESTING_GNB_W_COTS_UE.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index 51fdf25f77..d4381a1ca5 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -82,10 +82,8 @@ Some config examples can be found in the following folder: https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/develop/targets/PROJECTS/GENERIC-LTE-EPC/CONF Also base config files can be found here: -[enb conf file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/enb.conf) -[gnb conf file](https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/rh_doc_update_3/doc/testing_gnb_w_cots_ue_resources/gnb.conf) - -TO DO : attach base confif files +[enb conf file](../ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf) +[gnb conf file](../ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf) These files have to be updated manually to set the IP addresses and frequency. From def42f92d8ccb38b889fdc149957b6a54b75046d Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Fri, 31 Jul 2020 15:07:26 +0200 Subject: [PATCH 137/171] Update TESTING_GNB_W_COTS_UE.md --- doc/TESTING_GNB_W_COTS_UE.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index d4381a1ca5..d2f167164a 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -1,4 +1,5 @@ -STATUS 2020/06/26 : information is up to date, but under continuous improvement +STATUS 2020/07/30 : under continuous improvement ; updated the configuration files links with CI approved reference files + ## Table of Contents ## @@ -78,15 +79,17 @@ https://github.com/OPENAIRINTERFACE/openair-epc-fed/blob/master-documentation/do Each component (EPC, eNB, gNB) has its own configuration file. These config files are passed as arguments of the run command line, using the option -O \ -Some config examples can be found in the following folder: -https://gitlab.eurecom.fr/oai/openairinterface5g/-/tree/develop/targets/PROJECTS/GENERIC-LTE-EPC/CONF - -Also base config files can be found here: +The **REFERENCE** files for eNB and gNB, **used by the CI**, can be found here: [enb conf file](../ci-scripts/conf_files/enb.band7.tm1.fr1.25PRB.usrpb210.conf) [gnb conf file](../ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf) These files have to be updated manually to set the IP addresses and frequency. + +**ATTENTION** : an **EXTERNAL** clock is used to sync the eNB and gNB, +whether the clock is internal or external is defined in the configuration files (!! details needed !!) + + 1- In the **eNB configuration file** : - look for MME IP address, and update the **ipv4 field** with the IP address of the **EPC** server ``` @@ -126,7 +129,7 @@ These files have to be updated manually to set the IP addresses and frequency. } ); ``` -- look for X2 IP address, and update the **4 fields** with the IP address of the **eNB** server (notice : even if -in principle- S1 MME is not required for gNB setting) +- look for X2 IP address, and update the **4 fields** with the IP address of the **eNB** server / **gNB** server as below (notice : even if -in principle- S1 MME is not required for gNB setting) ``` ///X2 From b829d3c9f759d46feef72a16c4bfa6849e5e0e84 Mon Sep 17 00:00:00 2001 From: laurent Date: Fri, 31 Jul 2020 16:04:24 +0200 Subject: [PATCH 138/171] add exit trace and fix a gcc warning --- executables/main-fs6.c | 2 +- executables/main-ocp.c | 2 ++ executables/split_headers.h | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/executables/main-fs6.c b/executables/main-fs6.c index ffa44bd978..d2d64d0959 100644 --- a/executables/main-fs6.c +++ b/executables/main-fs6.c @@ -401,7 +401,7 @@ void sendFs6Ul(PHY_VARS_eNB *eNB, int UE_id, int harq_pid, int segmentID, int16_ hULUE(newUDPheader)->O_ACK=eNB->ulsch[UE_id]->harq_processes[harq_pid]->O_ACK; memcpy(hULUE(newUDPheader)->o_ACK, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK, sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o_ACK)); - hULUE(newUDPheader)->ta=lte_est_timing_advance_pusch(eNB, UE_id); + hULUE(newUDPheader)->ta=lte_est_timing_advance_pusch(&eNB->frame_parms, eNB->pusch_vars[UE_id]->drs_ch_estimates_time); hULUE(newUDPheader)->segment=segmentID; memcpy(hULUE(newUDPheader)->o, eNB->ulsch[UE_id]->harq_processes[harq_pid]->o, sizeof(eNB->ulsch[UE_id]->harq_processes[harq_pid]->o)); diff --git a/executables/main-ocp.c b/executables/main-ocp.c index e4e42b4f23..204067b229 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -97,6 +97,7 @@ void exit_function(const char *file, const char *function, const int line, const if (s != NULL) { printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } + softmodem_printresources(0,(telnet_printfunc_t)printf); close_log_mem(); oai_exit = 1; @@ -1167,6 +1168,7 @@ int main ( int argc, char **argv ) { T_Config_Init(); #endif configure_linux(); + set_softmodem_sighandler(); cpuf=get_cpu_freq_GHz(); set_taus_seed (0); diff --git a/executables/split_headers.h b/executables/split_headers.h index 4e328f74c4..985b1b7dae 100644 --- a/executables/split_headers.h +++ b/executables/split_headers.h @@ -28,6 +28,7 @@ #include #include #include +#include #define CU_PORT "7878" #define DU_PORT "8787" @@ -325,5 +326,6 @@ void fep_full(RU_t *ru, int subframe); void feptx_prec(RU_t *ru,int frame,int subframe); void feptx_ofdm(RU_t *ru, int frame, int subframe); void oai_subframe_ind(uint16_t sfn, uint16_t sf); +void softmodem_printresources(int sig, telnet_printfunc_t pf); extern uint16_t sf_ahead; #endif From de64484fe5bc6132fd13ff6c343cbe682adbe9f6 Mon Sep 17 00:00:00 2001 From: Remi Hardy Date: Fri, 31 Jul 2020 16:11:13 +0200 Subject: [PATCH 139/171] Update TESTING_GNB_W_COTS_UE.md --- doc/TESTING_GNB_W_COTS_UE.md | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/doc/TESTING_GNB_W_COTS_UE.md b/doc/TESTING_GNB_W_COTS_UE.md index d2f167164a..a16b4dbe13 100644 --- a/doc/TESTING_GNB_W_COTS_UE.md +++ b/doc/TESTING_GNB_W_COTS_UE.md @@ -216,26 +216,20 @@ Execute: ``` -For example: -``` -~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./lte-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/enb.band7.tm1.50PRB.usrpb210.conf | tee mylogfile.log -``` - - - **gNB** (on the gNB host) Execute: ``` -~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** | tee **YOUR_LOG_FILE** +~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O **YOUR_GNB_CONF_FILE** -E | tee **YOUR_LOG_FILE** ``` -For example: -``` -~/openairinterface5g/cmake_targets/ran_build/build$ sudo ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf | tee mylogfile.log -``` +**ATTENTION** : for the gNB execution, +The -E option is required to enable the tri-quarter sampling rate when using a B2xx serie USRP +The -E opton is not needed when using a a N300 USRP + ## Test Case From 0e0627736045e29276fdeb030e8f24c41db06aaa Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Fri, 31 Jul 2020 16:14:34 +0200 Subject: [PATCH 140/171] CI: enabling 3/4 sampling rate when running gNB on B210 Signed-off-by: Raphael Defosseux --- ci-scripts/xml_files/fr1_multi_node_test.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/xml_files/fr1_multi_node_test.xml b/ci-scripts/xml_files/fr1_multi_node_test.xml index 31a703793f..d35dd74c2b 100644 --- a/ci-scripts/xml_files/fr1_multi_node_test.xml +++ b/ci-scripts/xml_files/fr1_multi_node_test.xml @@ -46,8 +46,8 @@ Initialize_eNB - Initialize gNB - -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf + Initialize gNB (3/4 sampling rate) + -O ci-scripts/conf_files/gnb.band78.tm1.fr1.106PRB.usrpb210.conf -E 1 1 nr From 381fa7234abb56f93f916dbba6608f23199613d1 Mon Sep 17 00:00:00 2001 From: laurent Date: Mon, 3 Aug 2020 09:20:25 +0200 Subject: [PATCH 141/171] remove need to set /data/opencells-ran/../oaiCloneFapi before calling cmake --- cmake_targets/CMakeLists.txt | 6 +++++- executables/main-ocp.c | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 0b60172747..5db0b1f021 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -27,6 +27,10 @@ cmake_minimum_required (VERSION 3.0) # Base directories, compatible with legacy OAI building # ######################################################### set (OPENAIR_DIR $ENV{OPENAIR_DIR}) +if("${OPENAIR_DIR}" STREQUAL "") + string(REGEX REPLACE "/cmake_targets.*$" "" OPENAIR_DIR ${CMAKE_CURRENT_BINARY_DIR}) +endif() + set (NFAPI_DIR ${OPENAIR_DIR}/nfapi/open-nFAPI) set (NFAPI_USER_DIR ${OPENAIR_DIR}/nfapi/oai_integration) set (OPENAIR1_DIR ${OPENAIR_DIR}/openair1) @@ -2624,7 +2628,7 @@ add_executable(ocp-enb ${CONFIG_SOURCES} ${SHLIB_LOADER_SOURCES} ) -add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer) +add_dependencies(ocp-enb rrc_flag s1ap_flag x2_flag oai_iqplayer coding params_libconfig rfsimulator) target_link_libraries (ocp-enb -Wl,--start-group diff --git a/executables/main-ocp.c b/executables/main-ocp.c index 204067b229..2d96d40c75 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -97,7 +97,6 @@ void exit_function(const char *file, const char *function, const int line, const if (s != NULL) { printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); } - softmodem_printresources(0,(telnet_printfunc_t)printf); close_log_mem(); oai_exit = 1; From 613d603278d770e4ae70c5dc406a57d76626377c Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Aug 2020 11:15:06 +0200 Subject: [PATCH 142/171] CI: few fixes and improvements Signed-off-by: Raphael Defosseux --- ci-scripts/cls_cots_ue.py | 14 ++++++-------- ci-scripts/main.py | 16 ++++++---------- ci-scripts/ran.py | 10 +++++----- .../enb_ocp_usrp210_band7_test_05mhz_tm1.xml | 4 ++-- 4 files changed, 19 insertions(+), 25 deletions(-) diff --git a/ci-scripts/cls_cots_ue.py b/ci-scripts/cls_cots_ue.py index 23feba982b..6954aa3927 100644 --- a/ci-scripts/cls_cots_ue.py +++ b/ci-scripts/cls_cots_ue.py @@ -50,8 +50,7 @@ class CotsUe: def Check_Airplane(self): mySSH = sshconnection.SSHConnection() mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord) - mySSH.command('cd /home/oaici/remi/android-sdk-linux/platform-tools', '\$', 5) - status=mySSH.cde_check_value('sudo ./adb shell settings get global airplane_mode_on ', ['0','1'],5) + status=mySSH.cde_check_value('sudo adb shell settings get global airplane_mode_on ', ['0','1'],5) mySSH.close() return status @@ -59,8 +58,7 @@ class CotsUe: def Set_Airplane(self,target_state_str): mySSH = sshconnection.SSHConnection() mySSH.open(self.UEIPAddr, self.UEUserName, self.UEPassWord) - mySSH.command('cd /home/oaici/remi/android-sdk-linux/platform-tools', '\$', 5) - mySSH.command('sudo ./adb start-server','$',5) + mySSH.command('sudo adb start-server','$',5) logging.info("Toggling COTS UE Airplane mode to : "+target_state_str) current_state = self.Check_Airplane() if target_state_str.lower()=="on": @@ -71,9 +69,9 @@ class CotsUe: #toggle state retry = 0 while (current_state!=target_state) and (retry < self.__SetAirplaneRetry): - mySSH.command('sudo ./adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5) - mySSH.command('sudo ./adb shell input keyevent 20', '\$', 5) - mySSH.command('sudo ./adb shell input tap 968 324', '\$', 5) + mySSH.command('sudo adb shell am start -a android.settings.AIRPLANE_MODE_SETTINGS', '\$', 5) + mySSH.command('sudo adb shell input keyevent 20', '\$', 5) + mySSH.command('sudo adb shell input tap 968 324', '\$', 5) time.sleep(1) current_state = self.Check_Airplane() retry+=1 @@ -82,7 +80,7 @@ class CotsUe: logging.error("Current state is : "+ str(current_state)) else: print("Airplane mode is already "+ target_state_str) - mySSH.command('sudo ./adb kill-server','$',5) + mySSH.command('sudo adb kill-server','$',5) mySSH.close() diff --git a/ci-scripts/main.py b/ci-scripts/main.py index 32742f3e88..d37f205f4e 100644 --- a/ci-scripts/main.py +++ b/ci-scripts/main.py @@ -330,7 +330,7 @@ class OaiCiTest(): check_OAI_UE = False pStatus = self.CheckProcessExist(check_eNB, check_OAI_UE) if (pStatus < 0): - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', pStatus) + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', pStatus) HTML.CreateHtmlTabFooter(False) sys.exit(1) UE_prefix = '' @@ -522,7 +522,7 @@ class OaiCiTest(): SSH.close() if fullSyncStatus and gotSyncStatus and tunnelInterfaceStatus: - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'OK', CONST.ALL_PROCESSES_OK, 'OAI UE') logging.debug('\u001B[1m Initialize OAI UE Completed\u001B[0m') if (self.ADBIPAddress != 'none'): self.UEDevices = [] @@ -535,10 +535,10 @@ class OaiCiTest(): HTML.htmlUEFailureMsg='oaitun_ue1/oaitun_uem1 interfaces are either NOT mounted or NOT configured' else: HTML.htmlUEFailureMsg='oaitun_ue1 interface is either NOT mounted or NOT configured' - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_NO_TUNNEL_INTERFACE, 'OAI UE') else: HTML.htmlUEFailureMsg='nr-uesoftmodem did NOT synced' - HTML.CreateHtmlTestRow(self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') + HTML.CreateHtmlTestRow(self.air_interface + ' ' + self.Initialize_OAI_UE_args, 'KO', CONST.OAI_UE_PROCESS_COULD_NOT_SYNC, 'OAI UE') logging.error('\033[91mInitialize OAI UE Failed! \033[0m') self.AutoTerminateUEandeNB() @@ -1085,11 +1085,7 @@ class OaiCiTest(): sys.exit('Insufficient Parameter') SSH.open(self.ADBIPAddress, self.ADBUserName, self.ADBPassword) if self.ADBCentralized: - if self.ADBIPAddress == '192.168.18.196': - SSH.command('/home/oaici/remi/android-sdk-linux/platform-tools/adb devices', '\$', 15) - else: - SSH.command('adb devices', '\$', 15) - #self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) + SSH.command('adb devices', '\$', 15) self.UEDevices = re.findall("\\\\r\\\\n([A-Za-z0-9]+)\\\\tdevice",SSH.getBefore()) SSH.close() else: @@ -2584,7 +2580,7 @@ class OaiCiTest(): freq = result.group('carrier_frequency') new_freq = re.sub('/[0-9]+','',freq) float_freq = float(new_freq) / 1000000 - HTML.SethtmlUEFailureMsg(HTML.GethtmlUEFailureMsg() + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz') + HTML.htmlUEFailureMsg=HTML.htmlUEFailureMsg + 'DL Freq: ' + ('%.1f' % float_freq) + ' MHz' logging.debug('\033[94m' + " DL Carrier Frequency is: " + str(freq) + '\033[0m') except Exception as e: logging.error('\033[91m' + " DL Carrier Frequency not found" + '\033[0m') diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 936eeb3227..35513493dc 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -343,7 +343,7 @@ class RANManagement(): if (self.pStatus < 0): if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow(self.Initialize_eNB_args, 'KO', self.pStatus) + self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' ' + self.Initialize_eNB_args, 'KO', self.pStatus) self.htmlObj.CreateHtmlTabFooter(False) sys.exit(1) # If tracer options is on, running tshark on EPC side and capture traffic b/ EPC and eNB @@ -450,9 +450,9 @@ class RANManagement(): mySSH.command('killall --signal SIGKILL record', '\$', 5) mySSH.close() doLoop = False - logging.error('\u001B[1;37;41m eNB logging system did not show got sync! \u001B[0m') + logging.error('\u001B[1;37;41m eNB/gNB/ocp-eNB logging system did not show got sync! \u001B[0m') if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow('-O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK) + self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'KO', CONST.ALL_PROCESSES_OK) # In case of T tracer recording, we need to kill tshark on EPC side result = re.search('T_stdout', str(self.Initialize_eNB_args)) if (result is not None) and (self.epcObj is not None): @@ -510,8 +510,8 @@ class RANManagement(): mySSH.close() if self.htmlObj is not None: - self.htmlObj.CreateHtmlTestRow('-O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK) - logging.debug('\u001B[1m Initialize eNB Completed\u001B[0m') + self.htmlObj.CreateHtmlTestRow(self.air_interface[self.eNB_instance] + ' -O ' + config_file + extra_options, 'OK', CONST.ALL_PROCESSES_OK) + logging.debug('\u001B[1m Initialize eNB/gNB/ocp-eNB Completed\u001B[0m') def CheckeNBProcess(self, status_queue): try: diff --git a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml index 854fb8cb19..a4caa77075 100644 --- a/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml +++ b/ci-scripts/xml_files/enb_ocp_usrp210_band7_test_05mhz_tm1.xml @@ -34,14 +34,14 @@ Initialize_eNB - Initialize eNB (FDD/Band7/5MHz) + Initialize OCP-eNB (FDD/Band7/5MHz) -O ci-scripts/conf_files/enb.band7.tm1.25PRB.usrpb210.conf ocp Terminate_eNB - Terminate eNB + Terminate OCP-eNB ocp From 7daa4a2a104bf973995f96e5713e9e4eb2732db0 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Aug 2020 14:02:12 +0200 Subject: [PATCH 143/171] CI: update on FR1 scenarios Signed-off-by: Raphael Defosseux --- .../xml_files/fr1_multi_node_terminate.xml | 50 +++++++++++++++++++ ci-scripts/xml_files/fr1_multi_node_test.xml | 4 +- 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 ci-scripts/xml_files/fr1_multi_node_terminate.xml diff --git a/ci-scripts/xml_files/fr1_multi_node_terminate.xml b/ci-scripts/xml_files/fr1_multi_node_terminate.xml new file mode 100644 index 0000000000..cbaaf8ba99 --- /dev/null +++ b/ci-scripts/xml_files/fr1_multi_node_terminate.xml @@ -0,0 +1,50 @@ + + + test-fr1-tm1 + Test-FR1-TM1 + tasks + 1 + + 070001 + 070000 + + + + + + Terminate_eNB + Terminate eNB + 0 + 0 + + + + Terminate_eNB + Terminate gNB + 1 + 1 + + + + diff --git a/ci-scripts/xml_files/fr1_multi_node_test.xml b/ci-scripts/xml_files/fr1_multi_node_test.xml index d35dd74c2b..8c56f0bcec 100644 --- a/ci-scripts/xml_files/fr1_multi_node_test.xml +++ b/ci-scripts/xml_files/fr1_multi_node_test.xml @@ -29,8 +29,8 @@ 030000 040000 000001 - 070000 070001 + 070000 @@ -68,7 +68,7 @@ Terminate_eNB - Terminate eNB + Terminate gNB 1 1 From a385ad5244c0e7062772dcda711c0f159ab87968 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Mon, 3 Aug 2020 14:03:20 +0200 Subject: [PATCH 144/171] Putting back SIGINT detection for lte-softmodem and initial skeleton to retrieve runtime stats from eNB/gNB Signed-off-by: Raphael Defosseux --- ci-scripts/ran.py | 30 ++++++++++++++++++++++++++++++ openair2/X2AP/x2ap_eNB.c | 4 +++- targets/RT/USER/lte-softmodem.c | 2 ++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 35513493dc..71cdca1019 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -698,7 +698,30 @@ class RANManagement(): X2HO_inNbProcedures = 0 X2HO_outNbProcedures = 0 global_status = CONST.ALL_PROCESSES_OK + # Runtime statistics + runTime = '' + userTime = '' + systemTime = '' + maxPhyMemUsage = '' + nbContextSwitches = '' for line in enb_log_file.readlines(): + # Runtime statistics + result = re.search('Run time:' ,str(line)) + if result is not None: + runTime = str(line).strip() + if runTime != '': + result = re.search('Time executing user inst', str(line)) + if result is not None: + userTime = 'to be decoded - 1' + result = re.search('Time executing system inst', str(line)) + if result is not None: + systemTime = 'to be decoded - 2' + result = re.search('Max. Phy. memory usage:', str(line)) + if result is not None: + maxPhyMemUsage = 'to be decoded - 3' + result = re.search('Number of context switch.*process origin', str(line)) + if result is not None: + nbContextSwitches = 'to be decoded - 4' if X2HO_state == CONST.X2_HO_REQ_STATE__IDLE: result = re.search('target eNB Receives X2 HO Req X2AP_HANDOVER_REQ', str(line)) if result is not None: @@ -955,4 +978,11 @@ class RANManagement(): global_status = CONST.ENB_PROCESS_REALTIME_ISSUE if self.htmlObj is not None: self.htmlObj.HmleNBFailureMsg=htmleNBFailureMsg + # Runtime statistics + if runTime != '': + logging.debug(runTime) + logging.debug('Time executing user inst : ' + userTime) + logging.debug('Time executing system inst : ' + systemTime) + logging.debug('Max Physical Memory Usage : ' + maxPhyMemUsage) + logging.debug('Nb Context Switches : ' + nbContextSwitches) return global_status diff --git a/openair2/X2AP/x2ap_eNB.c b/openair2/X2AP/x2ap_eNB.c index 6a037b8ee3..bd77272747 100644 --- a/openair2/X2AP/x2ap_eNB.c +++ b/openair2/X2AP/x2ap_eNB.c @@ -116,7 +116,9 @@ void x2ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa /* some sanity check - to be refined at some point */ if (sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED) { X2AP_ERROR("x2ap_enb_data_p not NULL and sctp state not SCTP_STATE_ESTABLISHED, what to do?\n"); - abort(); + // Allow for a gracious exit when we kill first the gNB, then the eNB + //abort(); + return; } x2ap_enb_data_p->in_streams = sctp_new_association_resp->in_streams; diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 4715a4e995..26f84e66c0 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -556,6 +556,8 @@ int main ( int argc, char **argv ) MSC_INIT(MSC_E_UTRAN, THREAD_MAX+TASK_MAX); init_opt(); + // to make a graceful exit when ctrl-c is pressed + set_softmodem_sighandler(); check_clock(); #ifndef PACKAGE_VERSION # define PACKAGE_VERSION "UNKNOWN-EXPERIMENTAL" From 1326f6daf714a457de2bb5e46c9fe3a83c526c54 Mon Sep 17 00:00:00 2001 From: matzakos Date: Tue, 4 Aug 2020 14:59:05 +0200 Subject: [PATCH 145/171] NR_RRC_PDCP: Bring back Downlink data scheduling in every opportunity -Schedule IP traffic when it is available and random data when there is no IP traffic --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 138 ++++++------------ openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 2 +- 2 files changed, 45 insertions(+), 95 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 99a0083360..c120981713 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -589,7 +589,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, - int num_slots_per_tdd, + NR_sched_pucch *pucch_sched, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *dlsch_config){ LOG_D(MAC, "In nr_schedule_uss_dlsch_phytest frame %d slot %d\n",frameP,slotP); @@ -597,7 +597,6 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, int post_padding = 0, ta_len = 0, header_length_total = 0, sdu_length_total = 0, num_sdus = 0; int lcid, offset, i, header_length_last, TBS_bytes = 0; int UE_id = 0, CC_id = 0; - int pucch_sched; gNB_MAC_INST *gNB_mac = RC.nrmac[module_idP]; //NR_COMMON_channels_t *cc = nr_mac->common_channels; @@ -621,7 +620,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, ta_len = gNB_mac->ta_len; - /*TBS_bytes = configure_fapi_dl_pdu(module_idP, + TBS_bytes = configure_fapi_dl_pdu(module_idP, dl_req, pucch_sched, dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, @@ -629,112 +628,63 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); if (TBS_bytes == 0) - return;*/ - - //Corresponding to noS1 and EPC_MODE_ENABLED use cases where DLSCH transmissions are scheduled only when there is IP traffic - //at the upper layers - if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test == 0){ + return; - lcid = DL_SCH_LCID_DTCH; + lcid = DL_SCH_LCID_DTCH; - //for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { + //for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - // TODO: check if the lcid is active + // TODO: check if the lcid is active - LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n", - module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); + LOG_D(MAC, "[gNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (TBS %d bytes, len %d)\n", + module_idP, frameP, lcid, TBS_bytes, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3); - //if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { - rlc_status = mac_rlc_status_ind(module_idP, - rnti, - module_idP, - frameP, - slotP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - 0, - 0); + //if (TBS_bytes - ta_len - header_length_total - sdu_length_total - 3 > 0) { + rlc_status = mac_rlc_status_ind(module_idP, + rnti, + module_idP, + frameP, + slotP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + 0, + 0); - if (rlc_status.bytes_in_buffer > 0) { + if (rlc_status.bytes_in_buffer > 0) { - LOG_I(MAC, "configure fapi due to data availability \n"); + LOG_I(MAC, "configure fapi due to data availability \n"); - nr_update_pucch_scheduling(module_idP, UE_id, frameP, slotP, num_slots_per_tdd, &pucch_sched); + LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", + module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, + lcid, header_length_total, TBS_bytes); - TBS_bytes = configure_fapi_dl_pdu(module_idP, - dl_req, - &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], - dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, - dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, - dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); + sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + lcid, + TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, + (char *)&mac_sdus[sdu_length_total], + 0, + 0); - if (TBS_bytes == 0) - return; + LOG_W(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); - LOG_I(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d), TBS_bytes: %d \n \n", - module_idP, frameP, TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, - lcid, header_length_total, TBS_bytes); + sdu_lcids[num_sdus] = lcid; + sdu_length_total += sdu_lengths[num_sdus]; + header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); + header_length_total += header_length_last; - sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, - rnti, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - lcid, - TBS_bytes - ta_len - header_length_total - sdu_length_total - 3, - (char *)&mac_sdus[sdu_length_total], - 0, - 0); + num_sdus++; - LOG_W(MAC, "[gNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n", module_idP, sdu_lengths[num_sdus], lcid); + //ue_sched_ctl->uplane_inactivity_timer = 0; + } - sdu_lcids[num_sdus] = lcid; - sdu_length_total += sdu_lengths[num_sdus]; - header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128); - header_length_total += header_length_last; - - num_sdus++; - - //ue_sched_ctl->uplane_inactivity_timer = 0; - } - else if(ta_len > 0){ - LOG_I(MAC, "configure fapi due to TA \n"); - - nr_update_pucch_scheduling(module_idP, UE_id, frameP, slotP, num_slots_per_tdd, &pucch_sched); - TBS_bytes = configure_fapi_dl_pdu(module_idP, - dl_req, - &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], - dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, - dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, - dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); - - if (TBS_bytes == 0) - return; - } - /*} else { // no TBS_bytes left - break; - }*/ - //} for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) { - - } //if (IS_SOFTMODEM_NOS1 || get_softmodem_params()->phy_test) else { - nr_update_pucch_scheduling(module_idP, UE_id, frameP, slotP, num_slots_per_tdd, &pucch_sched); - TBS_bytes = configure_fapi_dl_pdu(module_idP, - dl_req, - &UE_list->UE_sched_ctrl[UE_id].sched_pucch[pucch_sched], - dlsch_config!=NULL ? dlsch_config->mcsIndex : NULL, - dlsch_config!=NULL ? &dlsch_config->rbSize : NULL, - dlsch_config!=NULL ? &dlsch_config->rbStart : NULL); - - if (TBS_bytes == 0) - return; - - //When the --NOS1 option is not enabled, DLSCH transmissions with random data - //occur every time that the current function is called (dlsch phytest mode) - LOG_D(MAC,"Configuring DL_TX in %d.%d\n", frameP, slotP); // fill dlsch_buffer with random data @@ -759,7 +709,7 @@ void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, } #endif - } // else IS_SOFTMODEM_NOS1 + } // there is at least one SDU or TA command // if (num_sdus > 0 ){ diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 06f1b82f5d..a033363e65 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -151,7 +151,7 @@ void configure_fapi_dl_Tx(module_id_t Mod_idP, void nr_schedule_uss_dlsch_phytest(module_id_t module_idP, frame_t frameP, sub_frame_t slotP, - int num_slots_per_tdd, + NR_sched_pucch *pucch_sched, nfapi_nr_dl_tti_pdsch_pdu_rel15_t *pdsch_config); void nr_schedule_pusch(int Mod_idP, From a4a7de5ffed08dc2179502c5c7d90f3d8a32d729 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 5 Aug 2020 08:57:05 +0200 Subject: [PATCH 146/171] Make restart work again: do not free/copy ru frame_parms --- openair1/PHY/INIT/lte_init_ru.c | 1 - targets/RT/USER/lte-softmodem.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/openair1/PHY/INIT/lte_init_ru.c b/openair1/PHY/INIT/lte_init_ru.c index dddd6b1bd5..baea52083f 100644 --- a/openair1/PHY/INIT/lte_init_ru.c +++ b/openair1/PHY/INIT/lte_init_ru.c @@ -186,7 +186,6 @@ void phy_free_RU(RU_t *ru) { int i,j,p; RU_CALIBRATION *calibration = &ru->calibration; LOG_I(PHY, "Feeing RU signal buffers (if_south %s) nb_tx %d\n", ru_if_types[ru->if_south], ru->nb_tx); - free_and_zero(ru->frame_parms); if (ru->if_south <= REMOTE_IF5) { // this means REMOTE_IF5 or LOCAL_RF, so free memory for time-domain signals for (i = 0; i < ru->nb_tx; i++) free_and_zero(ru->common.txdata[i]); diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 4715a4e995..47480287e4 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -439,8 +439,6 @@ int restart_L1L2(module_id_t enb_id) { RC.ru_mask |= (1 << ru->idx); /* copy the changed frame parameters to the RU */ - /* TODO this should be done for all RUs associated to this eNB */ - memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); set_function_spec_param(RC.ru[enb_id]); /* reset the list of connected UEs in the MAC, since in this process with * loose all UEs (have to reconnect) */ From e761819e28ab9f943bde0b4681a9e10ae518369f Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Wed, 5 Aug 2020 10:10:50 +0200 Subject: [PATCH 147/171] Fix in other functions --- executables/main-ocp.c | 3 --- executables/nr-softmodem.c | 3 --- targets/RT/USER/lte-softmodem.c | 1 - 3 files changed, 7 deletions(-) diff --git a/executables/main-ocp.c b/executables/main-ocp.c index e4e42b4f23..23e92e0a5a 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -1123,9 +1123,6 @@ int restart_L1L2(module_id_t enb_id) { sync_var = -1; pthread_mutex_unlock(&sync_mutex); RC.ru_mask |= (1 << ru->idx); - /* copy the changed frame parameters to the RU */ - /* TODO this should be done for all RUs associated to this eNB */ - memcpy(&ru->frame_parms, &RC.eNB[enb_id][0]->frame_parms, sizeof(LTE_DL_FRAME_PARMS)); /* reset the list of connected UEs in the MAC, since in this process with * loose all UEs (have to reconnect) */ init_UE_info(&RC.mac[enb_id]->UE_info); diff --git a/executables/nr-softmodem.c b/executables/nr-softmodem.c index bf77125975..efc5442a50 100644 --- a/executables/nr-softmodem.c +++ b/executables/nr-softmodem.c @@ -723,9 +723,6 @@ int restart_L1L2(module_id_t gnb_id) { RC.ru_mask |= (1 << ru->idx); - /* copy the changed frame parameters to the RU */ - /* TODO this should be done for all RUs associated to this gNB */ - memcpy(&ru->nr_frame_parms, &RC.gNB[gnb_id]->frame_parms, sizeof(NR_DL_FRAME_PARMS)); set_function_spec_param(RC.ru[gnb_id]); LOG_I(GNB_APP, "attempting to create ITTI tasks\n"); // No more rrc thread, as many race conditions are hidden behind diff --git a/targets/RT/USER/lte-softmodem.c b/targets/RT/USER/lte-softmodem.c index 47480287e4..8429fa6e44 100644 --- a/targets/RT/USER/lte-softmodem.c +++ b/targets/RT/USER/lte-softmodem.c @@ -438,7 +438,6 @@ int restart_L1L2(module_id_t enb_id) { } RC.ru_mask |= (1 << ru->idx); - /* copy the changed frame parameters to the RU */ set_function_spec_param(RC.ru[enb_id]); /* reset the list of connected UEs in the MAC, since in this process with * loose all UEs (have to reconnect) */ From e6f20804b91331f71bd1f011d95f65eea1bd5018 Mon Sep 17 00:00:00 2001 From: matzakos Date: Wed, 5 Aug 2020 15:45:39 +0200 Subject: [PATCH 148/171] Remove dependency from noS1 mode to forward received UL traffic from MAC to RLC --- .../LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 47 +++++++++++-------- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 1 + 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 89c3fe69fe..b222e02241 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -36,6 +36,7 @@ void nr_process_mac_pdu( module_id_t module_idP, + rnti_t rnti, uint8_t CC_id, frame_t frameP, uint8_t *pduP, @@ -219,25 +220,33 @@ void nr_process_mac_pdu( LOG_T(MAC, "\n"); #endif - - if (IS_SOFTMODEM_NOS1){ - if (rx_lcid < NB_RB_MAX && rx_lcid >= UL_SCH_LCID_DTCH) { - - mac_rlc_data_ind(module_idP, - 0x1234, - module_idP, - frameP, - ENB_FLAG_YES, - MBMS_FLAG_NO, - rx_lcid, - (char *) (pdu_ptr + mac_subheader_len), - mac_sdu_len, - 1, - NULL); - } else { - LOG_E(MAC, "[UE %d] Frame %d : unknown LCID %d (gNB %d)\n", module_idP, frameP, rx_lcid, module_idP); - } + if(IS_SOFTMODEM_NOS1){ + mac_rlc_data_ind(module_idP, + 0x1234, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *) (pdu_ptr + mac_subheader_len), + mac_sdu_len, + 1, + NULL); } + else{ + mac_rlc_data_ind(module_idP, + rnti, + module_idP, + frameP, + ENB_FLAG_YES, + MBMS_FLAG_NO, + rx_lcid, + (char *) (pdu_ptr + mac_subheader_len), + mac_sdu_len, + 1, + NULL); + } + break; @@ -303,7 +312,7 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (sduP != NULL){ UE_scheduling_control->ta_update = timing_advance; LOG_D(MAC, "Received PDU at MAC gNB \n"); - nr_process_mac_pdu(gnb_mod_idP, CC_idP, frameP, sduP, sdu_lenP); + nr_process_mac_pdu(gnb_mod_idP, current_rnti, CC_idP, frameP, sduP, sdu_lenP); } } else { diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index a033363e65..69a9899e1c 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -297,6 +297,7 @@ void schedule_fapi_ul_pdu(int Mod_idP, void nr_process_mac_pdu( module_id_t module_idP, + rnti_t rnti, uint8_t CC_id, frame_t frameP, uint8_t *pduP, From cf23c586816b89c6a825c69173e14478d8bf9650 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 5 Aug 2020 18:04:16 +0200 Subject: [PATCH 149/171] CI: fix typo for RAN HTML reporting Signed-off-by: Raphael Defosseux --- ci-scripts/ran.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci-scripts/ran.py b/ci-scripts/ran.py index 71cdca1019..96f28e21fe 100644 --- a/ci-scripts/ran.py +++ b/ci-scripts/ran.py @@ -627,7 +627,7 @@ class RANManagement(): if (copyin_res == -1): logging.debug('\u001B[1;37;41m Could not copy ' + nodeB_prefix + 'NB logfile to analyze it! \u001B[0m') if self.htmlObj is not None: - self.htmlObj.HmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' + self.htmlObj.htmleNBFailureMsg='Could not copy ' + nodeB_prefix + 'NB logfile to analyze it!' self.htmlObj.CreateHtmlTestRow('N/A', 'KO', CONST.ENB_PROCESS_NOLOGFILE_TO_ANALYZE) self.eNBmbmsEnables[int(self.eNB_instance)] = False return @@ -977,7 +977,7 @@ class RANManagement(): htmleNBFailureMsg += rlcMsg + '\n' global_status = CONST.ENB_PROCESS_REALTIME_ISSUE if self.htmlObj is not None: - self.htmlObj.HmleNBFailureMsg=htmleNBFailureMsg + self.htmlObj.htmleNBFailureMsg=htmleNBFailureMsg # Runtime statistics if runTime != '': logging.debug(runTime) From 431ed8bd730a88ed7c4ea191cbdebf40010b100a Mon Sep 17 00:00:00 2001 From: matzakos Date: Wed, 5 Aug 2020 18:42:47 +0200 Subject: [PATCH 150/171] Add GTPU tunnel data request at PDCP to deliver Uplink traffic over S1-U --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 45 +++++++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 2f9a01c8a9..ba59c85fb6 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -394,11 +394,48 @@ static void deliver_sdu_drb(void *_ue, nr_pdcp_entity_t *entity, { extern int nas_sock_fd[]; int len; + nr_pdcp_ue_t *ue = _ue; + MessageDef *message_p; + uint8_t *gtpu_buffer_p; + int rb_id; + int i; + + if(IS_SOFTMODEM_NOS1){ + len = write(nas_sock_fd[0], buf, size); + if (len != size) { + LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + } + else{ + for (i = 0; i < 5; i++) { + if (entity == ue->drb[i]) { + rb_id = i+1; + goto rb_found; + } + } + + LOG_E(PDCP, "%s:%d:%s: fatal, no RB found for ue %d\n", + __FILE__, __LINE__, __FUNCTION__, ue->rnti); + exit(1); + + rb_found: + gtpu_buffer_p = itti_malloc(TASK_PDCP_ENB, TASK_GTPV1_U, + size + GTPU_HEADER_OVERHEAD_MAX); + AssertFatal(gtpu_buffer_p != NULL, "OUT OF MEMORY"); + memcpy(>pu_buffer_p[GTPU_HEADER_OVERHEAD_MAX], buf, size); + message_p = itti_alloc_new_message(TASK_PDCP_ENB, GTPV1U_ENB_TUNNEL_DATA_REQ); + AssertFatal(message_p != NULL, "OUT OF MEMORY"); + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).buffer = gtpu_buffer_p; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).length = size; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).offset = GTPU_HEADER_OVERHEAD_MAX; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rnti = ue->rnti; + GTPV1U_ENB_TUNNEL_DATA_REQ(message_p).rab_id = rb_id + 4; + printf("!!!!!!! deliver_sdu_drb (drb %d) sending message to gtp size %d: ", rb_id, size); + //for (i = 0; i < size; i++) printf(" %2.2x", (unsigned char)buf[i]); + printf("\n"); + itti_send_msg_to_task(TASK_GTPV1_U, INSTANCE_DEFAULT, message_p); - len = write(nas_sock_fd[0], buf, size); - if (len != size) { - LOG_E(PDCP, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); - exit(1); } } From 16ab5979e206c74f4a69299efd8a1bb9523cd2f2 Mon Sep 17 00:00:00 2001 From: Khodr Saaifan Date: Wed, 5 Aug 2020 19:15:00 +0200 Subject: [PATCH 151/171] Extend rfsim to enable muti transmit antennas for gNB+solve beamforming ssb_index 0 when nb_tx>1 --- openair1/PHY/INIT/nr_init_ru.c | 6 +++--- openair1/PHY/INIT/nr_parms.c | 4 ++-- openair1/PHY/MODULATION/beamforming.c | 2 +- targets/ARCH/rfsimulator/simulator.c | 20 ++++++++++--------- .../CONF/gnb.band78.tm1.106PRB.usrpn300.conf | 4 +++- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/openair1/PHY/INIT/nr_init_ru.c b/openair1/PHY/INIT/nr_init_ru.c index 8b70b523a5..28b13112ce 100644 --- a/openair1/PHY/INIT/nr_init_ru.c +++ b/openair1/PHY/INIT/nr_init_ru.c @@ -121,9 +121,9 @@ int nr_phy_init_RU(RU_t *ru) { LOG_E(PHY,"[INIT] %s() RC.nb_nr_L1_inst:%d \n", __FUNCTION__, RC.nb_nr_L1_inst); int beam_count = 0; - if (ru->nb_log_antennas>1) { + if (ru->nb_tx>1) {//Enable beamforming when nb_tx > 1 for (p=0;pnb_log_antennas;p++) { - if ((fp->L_ssb >> p) & 0x01) + if ((fp->L_ssb >> (63-p)) & 0x01)//64 bit-map with the MSB @2⁶³ corresponds to SSB ssb_index 0 beam_count++; } AssertFatal(ru->nb_bfw==(beam_count*ru->nb_tx),"Number of beam weights from config file is %d while the expected number is %d",ru->nb_bfw,(beam_count*ru->nb_tx)); @@ -131,7 +131,7 @@ int nr_phy_init_RU(RU_t *ru) { int l_ind = 0; for (i=0; inb_log_antennas;p++) { - if ((fp->L_ssb >> p) & 0x01) { + if ((fp->L_ssb >> (63-p)) & 0x01) { ru->beam_weights[i][p] = (int32_t **)malloc16_clear(ru->nb_tx*sizeof(int32_t*)); for (j=0; jnb_tx; j++) { ru->beam_weights[i][p][j] = (int32_t *)malloc16_clear(fp->ofdm_symbol_size*sizeof(int32_t)); diff --git a/openair1/PHY/INIT/nr_parms.c b/openair1/PHY/INIT/nr_parms.c index c3fe9c54b1..6045930b17 100644 --- a/openair1/PHY/INIT/nr_parms.c +++ b/openair1/PHY/INIT/nr_parms.c @@ -308,7 +308,7 @@ int nr_init_frame_parms(nfapi_nr_config_request_scf_t* cfg, int num_tx_ant = (cfg == NULL) ? fp->Lmax : cfg->carrier_config.num_tx_ant.value; for (int p=0; pN_ssb += ((fp->L_ssb >> p) & 0x01); + fp->N_ssb += ((fp->L_ssb >> (63-p)) & 0x01); return 0; @@ -389,7 +389,7 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, fp->N_ssb = 0; for (int p=0; pLmax; p++) - fp->N_ssb += ((fp->L_ssb >> p) & 0x01); + fp->N_ssb += ((fp->L_ssb >> (63-p)) & 0x01); return 0; } diff --git a/openair1/PHY/MODULATION/beamforming.c b/openair1/PHY/MODULATION/beamforming.c index 79e220ac37..b1f419b172 100644 --- a/openair1/PHY/MODULATION/beamforming.c +++ b/openair1/PHY/MODULATION/beamforming.c @@ -155,7 +155,7 @@ int nr_beam_precoding(int32_t **txdataF, memset(&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size],0,sizeof(int32_t)*(frame_parms->ofdm_symbol_size)); for (p=0; pL_ssb >> p) & 0x01) { + if ((frame_parms->L_ssb >> (63-p)) & 0x01) { multadd_cpx_vector((int16_t*)&txdataF[p][symbol*frame_parms->ofdm_symbol_size], (int16_t*)beam_weights[p][aa], (int16_t*)&txdataF_BF[aa][symbol*frame_parms->ofdm_symbol_size], diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index b7b435f2d9..f9e2dc2565 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -510,7 +510,7 @@ static bool flushInput(rfsimulator_state_t *t, int timeout, int nsamps_for_initi LOG_E(HW,"UEsock: %d Tx/Rx shift too large Tx:%lu, Rx:%lu\n", fd, t->lastWroteTS, b->lastReceivedTS); pthread_mutex_unlock(&Sockmutex); - b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize]; + b->transferPtr=(char *)&b->circularBuf[(b->lastReceivedTS*b->th.nbAnt)%CirSize]; b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt); } @@ -641,7 +641,7 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo if (reGenerateChannel) random_channel(ptr->channel_model,0); - for (int a=0; achannel_model != NULL ) // apply a channel model rxAddInput( ptr->circularBuf, (struct complex16 *) samplesVoid[a], a, @@ -652,14 +652,16 @@ int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, vo ); else { // no channel modeling sample_t *out=(sample_t *)samplesVoid[a]; - const int64_t base=t->nextTimestamp*nbAnt+a; - for ( int i=0; i < nsamps; i++ ) { - const int idx=(i*nbAnt+base)%CirSize; - out[i].r+=ptr->circularBuf[idx].r; - out[i].i+=ptr->circularBuf[idx].i; - } + int nbAnt_tx = ptr->th.nbAnt;//number of Tx antennas + //LOG_I(HW, "nbAnt_tx %d\n",nbAnt_tx); + for (int i=0; i < nsamps; i++) {//loop over nsamps + for (int a_tx=0; a_txcircularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].r; + out[i].i+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt_tx+a_tx)%CirSize].i; + } // end for a_tx + } // end for i (number of samps) } // end of no channel modeling - } // end for a... + } // end for a (number of rx antennas) } } diff --git a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf index 2c37e0d03f..dbcbb2ed4f 100644 --- a/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf +++ b/targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf @@ -248,7 +248,9 @@ RUs = ( max_pdschReferenceSignalPower = -27; max_rxgain = 114; eNB_instances = [0]; - sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; + #beamforming 1x4 matrix: + bf_weights = [0x00007fff, 0x0000, 0x0000, 0x0000]; + sdr_addrs = "addr=192.168.10.2,mgmt_addr=192.168.10.2,second_addr=192.168.20.2"; clock_src = "external"; } ); From 3514caddc292fd921e7fc77ad64f24670aa50f2d Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 6 Aug 2020 09:06:37 +0200 Subject: [PATCH 152/171] minor warning fixes --- openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c | 8 ++++---- openair1/PHY/TOOLS/nr_phy_scope.c | 3 ++- openair2/LAYER2/MAC/eNB_scheduler_fairRR.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c index d2a8e64749..65bb2edaca 100644 --- a/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c +++ b/openair1/PHY/NR_UE_TRANSPORT/pucch_nr.c @@ -963,7 +963,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, uint64_t b[16]; // limit to 1024-bit encoded length // M_bit is the number of bits of block b (payload after encoding) uint16_t M_bit; - nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,(void*)b,&M_bit); + nr_uci_encoding(payload,nr_bit,pucch_format2_nr,0,nrofSymbols,nrofPRB,1,0,0,&b[0],&M_bit); /* * Implementing TS 38.211 * Subclauses 6.3.2.5.1 Scrambling (PUCCH format 2) @@ -985,7 +985,7 @@ void nr_generate_pucch2(PHY_VARS_NR_UE *ue, /* * Implementing TS 38.211 Subclause 6.3.2.5.1 scrambling format 2 */ - nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,b,btilde); + nr_pucch2_3_4_scrambling(M_bit,rnti,data_scrambling_id,&b[0],btilde); /* * Implementing TS 38.211 Subclause 6.3.2.5.2 modulation format 2 * btilde shall be modulated as described in subclause 5.1 using QPSK @@ -1154,7 +1154,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, //nrofPRB = 2; // only for test purposes if (fmt == pucch_format4_nr) nrofPRB = 1; - nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,(void*)b,&M_bit); + nr_uci_encoding(payload,nr_bit,fmt,is_pi_over_2_bpsk_enabled,nrofSymbols,nrofPRB,n_SF_PUCCH_s,intraSlotFrequencyHopping,add_dmrs,&b[0],&M_bit); /* * Implementing TS 38.211 * Subclauses 6.3.2.6.1 Scrambling (PUCCH formats 3 and 4) @@ -1176,7 +1176,7 @@ void nr_generate_pucch3_4(PHY_VARS_NR_UE *ue, /* * Implementing TS 38.211 Subclause 6.3.2.6.1 scrambling formats 3 and 4 */ - nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,b,btilde); + nr_pucch2_3_4_scrambling(M_bit,rnti,n_id,&b[0],btilde); /* * Implementing TS 38.211 Subclause 6.3.2.6.2 modulation formats 3 and 4 * diff --git a/openair1/PHY/TOOLS/nr_phy_scope.c b/openair1/PHY/TOOLS/nr_phy_scope.c index dfb148d34e..9d5d21f7cb 100644 --- a/openair1/PHY/TOOLS/nr_phy_scope.c +++ b/openair1/PHY/TOOLS/nr_phy_scope.c @@ -400,7 +400,8 @@ static void *scope_thread_gNB(void *arg) { // FILE *gNB_stats = fopen("gNB_stats.txt", "w"); //#endif size_t stksize=0; - pthread_attr_t atr= {0}; + pthread_attr_t atr; + pthread_attr_init(&atr); pthread_attr_getstacksize(&atr, &stksize); pthread_attr_setstacksize(&atr,32*1024*1024 ); sleep(3); // no clean interthread barriers diff --git a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c index 00fd40109d..f6220fa46d 100644 --- a/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c +++ b/openair2/LAYER2/MAC/eNB_scheduler_fairRR.c @@ -2240,7 +2240,7 @@ void ulsch_scheduler_pre_ue_select_fairRR( uint8_t first_ue_total[MAX_NUM_CCs][20]; uint8_t first_ue_id[MAX_NUM_CCs][20]; uint8_t ul_inactivity_num[MAX_NUM_CCs]; - uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={0}; + uint8_t ul_inactivity_id[MAX_NUM_CCs][20]={{0}}; // LTE_DL_FRAME_PARMS *frame_parms; uint8_t ulsch_ue_max_num[MAX_NUM_CCs]; uint16_t saved_ulsch_dci[MAX_NUM_CCs]; From 9dadad8298ab886a7bccffad290e5dce10095612 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 6 Aug 2020 09:10:20 +0200 Subject: [PATCH 153/171] fix enabling of PTRS to set a flag in a bitmap, use "bitmap |= flag", to clear a flag in a bitmap use "bitmap &= ~flag". --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index 8841083796..9f5d4f5ec7 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -954,11 +954,10 @@ void nr_schedule_uss_ulsch_phytest(int Mod_idP, pusch_pdu->pusch_ptrs.ptrs_ports_list = (nfapi_nr_ptrs_ports_t *) malloc(2*sizeof(nfapi_nr_ptrs_ports_t)); pusch_pdu->pusch_ptrs.ptrs_ports_list[0].ptrs_re_offset = 0; - pusch_pdu->pdu_bit_map &= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS + pusch_pdu->pdu_bit_map |= PUSCH_PDU_BITMAP_PUSCH_PTRS; // enable PUSCH PTRS } else{ -// if(1<pusch_ptrs.ptrs_time_density >= pusch_pdu->nr_of_symbols) - pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS + pusch_pdu->pdu_bit_map &= ~PUSCH_PDU_BITMAP_PUSCH_PTRS; // disable PUSCH PTRS } // -------------------------------------------------------------------------------------------------------------------------------------------- From cccb56e57193e7323aa30935243236ccbcaa709a Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Thu, 6 Aug 2020 11:46:39 +0200 Subject: [PATCH 154/171] nr rlc: bug fixes, cleanup - bad values in asn1_utils.c (copy/paste from 4g) - remove hardcoded values (t_reassembly, sn_field_length) - some cleanup --- openair2/LAYER2/nr_rlc/asn1_utils.c | 53 +++++++++++++++++++------ openair2/LAYER2/nr_rlc/asn1_utils.h | 5 ++- openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c | 33 ++------------- 3 files changed, 47 insertions(+), 44 deletions(-) diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.c b/openair2/LAYER2/nr_rlc/asn1_utils.c index 46f7d90da5..43d55af1ac 100644 --- a/openair2/LAYER2/nr_rlc/asn1_utils.c +++ b/openair2/LAYER2/nr_rlc/asn1_utils.c @@ -21,14 +21,14 @@ #include "rlc.h" -int decode_t_reordering(int v) +int decode_t_reassembly(int v) { - static int tab[32] = { - 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, - 90, 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 1600 + static int tab[31] = { + 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, + 95, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200 }; - if (v < 0 || v > 31) { + if (v < 0 || v > 30) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } @@ -72,11 +72,13 @@ int decode_t_poll_retransmit(int v) int decode_poll_pdu(int v) { - static int tab[8] = { - 4, 8, 16, 32, 64, 128, 256, -1 /* -1 means infinity */ + static int tab[24] = { + 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 6144, 8192, 12288, + 16384, 20480, 24576, 28672, 32768, 40960, 49152, 57344, 65536 + -1 /* -1 means infinity */ }; - if (v < 0 || v > 7) { + if (v < 0 || v > 23) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } @@ -86,12 +88,23 @@ int decode_poll_pdu(int v) int decode_poll_byte(int v) { - static int tab[15] = { - 25, 50, 75, 100, 125, 250, 375, 500, 750, 1000, 1250, 1500, 2000, 3000, + static int tab[44] = { + /* KB */ + 1024 * 1, 1024 * 2, 1024 * 5, 1024 * 8, 1024 * 10, + 1024 * 15, 1024 * 25, 1024 * 50, 1024 * 75, 1024 * 100, + 1024 * 125, 1024 * 250, 1024 * 375, 1024 * 500, 1024 * 750, + 1024 * 1000, 1024 * 1250, 1024 * 1500, 1024 * 2000, 1024 * 3000, + 1024 * 4000, 1024 * 4500, 1024 * 5000, 1024 * 5500, 1024 * 6000, + 1024 * 6500, 1024 * 7000, 1024 * 7500, + /* MB */ + 1024 * 1024 * 8, 1024 * 1024 * 9, 1024 * 1024 * 10, 1024 * 1024 * 11, + 1024 * 1024 * 12, 1024 * 1024 * 13, 1024 * 1024 * 14, 1024 * 1024 * 15, + 1024 * 1024 * 16, 1024 * 1024 * 17, 1024 * 1024 * 18, 1024 * 1024 * 20, + 1024 * 1024 * 25, 1024 * 1024 * 30, 1024 * 1024 * 40, -1 /* -1 means infinity */ }; - if (v < 0 || v > 14) { + if (v < 0 || v > 43) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } @@ -114,10 +127,24 @@ int decode_max_retx_threshold(int v) return tab[v]; } -int decode_sn_field_length(int v) +int decode_sn_field_length_um(int v) { static int tab[2] = { - 5, 10 + 6, 12 + }; + + if (v < 0 || v > 1) { + LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); + exit(1); + } + + return tab[v]; +} + +int decode_sn_field_length_am(int v) +{ + static int tab[2] = { + 12, 18 }; if (v < 0 || v > 1) { diff --git a/openair2/LAYER2/nr_rlc/asn1_utils.h b/openair2/LAYER2/nr_rlc/asn1_utils.h index 61394c9c69..cf6309e330 100644 --- a/openair2/LAYER2/nr_rlc/asn1_utils.h +++ b/openair2/LAYER2/nr_rlc/asn1_utils.h @@ -22,12 +22,13 @@ #ifndef _ASN1_UTILS_H_ #define _ASN1_UTILS_H_ -int decode_t_reordering(int v); +int decode_t_reassembly(int v); int decode_t_status_prohibit(int v); int decode_t_poll_retransmit(int v); int decode_poll_pdu(int v); int decode_poll_byte(int v); int decode_max_retx_threshold(int v); -int decode_sn_field_length(int v); +int decode_sn_field_length_um(int v); +int decode_sn_field_length_am(int v); #endif /* _ASN1_UTILS_H_ */ diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index 6d2bec29f7..04e0f5b3d6 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -40,13 +40,10 @@ static nr_rlc_ue_manager_t *nr_rlc_ue_manager; /* TODO: handle time a bit more properly */ -//#if 0 static uint64_t nr_rlc_current_time; static int nr_rlc_current_time_last_frame; static int nr_rlc_current_time_last_subframe; -//#endif -//#if 0 void mac_rlc_data_ind ( const module_id_t module_idP, const rnti_t rntiP, @@ -202,7 +199,6 @@ mac_rlc_status_resp_t mac_rlc_status_ind( ret.head_sdu_is_segmented = 0; return ret; } -//#endif rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( const module_id_t module_idP, @@ -261,7 +257,6 @@ rlc_buffer_occupancy_t mac_rlc_get_buffer_occupancy_ind( int oai_emulation; -//#if 0 rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, const srb_flag_t srb_flagP, const MBMS_flag_t MBMS_flagP, @@ -313,9 +308,7 @@ rlc_op_status_t rlc_data_req (const protocol_ctxt_t *const ctxt_pP, return RLC_OP_STATUS_OK; } -//#endif -//#if 0 int rlc_module_init(int enb_flag) { static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; @@ -336,13 +329,10 @@ int rlc_module_init(int enb_flag) return 0; } -//#endif -//#if 0 void rlc_util_print_hex_octets(comp_name_t componentP, unsigned char *dataP, const signed long sizeP) { } -//#endif static void deliver_sdu(void *_ue, nr_rlc_entity_t *entity, char *buf, int size) { @@ -529,7 +519,7 @@ rb_found: #endif } -__attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) +static void add_srb(int rnti, struct LTE_SRB_ToAddMod *s) { nr_rlc_entity_t *nr_rlc_am; nr_rlc_ue_t *ue; @@ -539,7 +529,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod * int srb_id = s->srb_Identity; int logical_channel_group; - //int t_reordering; int t_status_prohibit; int t_poll_retransmit; int poll_pdu; @@ -582,7 +571,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod * exit(1); } am = &r->choice.explicitValue.choice.am; - //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering); t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); @@ -592,7 +580,6 @@ __attribute__ ((unused)) static void add_srb(int rnti, struct LTE_SRB_ToAddMod * } case LTE_SRB_ToAddMod__rlc_Config_PR_defaultValue: /* default values from 36.331 9.2.1 */ - //t_reordering = 35; t_status_prohibit = 0; t_poll_retransmit = 45; poll_pdu = -1; @@ -646,7 +633,6 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ int channel_id = rlc_BearerConfig->logicalChannelIdentity; int logical_channel_group; - //int t_reordering; int t_status_prohibit; int t_poll_retransmit; int poll_pdu; @@ -679,7 +665,6 @@ static void add_drb_am(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ case NR_RLC_Config_PR_am: { struct NR_RLC_Config__am *am; am = r->choice.am; - //t_reordering = decode_t_reordering(am->dl_AM_RLC.t_Reordering); t_status_prohibit = decode_t_status_prohibit(am->dl_AM_RLC.t_StatusProhibit); t_poll_retransmit = decode_t_poll_retransmit(am->ul_AM_RLC.t_PollRetransmit); poll_pdu = decode_poll_pdu(am->ul_AM_RLC.pollPDU); @@ -734,7 +719,6 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ int channel_id = rlc_BearerConfig->logicalChannelIdentity; int logical_channel_group; - //int t_reordering; int sn_field_length; int t_reassembly; @@ -762,12 +746,12 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ case NR_RLC_Config_PR_um_Bi_Directional: { struct NR_RLC_Config__um_Bi_Directional *um; um = r->choice.um_Bi_Directional; - //t_reordering = decode_t_reordering(um->dl_UM_RLC.t_Reordering); + t_reassembly = decode_t_reassembly(um->dl_UM_RLC.t_Reassembly); if (*um->dl_UM_RLC.sn_FieldLength != *um->ul_UM_RLC.sn_FieldLength) { LOG_E(RLC, "%s:%d:%s: fatal\n", __FILE__, __LINE__, __FUNCTION__); exit(1); } - sn_field_length = decode_sn_field_length(*um->dl_UM_RLC.sn_FieldLength); + sn_field_length = decode_sn_field_length_um(*um->dl_UM_RLC.sn_FieldLength); break; } default: @@ -781,9 +765,6 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ LOG_D(RLC, "%s:%d:%s: warning DRB %d already exist for ue %d, do nothing\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rnti); } else { - /* hack: hardcode values for NR */ - t_reassembly = 35; - sn_field_length = 6; nr_rlc_um = new_nr_rlc_entity_um(1000000, 1000000, deliver_sdu, ue, @@ -797,7 +778,7 @@ static void add_drb_um(int rnti, struct NR_DRB_ToAddMod *s, NR_RLC_BearerConfig_ nr_rlc_manager_unlock(nr_rlc_ue_manager); } -__attribute__ ((unused)) static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, struct NR_RLC_BearerConfig *rlc_BearerConfig) +static void add_drb(int rnti, struct NR_DRB_ToAddMod *s, struct NR_RLC_BearerConfig *rlc_BearerConfig) { switch (rlc_BearerConfig->rlc_Config->present) { case NR_RLC_Config_PR_am: @@ -869,7 +850,6 @@ rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t * const ctxt return RLC_OP_STATUS_OK; } -//#if 0 rlc_op_status_t rrc_rlc_config_req ( const protocol_ctxt_t* const ctxt_pP, const srb_flag_t srb_flagP, @@ -928,16 +908,12 @@ rlc_op_status_t rrc_rlc_config_req ( nr_rlc_manager_unlock(nr_rlc_ue_manager); return RLC_OP_STATUS_OK; } -//#endif -//#if 0 void rrc_rlc_register_rrc (rrc_data_ind_cb_t rrc_data_indP, rrc_data_conf_cb_t rrc_data_confP) { /* nothing to do */ } -//#endif -//#if 0 rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) { LOG_D(RLC, "%s:%d:%s: remove UE %d\n", __FILE__, __LINE__, __FUNCTION__, x->rnti); @@ -947,4 +923,3 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } -//#endif From c95e5deb42c340eda0b7dce2fd5ecc6cc2207311 Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Fri, 7 Aug 2020 10:33:26 +0200 Subject: [PATCH 155/171] add back ssb_perRACH_Occasion, sony phone complains --- openair2/RRC/NR/rrc_gNB_reconfig.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openair2/RRC/NR/rrc_gNB_reconfig.c b/openair2/RRC/NR/rrc_gNB_reconfig.c index c163ef645b..d3eae00ca7 100644 --- a/openair2/RRC/NR/rrc_gNB_reconfig.c +++ b/openair2/RRC/NR/rrc_gNB_reconfig.c @@ -162,9 +162,8 @@ void fill_default_secondaryCellGroup(NR_ServingCellConfigCommon_t *servingcellco secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions= calloc(1,sizeof(struct NR_CFRA__occasions)); memcpy(&secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->rach_ConfigGeneric, &servingcellconfigcommon->uplinkConfigCommon->initialUplinkBWP->rach_ConfigCommon->choice.setup->rach_ConfigGeneric, sizeof(NR_RACH_ConfigGeneric_t)); - //secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long)); - //*secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one; - secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= NULL; + secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion= calloc(1,sizeof(long)); + *secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->occasions->ssb_perRACH_Occasion = NR_CFRA__occasions__ssb_perRACH_Occasion_one; secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.present = NR_CFRA__resources_PR_ssb; secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb = calloc(1,sizeof(struct NR_CFRA__resources__ssb)); secondaryCellGroup->spCellConfig->reconfigurationWithSync->rach_ConfigDedicated->choice.uplink->cfra->resources.choice.ssb->ra_ssb_OccasionMaskIndex = 0; From a75d6088ea3fba3533dcfa36f57e26649d1f8821 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 10 Aug 2020 20:05:40 +0200 Subject: [PATCH 156/171] fix dlschsim by correctly setting dmrsConfigType --- openair1/SIMULATION/NR_PHY/dlschsim.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SIMULATION/NR_PHY/dlschsim.c b/openair1/SIMULATION/NR_PHY/dlschsim.c index f8cf413814..b4069237b8 100644 --- a/openair1/SIMULATION/NR_PHY/dlschsim.c +++ b/openair1/SIMULATION/NR_PHY/dlschsim.c @@ -478,9 +478,9 @@ int main(int argc, char **argv) harq_process->Qm = mod_order; harq_process->rvidx = rvidx; harq_process->R = rate; - harq_process->dmrsConfigType = 1; + harq_process->dmrsConfigType = NFAPI_NR_DMRS_TYPE1; harq_process->dlDmrsSymbPos = 4; - harq_process->n_dmrs_cdm_groups = 1; + harq_process->n_dmrs_cdm_groups = 1; printf("harq process ue mcs = %d Qm = %d, symb %d\n", harq_process->mcs, harq_process->Qm, nb_symb_sch); unsigned char *test_input; test_input = (unsigned char *) malloc16(sizeof(unsigned char) * TBS / 8); From 9bcec8a628c5c59713caf9c8b67f2b81884f2901 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Mon, 10 Aug 2020 20:07:51 +0200 Subject: [PATCH 157/171] hotfix UE configuration for DCI format 1_1 Set n_dmrs_cdm_groups = 1 for now. Should be fixed accordingly to TS 38.214 section 5.1.6.2 using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of TS 38.212 --- openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c index 791fef2a2a..60f331a086 100644 --- a/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c +++ b/openair2/LAYER2/NR_MAC_UE/nr_ue_procedures.c @@ -2878,6 +2878,9 @@ int8_t nr_ue_process_dci(module_id_t module_id, int cc_id, uint8_t gNB_index, dc mac->scc->dmrs_TypeA_Position, dlsch_config_pdu_1_1->number_symbols); dlsch_config_pdu_1_1->dmrsConfigType = mac->DLbwp[0]->bwp_Dedicated->pdsch_Config->choice.setup->dmrs_DownlinkForPDSCH_MappingTypeA->choice.setup->dmrs_Type == NULL ? 0 : 1; + /* TODO: fix number of DM-RS CDM groups without data according to subclause 5.1.6.2 of 3GPP TS 38.214, + using tables 7.3.1.2.2-1, 7.3.1.2.2-2, 7.3.1.2.2-3, 7.3.1.2.2-4 of 3GPP TS 38.212 */ + dlsch_config_pdu_1_1->n_dmrs_cdm_groups = 1; /* VRB_TO_PRB_MAPPING */ if (mac->phy_config.config_req.dl_bwp_dedicated.pdsch_config_dedicated.resource_allocation != 0) dlsch_config_pdu_1_1->vrb_to_prb_mapping = (dci->vrb_to_prb_mapping.val == 0) ? vrb_to_prb_mapping_non_interleaved:vrb_to_prb_mapping_interleaved; From f445bdd3244a3cd09d90b640b46166d7b0c95b18 Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Tue, 11 Aug 2020 11:29:05 +0200 Subject: [PATCH 158/171] CI: fixed typo in the list of allowed methods Signed-off-by: Raphael Defosseux --- ci-scripts/xml_class_list.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci-scripts/xml_class_list.yml b/ci-scripts/xml_class_list.yml index 56890c1fc6..e80063a120 100755 --- a/ci-scripts/xml_class_list.yml +++ b/ci-scripts/xml_class_list.yml @@ -13,7 +13,7 @@ - Initialize_OAI_UE - Terminate_OAI_UE - DataDisable_UE - - DataEnable_ + - DataEnable_UE - CheckStatusUE - Ping - Iperf From 4e674345705f4a5273724502fabc97d36bdd5b0d Mon Sep 17 00:00:00 2001 From: Raphael Defosseux Date: Wed, 12 Aug 2020 14:55:59 +0200 Subject: [PATCH 159/171] BUILD: fix for new API on load_softscope Signed-off-by: Raphael Defosseux --- executables/main-ocp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/executables/main-ocp.c b/executables/main-ocp.c index 2d96d40c75..57d8e455c1 100644 --- a/executables/main-ocp.c +++ b/executables/main-ocp.c @@ -1348,7 +1348,7 @@ int main ( int argc, char **argv ) { // end of CI modifications //getchar(); if(IS_SOFTMODEM_DOFORMS) - load_softscope("enb"); + load_softscope("enb", NULL); itti_wait_tasks_end(); oai_exit=1; From 819ee74123f6c4b1850c90f8bb904abd6f8a53a8 Mon Sep 17 00:00:00 2001 From: Thomas Schlichter Date: Thu, 13 Aug 2020 17:42:13 +0200 Subject: [PATCH 160/171] move up assertions in config_ue.c to satisfy cppcheck --- openair2/LAYER2/NR_MAC_UE/config_ue.c | 49 +++++++++++++++------------ 1 file changed, 28 insertions(+), 21 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_UE/config_ue.c b/openair2/LAYER2/NR_MAC_UE/config_ue.c index 31107aea62..bc98e16d39 100755 --- a/openair2/LAYER2/NR_MAC_UE/config_ue.c +++ b/openair2/LAYER2/NR_MAC_UE/config_ue.c @@ -334,41 +334,50 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){ uint8_t bwp_id = 1, coreset_id = 1, ss_id; NR_ServingCellConfig_t *scd = mac->scg->spCellConfig->spCellConfigDedicated; - NR_BWP_DownlinkCommon_t *bwp_Common = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Common; - NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Dedicated; - NR_SetupRelease_PDCCH_Config_t *pdcch_Config = dl_bwp_Dedicated->pdcch_Config; - NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; - struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; - struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList; - struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList; - struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList; - NR_SearchSpace_t *NR_SearchSpace; - - // check pdcch_Config, pdcch_ConfigCommon and DL BWP AssertFatal(scd->downlinkBWP_ToAddModList != NULL, "downlinkBWP_ToAddModList is null\n"); AssertFatal(scd->downlinkBWP_ToAddModList->list.count == 1, "downlinkBWP_ToAddModList->list->count is %d\n", scd->downlinkBWP_ToAddModList->list.count); - mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]; - AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n"); + + NR_BWP_DownlinkCommon_t *bwp_Common = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Common; AssertFatal(bwp_Common != NULL, "bwp_Common is null\n"); + + NR_BWP_DownlinkDedicated_t *dl_bwp_Dedicated = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]->bwp_Dedicated; + AssertFatal(dl_bwp_Dedicated != NULL, "dl_bwp_Dedicated is null\n"); + + NR_SetupRelease_PDCCH_Config_t *pdcch_Config = dl_bwp_Dedicated->pdcch_Config; AssertFatal(pdcch_Config != NULL, "pdcch_Config is null\n"); + + NR_SetupRelease_PDCCH_ConfigCommon_t *pdcch_ConfigCommon = bwp_Common->pdcch_ConfigCommon; AssertFatal(pdcch_ConfigCommon != NULL, "pdcch_ConfigCommon is null\n"); AssertFatal(pdcch_ConfigCommon->choice.setup->ra_SearchSpace != NULL, "ra_SearchSpace must be available in DL BWP\n"); + + struct NR_PDCCH_ConfigCommon__commonSearchSpaceList *commonSearchSpaceList = pdcch_ConfigCommon->choice.setup->commonSearchSpaceList; + AssertFatal(commonSearchSpaceList != NULL, "commonSearchSpaceList is null\n"); + AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n"); + + struct NR_PDCCH_Config__controlResourceSetToAddModList *controlResourceSetToAddModList = pdcch_Config->choice.setup->controlResourceSetToAddModList; AssertFatal(controlResourceSetToAddModList != NULL, "controlResourceSetToAddModList is null\n"); AssertFatal(controlResourceSetToAddModList->list.count == 1, "controlResourceSetToAddModList->list.count=%d\n", controlResourceSetToAddModList->list.count); - mac->coreset[bwp_id - 1][coreset_id - 1] = controlResourceSetToAddModList->list.array[0]; AssertFatal(controlResourceSetToAddModList->list.array[0] != NULL, "coreset[0][0] is null\n"); - // Check dedicated UL BWP and pass to MAC + struct NR_PDCCH_Config__searchSpacesToAddModList *searchSpacesToAddModList = pdcch_Config->choice.setup->searchSpacesToAddModList; + AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n"); + AssertFatal(searchSpacesToAddModList->list.count > 0, "list of UE specifically configured Search Spaces is empty\n"); + AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count); + + struct NR_UplinkConfig__uplinkBWP_ToAddModList *uplinkBWP_ToAddModList = scd->uplinkConfig->uplinkBWP_ToAddModList; AssertFatal(uplinkBWP_ToAddModList != NULL, "uplinkBWP_ToAddModList is null\n"); AssertFatal(uplinkBWP_ToAddModList->list.count == 1, "uplinkBWP_ToAddModList->list->count is %d\n", uplinkBWP_ToAddModList->list.count); + + // check pdcch_Config, pdcch_ConfigCommon and DL BWP + mac->DLbwp[0] = scd->downlinkBWP_ToAddModList->list.array[bwp_id - 1]; + mac->coreset[bwp_id - 1][coreset_id - 1] = controlResourceSetToAddModList->list.array[0]; + + // Check dedicated UL BWP and pass to MAC mac->ULbwp[0] = uplinkBWP_ToAddModList->list.array[0]; AssertFatal(mac->ULbwp[0]->bwp_Dedicated != NULL, "UL bwp_Dedicated is null\n"); // check available Search Spaces in the searchSpacesToAddModList and pass to MAC // note: the network configures at most 10 Search Spaces per BWP per cell (including UE-specific and common Search Spaces). - AssertFatal(searchSpacesToAddModList != NULL, "searchSpacesToAddModList is null\n"); - AssertFatal(searchSpacesToAddModList->list.count > 0, "list of UE specifically configured Search Spaces is empty\n"); - AssertFatal(searchSpacesToAddModList->list.count < FAPI_NR_MAX_SS_PER_CORESET, "too many searchpaces per coreset %d\n", searchSpacesToAddModList->list.count); for (ss_id = 0; ss_id < searchSpacesToAddModList->list.count; ss_id++) { NR_SearchSpace_t *ss = searchSpacesToAddModList->list.array[ss_id]; AssertFatal(ss->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); @@ -381,13 +390,11 @@ void config_control_ue(NR_UE_MAC_INST_t *mac){ // Check available CSSs in the commonSearchSpaceList (list of additional common search spaces) // note: commonSearchSpaceList SIZE(1..4) - AssertFatal(commonSearchSpaceList != NULL, "commonSearchSpaceList is null\n"); - AssertFatal(commonSearchSpaceList->list.count > 0, "PDCCH CSS list has 0 elements\n"); for (int css_id = 0; css_id < commonSearchSpaceList->list.count; css_id++) { NR_SearchSpace_t *css = commonSearchSpaceList->list.array[css_id]; AssertFatal(css->controlResourceSetId != NULL, "ss->controlResourceSetId is null\n"); AssertFatal(*css->controlResourceSetId == mac->coreset[bwp_id - 1][coreset_id - 1]->controlResourceSetId, "ss->controlResourceSetId is unknown\n"); - AssertFatal(css->searchSpaceId != NULL, "css->searchSpaceId is null\n"); + AssertFatal(css->searchSpaceId != 0, "css->searchSpaceId is 0\n"); AssertFatal(css->searchSpaceType != NULL, "css->searchSpaceType is null\n"); AssertFatal(css->monitoringSymbolsWithinSlot != NULL, "css->monitoringSymbolsWithinSlot is null\n"); AssertFatal(css->monitoringSymbolsWithinSlot->buf != NULL, "css->monitoringSymbolsWithinSlot->buf is null\n"); From 4d0d54a98d9b7dc12322dd9f1bcf90b58393f0dd Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Wed, 19 Aug 2020 14:25:03 +0200 Subject: [PATCH 161/171] power target from config file functional --- openair2/GNB_APP/RRC_nr_paramsvalues.h | 11 +------ openair2/GNB_APP/gnb_config.c | 41 +++++++------------------- openair2/GNB_APP/gnb_paramdef.h | 14 +++++++++ 3 files changed, 25 insertions(+), 41 deletions(-) diff --git a/openair2/GNB_APP/RRC_nr_paramsvalues.h b/openair2/GNB_APP/RRC_nr_paramsvalues.h index 94bff8f1a2..231aeb34f4 100644 --- a/openair2/GNB_APP/RRC_nr_paramsvalues.h +++ b/openair2/GNB_APP/RRC_nr_paramsvalues.h @@ -38,10 +38,7 @@ /* cell configuration section name */ #define GNB_CONFIG_STRING_GNB_LIST "gNBs" -#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset" -#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts" -#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10" -#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10" + #define GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON "servingCellConfigCommon" #define GNB_CONFIG_STRING_PHYSCELLID "physCellId" #define GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET "n_TimingAdvanceOffset" @@ -225,12 +222,6 @@ #define GNB_CONFIG_DLCARRIERBANDWIDTH_IDX 10 -#define SSBPARAMS_DESC {{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET,NULL,0,iptr:&ssb_SubcarrierOffset,defintval:0,TYPE_INT,0}} -#define PDSCHANTENNAPARAMS_DESC {{GNB_CONFIG_STRING_PDSCHANTENNAPORTS,NULL,0,iptr:&pdsch_AntennaPorts,defintval:1,TYPE_INT,0}} -#define TARGETPOWER_DESC { \ -{GNB_CONFIG_STRING_PUSCHTARGETPOWX10,NULL,0,iptr:&pusch_TargetSNRx10,defintval:200,TYPE_INT,0},\ -{GNB_CONFIG_STRING_PUCCHTARGETPOWX10,NULL,0,iptr:&pucch_TargetSNRx10,defintval:200,TYPE_INT,0}} - #define SCCPARAMS_DESC(scc) { \ {GNB_CONFIG_STRING_PHYSCELLID,NULL,0,i64ptr:scc->physCellId,defint64val:0,TYPE_INT64,0/*0*/}, \ {GNB_CONFIG_STRING_NTIMINGADVANCEOFFSET,NULL,0,i64ptr:scc->n_TimingAdvanceOffset,defint64val:NR_ServingCellConfigCommon__n_TimingAdvanceOffset_n0,TYPE_INT64,0/*1*/},\ diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 4a05351903..21b8f7a75b 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -529,12 +529,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { prepare_scc(scc); paramdef_t SCCsParams[] = SCCPARAMS_DESC(scc); paramlist_def_t SCCsParamList = {GNB_CONFIG_STRING_SERVINGCELLCONFIGCOMMON, NULL, 0}; - paramdef_t SSBsParams[] = SSBPARAMS_DESC; - paramlist_def_t SSBsParamList = {GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0}; - paramdef_t PDSCHANTENNAParams[] = PDSCHANTENNAPARAMS_DESC; - paramlist_def_t PDSCHANTENNAParamList = {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0}; - paramdef_t PUSCHTARGETPOWParams[] = TARGETPOWER_DESC; - paramlist_def_t PUSCHTARGETPOWParamList = {GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0}; ////////// Physical parameters @@ -583,14 +577,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { } sprintf(aprefix, "%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, 0); - config_getlist(&SSBsParamList, NULL, 0, aprefix); - if (SSBsParamList.numelt > 0) config_get(SSBsParams,sizeof(SSBsParams)/sizeof(paramdef_t),aprefix); - - config_getlist(&PDSCHANTENNAParamList, NULL, 0, aprefix); - if (PDSCHANTENNAParamList.numelt > 0) config_get(PDSCHANTENNAParams,sizeof(PDSCHANTENNAParams)/sizeof(paramdef_t),aprefix); - - config_getlist(&PUSCHTARGETPOWParamList, NULL, 0, aprefix); - if (PUSCHTARGETPOWParamList.numelt > 0) config_get(PUSCHTARGETPOWParams,sizeof(PUSCHTARGETPOWParams)/sizeof(paramdef_t),aprefix); config_getlist(&SCCsParamList, NULL, 0, aprefix); if (SCCsParamList.numelt > 0) { @@ -666,19 +652,16 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { (NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l] == 3),"BAD MNC DIGIT LENGTH %d", NRRRC_CONFIGURATION_REQ (msg_p).mnc_digit_length[l]); } - - // Parse optional physical parameters - sprintf(gnbpath,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k), + printf("SSB SCO %d\n",*GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr); + NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = *GNBParamList.paramarray[i][GNB_SSB_SUBCARRIEROFFSET_IDX].iptr; + printf("pdsch_AntennaPorts %d\n",*GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr); + NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = *GNBParamList.paramarray[i][GNB_PDSCH_ANTENNAPORTS_IDX].iptr; + printf("pusch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr); + NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUSCH_TARGETPOW_X10_IDX].iptr; + printf("pucch_TargetSNRx10 %d\n",*GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr); + NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = *GNBParamList.paramarray[i][GNB_PUCCH_TARGETPOW_X10_IDX].iptr; + NRRRC_CONFIGURATION_REQ (msg_p).scc = scc; - printf("SSB SCO %d\n",ssb_SubcarrierOffset); - NRRRC_CONFIGURATION_REQ (msg_p).ssb_SubcarrierOffset = ssb_SubcarrierOffset; - printf("pdsch_AntennaPorts %d\n",pdsch_AntennaPorts); - NRRRC_CONFIGURATION_REQ (msg_p).pdsch_AntennaPorts = pdsch_AntennaPorts; - printf("pusch_TargetSNRx10 %d\n",pusch_TargetSNRx10); - NRRRC_CONFIGURATION_REQ (msg_p).pusch_TargetSNRx10 = pusch_TargetSNRx10; - printf("pucch_TargetSNRx10 %d\n",pucch_TargetSNRx10); - NRRRC_CONFIGURATION_REQ (msg_p).pucch_TargetSNRx10 = pucch_TargetSNRx10; - NRRRC_CONFIGURATION_REQ (msg_p).scc = scc; }// }//End for (k=0; k 0) { // Output a list of all gNBs. config_getlist( &GNBParamList,GNBParams,sizeof(GNBParams)/sizeof(paramdef_t),NULL); - - - - - + if (GNBParamList.numelt > 0) { for (k = 0; k < GNBParamList.numelt; k++) { if (GNBParamList.paramarray[k][GNB_GNB_ID_IDX].uptr == NULL) { diff --git a/openair2/GNB_APP/gnb_paramdef.h b/openair2/GNB_APP/gnb_paramdef.h index 84045fc622..84da1de530 100644 --- a/openair2/GNB_APP/gnb_paramdef.h +++ b/openair2/GNB_APP/gnb_paramdef.h @@ -113,6 +113,11 @@ typedef enum { #define GNB_CONFIG_STRING_REMOTE_S_PORTC "remote_s_portc" #define GNB_CONFIG_STRING_LOCAL_S_PORTD "local_s_portd" #define GNB_CONFIG_STRING_REMOTE_S_PORTD "remote_s_portd" +#define GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET "ssb_SubcarrierOffset" +#define GNB_CONFIG_STRING_PDSCHANTENNAPORTS "pdsch_AntennaPorts" +#define GNB_CONFIG_STRING_PUSCHTARGETPOWX10 "pusch_TargetSNRx10" +#define GNB_CONFIG_STRING_PUCCHTARGETPOWX10 "pucch_TargetSNRx10" + typedef struct ccparams_nr_x2 { char *frame_type; @@ -156,7 +161,12 @@ typedef struct ccparams_nr_x2 { {GNB_CONFIG_STRING_REMOTE_S_PORTC, NULL, 0, uptr:NULL, defuintval:50000, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_LOCAL_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ {GNB_CONFIG_STRING_REMOTE_S_PORTD, NULL, 0, uptr:NULL, defuintval:50001, TYPE_UINT, 0}, \ +{GNB_CONFIG_STRING_SSBSUBCARRIEROFFSET, NULL, 0, iptr:NULL, defintval:31, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_PDSCHANTENNAPORTS, NULL, 0, iptr:NULL, defintval:1, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_PUSCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ +{GNB_CONFIG_STRING_PUCCHTARGETPOWX10, NULL, 0, iptr:NULL, defintval:200, TYPE_INT, 0}, \ } + #define GNB_GNB_ID_IDX 0 #define GNB_CELL_TYPE_IDX 1 #define GNB_GNB_NAME_IDX 2 @@ -171,6 +181,10 @@ typedef struct ccparams_nr_x2 { #define GNB_REMOTE_S_PORTC_IDX 11 #define GNB_LOCAL_S_PORTD_IDX 12 #define GNB_REMOTE_S_PORTD_IDX 13 +#define GNB_SSB_SUBCARRIEROFFSET_IDX 14 +#define GNB_PDSCH_ANTENNAPORTS_IDX 15 +#define GNB_PUSCH_TARGETPOW_X10_IDX 16 +#define GNB_PUCCH_TARGETPOW_X10_IDX 17 #define TRACKING_AREA_CODE_OKRANGE {0x0001,0xFFFD} #define GNBPARAMS_CHECK { \ From 403956d6c255016dbfb371bb9bea432c1309d66d Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 19 Aug 2020 14:34:05 +0200 Subject: [PATCH 162/171] avoiding race condition for PDSCH tx --- openair1/PHY/INIT/nr_init.c | 2 ++ openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c | 2 +- openair1/PHY/defs_gNB.h | 2 +- openair1/SCHED_NR/fapi_nr_l1.c | 2 +- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 30 +++++++++++----------- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/openair1/PHY/INIT/nr_init.c b/openair1/PHY/INIT/nr_init.c index 33d3fcbd28..0cfda8481e 100644 --- a/openair1/PHY/INIT/nr_init.c +++ b/openair1/PHY/INIT/nr_init.c @@ -506,6 +506,8 @@ void init_nr_transport(PHY_VARS_gNB *gNB) { LOG_I(PHY, "Initialise nr transport\n"); uint16_t grid_size = cfg->carrier_config.dl_grid_size[fp->numerology_index].value; + memset(gNB->num_pdsch_rnti, 0, sizeof(uint16_t)*80); + for (i=0; i pdcch_pdu[i].frame=-1; diff --git a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c index 7702d770ee..ba0bf6b4bf 100644 --- a/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c +++ b/openair1/PHY/NR_TRANSPORT/nr_dlsch_tools.c @@ -291,7 +291,7 @@ void nr_fill_dlsch(PHY_VARS_gNB *gNB, NR_DL_gNB_HARQ_t **harq = dlsch->harq_processes; /// DLSCH struct memcpy((void*)&harq[dlsch->harq_ids[frame%2][slot]]->pdsch_pdu, (void*)pdsch_pdu, sizeof(nfapi_nr_dl_tti_pdsch_pdu)); - gNB->num_pdsch_rnti++; + gNB->num_pdsch_rnti[slot]++; AssertFatal(sdu!=NULL,"sdu is null\n"); harq[dlsch->harq_ids[frame%2][slot]]->pdu = sdu; diff --git a/openair1/PHY/defs_gNB.h b/openair1/PHY/defs_gNB.h index 5bf873978f..5605a85287 100644 --- a/openair1/PHY/defs_gNB.h +++ b/openair1/PHY/defs_gNB.h @@ -691,7 +691,7 @@ typedef struct PHY_VARS_gNB_s { // nfapi_nr_ul_dci_request_pdus_t *ul_dci_pdu; nfapi_nr_dl_tti_ssb_pdu ssb_pdu; - int num_pdsch_rnti; + uint16_t num_pdsch_rnti[80]; NR_gNB_PBCH pbch; nr_cce_t cce_list[MAX_DCI_CORESET][NR_MAX_PDCCH_AGG_LEVEL]; NR_gNB_COMMON common_vars; diff --git a/openair1/SCHED_NR/fapi_nr_l1.c b/openair1/SCHED_NR/fapi_nr_l1.c index 48c0229e80..996cad9d1d 100644 --- a/openair1/SCHED_NR/fapi_nr_l1.c +++ b/openair1/SCHED_NR/fapi_nr_l1.c @@ -154,7 +154,7 @@ void nr_schedule_response(NR_Sched_Rsp_t *Sched_INFO){ number_ul_dci_pdu,number_ul_tti_pdu); int pdcch_received=0; - gNB->num_pdsch_rnti=0; + gNB->num_pdsch_rnti[slot]=0; for (int i=0; idlsch[i][0]->rnti=0; gNB->dlsch[i][0]->harq_mask=0; diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6430e933fd..6371017248 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -191,23 +191,23 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, if (ul_pdcch_pdu_id >= 0) gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].frame = -1; } - for (int i=0; inum_pdsch_rnti; i++) { + for (int i=0; inum_pdsch_rnti[slot]; i++) { VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,1); - LOG_D(PHY, "PDSCH generation started (%d)\n", gNB->num_pdsch_rnti); + LOG_D(PHY, "PDSCH generation started (%d) in frame %d.%d\n", gNB->num_pdsch_rnti[slot],frame,slot); nr_generate_pdsch(gNB->dlsch[i][0], - gNB->nr_gold_pdsch_dmrs[slot], - gNB->common_vars.txdataF, - AMP, frame, slot, fp, 0, - &gNB->dlsch_encoding_stats, - &gNB->dlsch_scrambling_stats, - &gNB->dlsch_modulation_stats, - &gNB->tinput, - &gNB->tprep, - &gNB->tparity, - &gNB->toutput, - &gNB->dlsch_rate_matching_stats, - &gNB->dlsch_interleaving_stats, - &gNB->dlsch_segmentation_stats); + gNB->nr_gold_pdsch_dmrs[slot], + gNB->common_vars.txdataF, + AMP, frame, slot, fp, 0, + &gNB->dlsch_encoding_stats, + &gNB->dlsch_scrambling_stats, + &gNB->dlsch_modulation_stats, + &gNB->tinput, + &gNB->tprep, + &gNB->tparity, + &gNB->toutput, + &gNB->dlsch_rate_matching_stats, + &gNB->dlsch_interleaving_stats, + &gNB->dlsch_segmentation_stats); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_GENERATE_DLSCH,0); } From 44ac0ec19025ce9c00365e56d6da38640d246967 Mon Sep 17 00:00:00 2001 From: Sakthivel Velumani Date: Wed, 19 Aug 2020 15:39:21 +0200 Subject: [PATCH 163/171] fixing a log message --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index 6371017248..eafc81cd91 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -170,8 +170,8 @@ void phy_procedures_gNB_TX(PHY_VARS_gNB *gNB, if (pdcch_pdu_id >= 0 || ul_pdcch_pdu_id >= 0) { LOG_D(PHY, "[gNB %d] Frame %d slot %d Calling nr_generate_dci_top (number of UL/DL DCI %d/%d)\n", gNB->Mod_id, frame, slot, - ul_pdcch_pdu_id==0?0:gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci, - pdcch_pdu_id==0?0:gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci); + gNB->ul_pdcch_pdu[ul_pdcch_pdu_id].pdcch_pdu.pdcch_pdu.pdcch_pdu_rel15.numDlDci, + gNB->pdcch_pdu[pdcch_pdu_id].pdcch_pdu.pdcch_pdu_rel15.numDlDci); VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_PHY_gNB_PDCCH_TX,1); From 35c298d7089d124568ec619d54c95a04fc887616 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Thu, 20 Aug 2020 11:26:10 +0200 Subject: [PATCH 164/171] remove unnecessary declarations --- openair2/GNB_APP/gnb_config.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 21b8f7a75b..716134ad8a 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -520,10 +520,6 @@ void RCconfig_NRRRC(MessageDef *msg_p, uint32_t i, gNB_RRC_INST *rrc) { paramlist_def_t GNBParamList = {GNB_CONFIG_STRING_GNB_LIST,NULL,0}; NR_ServingCellConfigCommon_t *scc = calloc(1,sizeof(NR_ServingCellConfigCommon_t)); - int ssb_SubcarrierOffset = 31; - int pdsch_AntennaPorts = 1; - int pusch_TargetSNRx10 = 200; - int pucch_TargetSNRx10 = 200; uint64_t ssb_bitmap=0xff; memset((void*)scc,0,sizeof(NR_ServingCellConfigCommon_t)); prepare_scc(scc); From 2dffbb75e77b128c49e1574af6ee3cd02a94c0a2 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Thu, 9 Jul 2020 15:39:39 +0200 Subject: [PATCH 165/171] fixing a bug in the prach sequency initialization --- openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c index f40d822b6b..526fc17083 100644 --- a/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c +++ b/openair2/LAYER2/NR_MAC_COMMON/nr_mac_common.c @@ -1151,8 +1151,9 @@ uint8_t compute_nr_root_seq(NR_RACH_ConfigCommon_t *rach_config, if (NCS == 0) return nb_preambles; else { r = L_ra/NCS; - printf(" found_sequences %u\n", (nb_preambles/r)); - return (nb_preambles/r); + found_sequences = (nb_preambles/r) + (nb_preambles%r!=0); //ceil(nb_preambles/r) + printf(" found_sequences %u\n", found_sequences); + return (found_sequences); } } else{ From 09344667c3392ab09a4e5f1a3d36c1726ac9743f Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 21 Aug 2020 15:08:26 +0200 Subject: [PATCH 166/171] fix for unresolved conflict --- openair1/SIMULATION/TOOLS/random_channel.c | 6 +----- targets/ARCH/rfsimulator/simulator.c | 1 + 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/openair1/SIMULATION/TOOLS/random_channel.c b/openair1/SIMULATION/TOOLS/random_channel.c index 505016b279..8c063fadc0 100644 --- a/openair1/SIMULATION/TOOLS/random_channel.c +++ b/openair1/SIMULATION/TOOLS/random_channel.c @@ -666,13 +666,12 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, } break; -<<<<<<< HEAD case TDL_A: case TDL_B: case TDL_C: case TDL_D: - case TDL_E: + case TDL_E: if (channel_model == TDL_A) { tdl_paths=TDL_A_PATHS; tdl_delays=tdl_a_delays; @@ -762,9 +761,6 @@ channel_desc_t *new_channel_desc_scm(uint8_t nb_tx, break; -======= - ->>>>>>> origin/develop case EPA: chan_desc->nb_taps = 7; chan_desc->Td = .410; diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index 1ebfb7c77d..b330e219ba 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -332,6 +332,7 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, channelmod, t->sample_rate, t->tx_bw, + 30e-9, // TDL delay-spread parameter t->chan_forgetfact, // forgetting_factor t->chan_offset, // maybe used for TA t->chan_pathloss); // path_loss in dB From 2f65453508043075e2b4adddd4a31d1ee7e0d454 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Fri, 21 Aug 2020 18:28:44 +0200 Subject: [PATCH 167/171] improved threshold for pucch0 detection --- openair1/PHY/NR_TRANSPORT/pucch_rx.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/openair1/PHY/NR_TRANSPORT/pucch_rx.c b/openair1/PHY/NR_TRANSPORT/pucch_rx.c index 6f551fcce8..4a89e4759e 100644 --- a/openair1/PHY/NR_TRANSPORT/pucch_rx.c +++ b/openair1/PHY/NR_TRANSPORT/pucch_rx.c @@ -340,6 +340,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, } } int32_t corr_re,corr_im,temp,no_corr=0; + int32_t av_corr=0; int seq_index; for(i=0;i%f\n",mcs[i],seq_index,corr_re,corr_im,10*log10(corr_re*corr_re + corr_im*corr_im)); #endif temp=corr_re*corr_re + corr_im*corr_im; - no_corr+=temp; + av_corr+=temp; if (temp>xrtmag) { xrtmag=temp; maxpos=i; } } - no_corr-=xrtmag; - if (nr_sequences>1) - no_corr/=(nr_sequences-1); + if(nr_sequences>1) + no_corr=(av_corr-xrtmag)/(nr_sequences-1); + av_corr/=nr_sequences; uint8_t xrtmag_dB = dB_fixed(xrtmag); @@ -386,6 +387,11 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, else if (SNRtimes10 > 635) cqi=255; else cqi=(640+SNRtimes10)/5; + bool no_conf=false; + if (nr_sequences>1) { + if ((xrtmag_dB<(11+dB_fixed(no_corr))) || (dB_fixed(av_corr)<(13+gNB->measurements.n0_power_tot_dB))) //TODO these are temporary threshold based on measurments with the phone + no_conf=true; + } // first bit of bitmap for sr presence and second bit for acknack presence uci_pdu->pduBitmap = pucch_pdu->sr_flag | ((pucch_pdu->bit_len_harq>0)<<1); uci_pdu->pucch_format = 0; // format 0 @@ -396,7 +402,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, if (pucch_pdu->bit_len_harq==0) { uci_pdu->harq = NULL; uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); - uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+gNB->measurements.n0_power_tot_dB)) ? 1 : 0; + uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(13+gNB->measurements.n0_power_tot_dB)) ? 1 : 0; if (xrtmag_dB>(gNB->measurements.n0_power_tot_dB)) { uci_pdu->sr->sr_indication = 1; } else { @@ -406,7 +412,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, else if (pucch_pdu->bit_len_harq==1) { uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq)); uci_pdu->harq->num_harq = 1; - uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0; + uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0; uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(1); uci_pdu->harq->harq_list[0].harq_value = index&0x01; LOG_I(PHY, "HARQ value %d with confidence level (0 is good, 1 is bad) %d\n", @@ -414,13 +420,13 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); uci_pdu->sr->sr_indication = (index>1) ? 1 : 0; - uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0; + uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0; } } else { uci_pdu->harq = calloc(1,sizeof(*uci_pdu->harq)); uci_pdu->harq->num_harq = 2; - uci_pdu->harq->harq_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0; + uci_pdu->harq->harq_confidence_level = (no_conf) ? 1 : 0; uci_pdu->harq->harq_list = (nfapi_nr_harq_t*)malloc(2); uci_pdu->harq->harq_list[1].harq_value = index&0x01; uci_pdu->harq->harq_list[0].harq_value = (index>>1)&0x01; @@ -429,7 +435,7 @@ void nr_decode_pucch0(PHY_VARS_gNB *gNB, if (pucch_pdu->sr_flag == 1) { uci_pdu->sr = calloc(1,sizeof(*uci_pdu->sr)); uci_pdu->sr->sr_indication = (index>3) ? 1 : 0; - uci_pdu->sr->sr_confidence_level = (xrtmag_dB<(11+dB_fixed(no_corr))) ? 1 : 0; + uci_pdu->sr->sr_confidence_level = (no_conf) ? 1 : 0; } } } From 50dda0e4fe774826d88cbda930a36853faddd955 Mon Sep 17 00:00:00 2001 From: Raymond Knopp Date: Mon, 24 Aug 2020 13:02:19 +0200 Subject: [PATCH 168/171] Remove redundant log --- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c index dd0f30cf4b..00b43f6325 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_phytest.c @@ -260,9 +260,6 @@ int configure_fapi_dl_pdu(int Mod_idP, uint16_t *rbSize, uint16_t *rbStart) { - - LOG_I(MAC, "Inside configure_fapi_dl_pdu() \n"); - gNB_MAC_INST *nr_mac = RC.nrmac[Mod_idP]; NR_COMMON_channels_t *cc = nr_mac->common_channels; NR_ServingCellConfigCommon_t *scc = cc->ServingCellConfigCommon; From 0e02dcf62063ed8bd61bc4113f0821f8841eaec1 Mon Sep 17 00:00:00 2001 From: matzakos Date: Mon, 24 Aug 2020 15:01:18 +0200 Subject: [PATCH 169/171] Modify LCID value for RLC DRB preconfiguration in noS1 mode --- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index ba59c85fb6..c8b385bbfc 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -765,7 +765,7 @@ void nr_DRB_preconfiguration(void) NR_RLC_BearerConfig_t *RLC_BearerConfig = calloc(1,sizeof(*RLC_BearerConfig)); - RLC_BearerConfig->logicalChannelIdentity = 3; + RLC_BearerConfig->logicalChannelIdentity = 4; RLC_BearerConfig->servedRadioBearer = calloc(1,sizeof(*RLC_BearerConfig->servedRadioBearer)); RLC_BearerConfig->servedRadioBearer->present = NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity; From c1b775394fb475809b860a81b4da51756baa4803 Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 24 Aug 2020 16:10:13 +0200 Subject: [PATCH 170/171] tpc update for pusch only if there is signal --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 3 ++- .../LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c | 1 + openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 15 ++++++++++++--- openair2/LAYER2/NR_MAC_gNB/mac_proto.h | 4 +++- openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h | 1 + openair2/NR_PHY_INTERFACE/NR_IF_Module.c | 6 ++++-- 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index eafc81cd91..b90c148786 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -347,7 +347,8 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, gNB->crc_pdu_list[num_crc].num_cb = pusch_pdu->pusch_data.num_cb; gNB->crc_pdu_list[num_crc].ul_cqi = cqi; gNB->crc_pdu_list[num_crc].timing_advance = timing_advance_update; - gNB->crc_pdu_list[num_crc].rssi = 0xffff; // invalid value as this is not yet computed + // in terms of dBFS range -128 to 0 with 0.1 step + gNB->crc_pdu_list[num_crc].rssi = 1280 - (10*dB_fixed(2047*2047)-dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0])); gNB->UL_INFO.crc_ind.number_crcs++; diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c index d899669035..33d0e66996 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_primitives.c @@ -1465,6 +1465,7 @@ int add_new_nr_ue(module_id_t mod_idP, rnti_t rntiP){ memset((void *) &UE_list->UE_sched_ctrl[UE_id], 0, sizeof(NR_UE_sched_ctrl_t)); + UE_list->UE_sched_ctrl[UE_id].ul_rssi = 0; UE_list->UE_sched_ctrl[UE_id].sched_pucch = (NR_sched_pucch *)malloc(num_slots_ul*sizeof(NR_sched_pucch)); UE_list->UE_sched_ctrl[UE_id].sched_pusch = (NR_sched_pusch *)malloc(sizeof(NR_sched_pusch)); LOG_I(MAC, "gNB %d] Add NR UE_id %d : rnti %x\n", diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 7fe0d63efa..19452f8238 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -266,7 +266,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, uint8_t *sduP, const uint16_t sdu_lenP, const uint16_t timing_advance, - const uint8_t ul_cqi){ + const uint8_t ul_cqi, + const uint16_t rssi){ int current_rnti = 0, UE_id = -1, harq_pid = 0; gNB_MAC_INST *gNB_mac = NULL; NR_UE_list_t *UE_list = NULL; @@ -291,6 +292,16 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, UE_id, ul_cqi); + // if not missed detection (10dB threshold for now) + if (UE_scheduling_control->ul_rssi < (100+rssi)) { + UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); + UE_scheduling_control->ta_update = timing_advance; + } + else{ + UE_scheduling_control->tpc0 = 1; + } + UE_scheduling_control->ul_rssi = rssi; + #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n"); for (int i = 0; i < sdu_lenP ; i++) { @@ -302,8 +313,6 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, #endif if (sduP != NULL){ - UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); - UE_scheduling_control->ta_update = timing_advance; LOG_I(MAC, "[UE %d] PUSCH TPC %d and TA %d\n",UE_id,UE_scheduling_control->tpc0,UE_scheduling_control->ta_update); LOG_D(MAC, "Received PDU at MAC gNB \n"); nr_process_mac_pdu(gnb_mod_idP, CC_idP, frameP, sduP, sdu_lenP); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h index 7dd956927b..153f87e38b 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_proto.h +++ b/openair2/LAYER2/NR_MAC_gNB/mac_proto.h @@ -327,6 +327,8 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, const rnti_t rntiP, uint8_t * sduP, const uint16_t sdu_lenP, - const uint16_t timing_advance, const uint8_t ul_cqi); + const uint16_t timing_advance, + const uint8_t ul_cqi, + const uint16_t rssi); #endif /*__LAYER2_NR_MAC_PROTO_H__*/ diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 7d59deb9ae..07f1676d00 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -290,6 +290,7 @@ typedef struct { int16_t ta_update; uint8_t tpc0; uint8_t tpc1; + uint16_t ul_rssi; uint8_t current_harq_pid; NR_UE_harq_t harq_processes[NR_MAX_NB_HARQ_PROCESSES]; NR_UE_ul_harq_t ul_harq_processes[NR_MAX_NB_HARQ_PROCESSES]; diff --git a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c index 5a89ffb5e7..0affc2b023 100644 --- a/openair2/NR_PHY_INTERFACE/NR_IF_Module.c +++ b/openair2/NR_PHY_INTERFACE/NR_IF_Module.c @@ -213,7 +213,8 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) { (uint8_t *)NULL, UL_info->rx_ind.pdu_list[i].pdu_length, UL_info->rx_ind.pdu_list[i].timing_advance, - UL_info->rx_ind.pdu_list[i].ul_cqi); + UL_info->rx_ind.pdu_list[i].ul_cqi, + UL_info->rx_ind.pdu_list[i].rssi); } else { LOG_D(MAC,"Frame %d, Slot %d Calling rx_sdu (CRC ok) \n",UL_info->frame,UL_info->slot); nr_rx_sdu(UL_info->module_id, @@ -224,7 +225,8 @@ void handle_nr_ulsch(NR_UL_IND_t *UL_info, NR_UE_sched_ctrl_t *sched_ctrl) { UL_info->rx_ind.pdu_list[i].pdu, UL_info->rx_ind.pdu_list[i].pdu_length, UL_info->rx_ind.pdu_list[i].timing_advance, - UL_info->rx_ind.pdu_list[i].ul_cqi); + UL_info->rx_ind.pdu_list[i].ul_cqi, + UL_info->rx_ind.pdu_list[i].rssi); } break; } From 664ac4facc07306acaae3b5c06b3825175951a2e Mon Sep 17 00:00:00 2001 From: Francesco Mani Date: Mon, 24 Aug 2020 17:59:30 +0200 Subject: [PATCH 171/171] bugfix on last commit --- openair1/SCHED_NR/phy_procedures_nr_gNB.c | 2 +- openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openair1/SCHED_NR/phy_procedures_nr_gNB.c b/openair1/SCHED_NR/phy_procedures_nr_gNB.c index b90c148786..9607bf9701 100644 --- a/openair1/SCHED_NR/phy_procedures_nr_gNB.c +++ b/openair1/SCHED_NR/phy_procedures_nr_gNB.c @@ -362,7 +362,7 @@ void nr_fill_indication(PHY_VARS_gNB *gNB, int frame, int slot_rx, int ULSCH_id, gNB->rx_pdu_list[num_rx].harq_id = harq_pid; gNB->rx_pdu_list[num_rx].ul_cqi = cqi; gNB->rx_pdu_list[num_rx].timing_advance = timing_advance_update; - gNB->rx_pdu_list[num_rx].rssi = 0xffff; // invalid value as this is not yet computed + gNB->rx_pdu_list[num_rx].rssi = 1280 - (10*dB_fixed(2047*2047)-dB_fixed_times10(gNB->pusch_vars[ULSCH_id]->ulsch_power[0])); if (crc_flag) gNB->rx_pdu_list[num_rx].pdu_length = 0; else { diff --git a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c index 8e6d2547b9..855f4b15f2 100644 --- a/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c +++ b/openair2/LAYER2/NR_MAC_gNB/gNB_scheduler_ulsch.c @@ -305,11 +305,11 @@ void nr_rx_sdu(const module_id_t gnb_mod_idP, if (UE_scheduling_control->ul_rssi < (100+rssi)) { UE_scheduling_control->tpc0 = nr_get_tpc(target_snrx10,ul_cqi,30); UE_scheduling_control->ta_update = timing_advance; + UE_scheduling_control->ul_rssi = rssi; } else{ UE_scheduling_control->tpc0 = 1; } - UE_scheduling_control->ul_rssi = rssi; #if defined(ENABLE_MAC_PAYLOAD_DEBUG) LOG_I(MAC, "Printing received UL MAC payload at gNB side: %d \n");