Merge remote-tracking branch 'origin/develop' into thread_pool_size
# Conflicts: # ci-scripts/conf_files/gNB_SA_n78_106PRB.2x2_usrpn310.conf # ci-scripts/conf_files/gNB_SA_n78_133PRB.2x2_usrpn310.conf # openair2/GNB_APP/L1_nr_paramdef.h # targets/PROJECTS/GENERIC-NR-5GC/CONF/du_gnb.conf
This commit is contained in:
@@ -24,26 +24,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#if !defined (msg)
|
||||
# define msg(aRGS...) LOG_D(PHY, ##aRGS)
|
||||
#endif
|
||||
#ifndef malloc16
|
||||
# ifdef __AVX2__
|
||||
# define malloc16(x) memalign(32,x)
|
||||
# else
|
||||
# define malloc16(x) memalign(16,x)
|
||||
# endif
|
||||
#endif
|
||||
#define free16(y,x) free(y)
|
||||
#define bigmalloc malloc
|
||||
#define bigmalloc16 malloc16
|
||||
#define openair_free(y,x) free((y))
|
||||
#define PAGE_SIZE 4096
|
||||
|
||||
#define PAGE_MASK 0xfffff000
|
||||
#define virt_to_phys(x) (x)
|
||||
|
||||
#define cmax(a,b) ((a>b) ? (a) : (b))
|
||||
#define cmin(a,b) ((a<b) ? (a) : (b))
|
||||
#include <common/utils/utils.h>
|
||||
#endif // /*__openair_DEFS_H__ */
|
||||
|
||||
|
||||
@@ -1510,7 +1510,7 @@ void NRRCConfig(void) {
|
||||
config_get( GNBSParams,sizeof(GNBSParams)/sizeof(paramdef_t),NULL);
|
||||
RC.nb_nr_inst = GNBSParams[GNB_ACTIVE_GNBS_IDX].numelt;
|
||||
|
||||
// Get num MACRLC instances
|
||||
// Get num MACRLC instances
|
||||
config_getlist( &MACRLCParamList,NULL,0, NULL);
|
||||
RC.nb_nr_macrlc_inst = MACRLCParamList.numelt;
|
||||
// Get num L1 instances
|
||||
|
||||
@@ -73,6 +73,8 @@ void fill_ul_config(fapi_nr_ul_config_request_t *ul_config, frame_t frame_tx, in
|
||||
memset(ul_config->ul_config_list, 0, sizeof(ul_config->ul_config_list));
|
||||
}
|
||||
ul_config->ul_config_list[ul_config->number_pdus].pdu_type = pdu_type;
|
||||
//ul_config->slot = slot_tx;
|
||||
//ul_config->sfn = frame_tx;
|
||||
ul_config->slot = slot_tx;
|
||||
ul_config->sfn = frame_tx;
|
||||
ul_config->number_pdus++;
|
||||
@@ -971,6 +973,8 @@ NR_UE_L2_STATE_t nr_ue_scheduler(nr_downlink_indication_t *dl_info, nr_uplink_in
|
||||
uint8_t ulsch_input_buffer_array[NFAPI_MAX_NUM_UL_PDU][MAX_ULSCH_PAYLOAD_BYTES];
|
||||
nr_scheduled_response_t scheduled_response;
|
||||
fapi_nr_tx_request_t tx_req;
|
||||
//tx_req.slot = slot_tx;
|
||||
//tx_req.sfn = frame_tx;
|
||||
tx_req.slot = slot_tx;
|
||||
tx_req.sfn = frame_tx;
|
||||
tx_req.number_of_pdus = 0;
|
||||
|
||||
@@ -272,6 +272,7 @@ bool is_xlsch_in_slot(uint64_t bitmap, sub_frame_t slot) {
|
||||
void gNB_dlsch_ulsch_scheduler(module_id_t module_idP,
|
||||
frame_t frame,
|
||||
sub_frame_t slot){
|
||||
//pthread_mutex_lock(&mutextest);
|
||||
|
||||
protocol_ctxt_t ctxt={0};
|
||||
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frame, slot,module_idP);
|
||||
|
||||
@@ -4293,7 +4293,7 @@ ssize_t do_nrMeasurementReport(uint8_t *buffer,
|
||||
LTE_MeasResultListEUTRA_t *measResultListEUTRA2=&measResultNeighCells->choice.measResultListEUTRA;
|
||||
asn1cSequenceAdd(measResultListEUTRA2->list, struct LTE_MeasResultEUTRA, measresulteutra_list);
|
||||
measresulteutra_list->physCellId = phy_id;
|
||||
asn1cCalloc(measresulteutra_list->cgi_Info, measresult_cgi2);
|
||||
//asn1cCalloc(measresulteutra_list->cgi_Info, measresult_cgi2);
|
||||
//measresult_cgi2->cellGlobalId= {0};
|
||||
//measresult_cgi2->trackingAreaCode= {0};
|
||||
struct LTE_MeasResultEUTRA__measResult* measResult= &measresulteutra_list->measResult;
|
||||
|
||||
@@ -522,6 +522,8 @@ typedef struct gNB_RRC_INST_s {
|
||||
int cell_info_configured;
|
||||
pthread_mutex_t cell_info_mutex;
|
||||
|
||||
char *uecap_file;
|
||||
|
||||
// security configuration (preferred algorithms)
|
||||
nr_security_configuration_t security;
|
||||
} gNB_RRC_INST;
|
||||
|
||||
@@ -202,56 +202,12 @@ static void init_NR_SI(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *configuration
|
||||
pthread_mutex_unlock(&rrc->cell_info_mutex);
|
||||
|
||||
if (get_softmodem_params()->phy_test > 0 || get_softmodem_params()->do_ra > 0) {
|
||||
// This is for phytest only, emulate first X2 message if uecap.raw file is present
|
||||
FILE *fd;
|
||||
fd = fopen("uecap.raw","r");
|
||||
|
||||
if (fd != NULL) {
|
||||
char buffer[4096];
|
||||
int msg_len=fread(buffer,1,4096,fd);
|
||||
LOG_I(RRC,"Read in %d bytes for uecap\n",msg_len);
|
||||
LTE_UL_DCCH_Message_t *LTE_UL_DCCH_Message;
|
||||
asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
|
||||
&asn_DEF_LTE_UL_DCCH_Message,
|
||||
(void **)<E_UL_DCCH_Message,
|
||||
(uint8_t *)buffer,
|
||||
msg_len);
|
||||
|
||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||
AssertFatal(1==0,"NR_UL_DCCH_MESSAGE decode error\n");
|
||||
// free the memory
|
||||
SEQUENCE_free( &asn_DEF_LTE_UL_DCCH_Message, LTE_UL_DCCH_Message, 1 );
|
||||
return;
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
xer_fprint(stdout,&asn_DEF_LTE_UL_DCCH_Message, LTE_UL_DCCH_Message);
|
||||
// recreate enough of X2 EN-DC Container
|
||||
AssertFatal(LTE_UL_DCCH_Message->message.choice.c1.present == LTE_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation,
|
||||
"ueCapabilityInformation not present\n");
|
||||
NR_CG_ConfigInfo_t *CG_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo));
|
||||
CG_ConfigInfo->criticalExtensions.present = NR_CG_ConfigInfo__criticalExtensions_PR_c1;
|
||||
CG_ConfigInfo->criticalExtensions.choice.c1 = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1));
|
||||
CG_ConfigInfo->criticalExtensions.choice.c1->present = NR_CG_ConfigInfo__criticalExtensions__c1_PR_cg_ConfigInfo;
|
||||
CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo = calloc(1,sizeof(*CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo));
|
||||
NR_CG_ConfigInfo_IEs_t *cg_ConfigInfo = CG_ConfigInfo->criticalExtensions.choice.c1->choice.cg_ConfigInfo;
|
||||
cg_ConfigInfo->ue_CapabilityInfo = calloc(1,sizeof(*cg_ConfigInfo->ue_CapabilityInfo));
|
||||
asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_LTE_UE_CapabilityRAT_ContainerList,NULL,
|
||||
(void *)<E_UL_DCCH_Message->message.choice.c1.choice.ueCapabilityInformation.criticalExtensions.choice.c1.choice.ueCapabilityInformation_r8.ue_CapabilityRAT_ContainerList,buffer,4096);
|
||||
AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
|
||||
enc_rval.failed_type->name, enc_rval.encoded);
|
||||
OCTET_STRING_fromBuf(cg_ConfigInfo->ue_CapabilityInfo,
|
||||
(const char *)buffer,
|
||||
(enc_rval.encoded+7)>>3);
|
||||
parse_CG_ConfigInfo(rrc,CG_ConfigInfo,NULL);
|
||||
} else {
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
|
||||
ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
|
||||
ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = configuration->scd;
|
||||
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
|
||||
if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
rrc_add_nsa_user(rrc,ue_context_p,NULL);
|
||||
}
|
||||
struct rrc_gNB_ue_context_s *ue_context_p = rrc_gNB_allocate_new_UE_context(rrc);
|
||||
ue_context_p->ue_context.spCellConfig = calloc(1, sizeof(struct NR_SpCellConfig));
|
||||
ue_context_p->ue_context.spCellConfig->spCellConfigDedicated = configuration->scd;
|
||||
LOG_I(NR_RRC,"Adding new user (%p)\n",ue_context_p);
|
||||
if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) {
|
||||
rrc_add_nsa_user(rrc,ue_context_p,NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "openair2/LAYER2/NR_MAC_gNB/mac_proto.h"
|
||||
#include "openair2/RRC/LTE/rrc_eNB_GTPV1U.h"
|
||||
#include "executables/softmodem-common.h"
|
||||
#include "executables/nr-softmodem.h"
|
||||
#include <openair2/RRC/NR/rrc_gNB_UE_context.h>
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
#include "UTIL/OSA/osa_defs.h"
|
||||
@@ -143,6 +144,30 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc,struct rrc_gNB_ue_context_s *ue_context_
|
||||
unsigned char *kUPenc = NULL;
|
||||
unsigned char *kUPint = NULL;
|
||||
int i;
|
||||
|
||||
// In case of phy-test and do-ra mode, read UE capabilities directly from file
|
||||
if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
|
||||
NR_UE_NR_Capability_t* UE_Capability_nr = NULL;
|
||||
char UE_NR_Capability_xer[65536];
|
||||
FILE *f = NULL;
|
||||
if (uecap_file)
|
||||
f = fopen(uecap_file, "r");
|
||||
if(f){
|
||||
size_t size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
||||
if (size == 0 || size == sizeof UE_NR_Capability_xer)
|
||||
LOG_E(NR_RRC,"UE Capabilities XER file %s is too large (%ld)\n", uecap_file, size);
|
||||
else {
|
||||
UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
||||
asn_dec_rval_t dec_rval = xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&UE_Capability_nr, UE_NR_Capability_xer, size);
|
||||
assert(dec_rval.code == RC_OK);
|
||||
xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr);
|
||||
}
|
||||
}
|
||||
else
|
||||
LOG_E(NR_RRC,"Could not open UE Capabilities input file. Not handling OAI UE Capabilities.\n");
|
||||
ue_context_p->ue_context.UE_Capability_nr = UE_Capability_nr;
|
||||
}
|
||||
|
||||
// NR RRCReconfiguration
|
||||
AssertFatal(rrc->Nb_ue < MAX_NR_RRC_UE_CONTEXTS,"cannot add another UE\n");
|
||||
ue_context_p->ue_context.reconfig = calloc(1,sizeof(NR_RRCReconfiguration_t));
|
||||
|
||||
@@ -34,8 +34,8 @@
|
||||
#include "rrc_proto.h"
|
||||
#include "common/utils/LOG/log.h"
|
||||
|
||||
NR_UE_RRC_INST_t* nr_l3_init_ue(char* rrc_config_path){
|
||||
NR_UE_RRC_INST_t* nr_l3_init_ue(char* uecap, char* rrc_config_path){
|
||||
//LOG_I(RRC, "[MAIN] NR UE MAC initialization...\n");
|
||||
|
||||
return openair_rrc_top_init_ue_nr(rrc_config_path);
|
||||
return openair_rrc_top_init_ue_nr(uecap,rrc_config_path);
|
||||
}
|
||||
|
||||
+34
-13
@@ -422,7 +422,7 @@ void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type,
|
||||
|
||||
}
|
||||
|
||||
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
|
||||
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* rrc_config_path){
|
||||
int nr_ue;
|
||||
if(NB_NR_UE_INST > 0){
|
||||
NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t));
|
||||
@@ -496,6 +496,8 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
|
||||
RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
|
||||
}
|
||||
|
||||
NR_UE_rrc_inst->uecap_file = uecap_file;
|
||||
|
||||
if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
|
||||
// read in files for RRCReconfiguration and RBconfig
|
||||
FILE *fd;
|
||||
@@ -505,7 +507,7 @@ NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
|
||||
else
|
||||
sprintf(filename,"reconfig.raw");
|
||||
fd = fopen(filename,"r");
|
||||
char buffer[1024];
|
||||
char buffer[1024];
|
||||
AssertFatal(fd,
|
||||
"cannot read file %s: errno %d, %s\n",
|
||||
filename,
|
||||
@@ -2634,14 +2636,18 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
//-----------------------------------------------------------------------------
|
||||
{
|
||||
asn_enc_rval_t enc_rval;
|
||||
asn_dec_rval_t dec_rval;
|
||||
NR_UL_DCCH_Message_t ul_dcch_msg;
|
||||
NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container;
|
||||
char UE_NR_Capability_xer[65536];
|
||||
size_t size;
|
||||
uint8_t buffer[200];
|
||||
int i;
|
||||
LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n",
|
||||
ctxt_pP->module_id,
|
||||
ctxt_pP->frame,
|
||||
gNB_index);
|
||||
|
||||
memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
|
||||
memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t));
|
||||
ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
|
||||
@@ -2650,20 +2656,35 @@ nr_rrc_ue_process_ueCapabilityEnquiry(
|
||||
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation));
|
||||
ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
|
||||
ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
|
||||
NR_UE_NR_Capability_t* UE_Capability_nr;
|
||||
UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
||||
NR_BandNR_t *nr_bandnr;
|
||||
nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t));
|
||||
nr_bandnr->bandNR = 1;
|
||||
ASN_SEQUENCE_ADD(
|
||||
&UE_Capability_nr->rf_Parameters.supportedBandListNR.list,
|
||||
nr_bandnr);
|
||||
NR_UE_NR_Capability_t* UE_Capability_nr = NULL;
|
||||
|
||||
char *file_path = NR_UE_rrc_inst[ctxt_pP->module_id].uecap_file;
|
||||
|
||||
FILE *f = NULL;
|
||||
if (file_path)
|
||||
f = fopen(file_path, "r");
|
||||
if(f){
|
||||
size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
|
||||
if (size == 0 || size == sizeof UE_NR_Capability_xer) {
|
||||
LOG_E(NR_RRC,"UE Capabilities XER file %s is too large (%ld)\n", file_path,size);
|
||||
free(UE_Capability_nr);
|
||||
return;
|
||||
}
|
||||
dec_rval = xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&UE_Capability_nr, UE_NR_Capability_xer, size);
|
||||
assert(dec_rval.code == RC_OK);
|
||||
}
|
||||
else {
|
||||
UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
|
||||
NR_BandNR_t *nr_bandnr;
|
||||
nr_bandnr = CALLOC(1,sizeof(NR_BandNR_t));
|
||||
nr_bandnr->bandNR = 1;
|
||||
ASN_SEQUENCE_ADD(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list,
|
||||
nr_bandnr);
|
||||
}
|
||||
OAI_NR_UECapability_t *UECap;
|
||||
UECap = CALLOC(1,sizeof(OAI_NR_UECapability_t));
|
||||
UECap->UE_NR_Capability = UE_Capability_nr;
|
||||
if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
|
||||
xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr);
|
||||
}
|
||||
xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr);
|
||||
|
||||
enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability,
|
||||
NULL,
|
||||
|
||||
@@ -70,7 +70,7 @@ typedef enum {
|
||||
nr_RadioBearerConfigX_r15=1
|
||||
} nsa_message_t;
|
||||
|
||||
#define MAX_UE_NR_CAPABILITY_SIZE 255
|
||||
#define MAX_UE_NR_CAPABILITY_SIZE 2048
|
||||
typedef struct OAI_NR_UECapability_s {
|
||||
uint8_t sdu[MAX_UE_NR_CAPABILITY_SIZE];
|
||||
uint8_t sdu_size;
|
||||
@@ -120,13 +120,15 @@ typedef struct NR_UE_RRC_INST_s {
|
||||
NR_DRB_ToAddMod_t *DRB_config[NB_CNX_UE][8];
|
||||
rb_id_t *defaultDRB; // remember the ID of the default DRB
|
||||
|
||||
NR_SRB_INFO Srb0[NB_SIG_CNX_UE];
|
||||
char *uecap_file;
|
||||
|
||||
NR_SRB_INFO Srb0[NB_SIG_CNX_UE];
|
||||
NR_SRB_INFO_TABLE_ENTRY Srb1[NB_CNX_UE];
|
||||
NR_SRB_INFO_TABLE_ENTRY Srb2[NB_CNX_UE];
|
||||
|
||||
uint8_t MBMS_flag;
|
||||
OAI_NR_UECapability_t *UECap;
|
||||
uint8_t *UECapability;
|
||||
uint8_t *UECapability;
|
||||
uint8_t UECapability_size;
|
||||
|
||||
RA_trigger_t ra_trigger;
|
||||
|
||||
@@ -56,14 +56,14 @@ extern queue_t nr_wait_ul_tti_req_queue;
|
||||
// main_rrc.c
|
||||
//
|
||||
/**\brief Layer 3 initialization*/
|
||||
NR_UE_RRC_INST_t* nr_l3_init_ue(char*);
|
||||
NR_UE_RRC_INST_t* nr_l3_init_ue(char*,char*);
|
||||
|
||||
//
|
||||
// UE_rrc.c
|
||||
//
|
||||
|
||||
/**\brief Initial the top level RRC structure instance*/
|
||||
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*);
|
||||
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char*,char*);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -546,7 +546,7 @@ int main( int argc, char **argv )
|
||||
#endif
|
||||
|
||||
logInit();
|
||||
//configure_linux();
|
||||
//set_latency_target();
|
||||
printf("Reading in command-line options\n");
|
||||
get_options ();
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
|
||||
|
||||
#include "UTIL/MEM/mem_block.h"
|
||||
#include <common/utils/assertions.h>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void list_init (list_t* , char *);
|
||||
@@ -126,10 +128,13 @@ static inline void * dataArray(varArray_t * input) {
|
||||
return input+1;
|
||||
}
|
||||
|
||||
static inline void appendVarArray(varArray_t * input, void* data) {
|
||||
static inline void appendVarArray(varArray_t ** inputPtr, void* data) {
|
||||
varArray_t *input=*inputPtr;
|
||||
if (input->size>=input->mallocedSize) {
|
||||
input->mallocedSize+=input->increment;
|
||||
input=(varArray_t *)realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize);
|
||||
*inputPtr=(varArray_t *)realloc(input,sizeof(varArray_t)+input->mallocedSize*input->atomSize);
|
||||
AssertFatal(*inputPtr, "no memory left");
|
||||
input=*inputPtr;
|
||||
}
|
||||
memcpy((uint8_t*)(input+1)+input->atomSize*input->size++, data, input->atomSize);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user