Merge remote-tracking branch 'origin/develop' into NR_SA_F1AP_5GRECORDS
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#ifndef COMMON_LIB_H
|
||||
#define COMMON_LIB_H
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <openair1/PHY/TOOLS/tools_defs.h>
|
||||
#include "record_player.h"
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include "common_lib.h"
|
||||
#include "ethernet_lib.h"
|
||||
|
||||
@@ -153,7 +153,7 @@ int check_ref_locked(usrp_state_t *s,size_t mboard) {
|
||||
}
|
||||
|
||||
static int sync_to_gps(openair0_device *device) {
|
||||
uhd::set_thread_priority_safe();
|
||||
//uhd::set_thread_priority_safe();
|
||||
//std::string args;
|
||||
//Set up program options
|
||||
//po::options_description desc("Allowed options");
|
||||
@@ -589,7 +589,7 @@ void *trx_usrp_write_thread(void * arg){
|
||||
|
||||
int trx_usrp_write_init(openair0_device *device){
|
||||
|
||||
uhd::set_thread_priority_safe(1.0);
|
||||
//uhd::set_thread_priority_safe(1.0);
|
||||
openair0_thread_t *write_thread = &device->write_thread;
|
||||
printf("initializing tx write thread\n");
|
||||
|
||||
@@ -597,7 +597,8 @@ int trx_usrp_write_init(openair0_device *device){
|
||||
write_thread->end = 0;
|
||||
write_thread->count_write = 0;
|
||||
printf("end of tx write thread\n");
|
||||
|
||||
pthread_mutex_init(&write_thread->mutex_write, NULL);
|
||||
pthread_cond_init(&write_thread->cond_write, NULL);
|
||||
pthread_create(&write_thread->pthread_write,NULL,trx_usrp_write_thread,(void *)device);
|
||||
|
||||
return(0);
|
||||
@@ -948,7 +949,7 @@ extern "C" {
|
||||
|
||||
|
||||
// hotfix! to be checked later
|
||||
uhd::set_thread_priority_safe(1.0);
|
||||
//uhd::set_thread_priority_safe(1.0);
|
||||
// Initialize USRP device
|
||||
int vers=0,subvers=0,subsubvers=0;
|
||||
int bw_gain_adjust=0;
|
||||
@@ -1337,18 +1338,18 @@ extern "C" {
|
||||
if(is_equal(s->sample_rate, (double)7.68e6))
|
||||
s->tx_forward_nsamps = 50;
|
||||
|
||||
recplay_state_t *recPlay=device->recplay_state;
|
||||
recplay_state_t *recPlay=device->recplay_state;
|
||||
|
||||
if (recPlay != NULL) { // record mode
|
||||
recPlay->maxSizeBytes=openair0_cfg[0].recplay_conf->u_sf_max *
|
||||
if (recPlay != NULL) { // record mode
|
||||
recPlay->maxSizeBytes=openair0_cfg[0].recplay_conf->u_sf_max *
|
||||
(sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF);
|
||||
recPlay->ms_sample = (iqrec_t *) malloc(recPlay->maxSizeBytes);
|
||||
recPlay->currentPtr= (uint8_t *)recPlay->ms_sample;
|
||||
recPlay->ms_sample = (iqrec_t *) malloc(recPlay->maxSizeBytes);
|
||||
recPlay->currentPtr= (uint8_t *)recPlay->ms_sample;
|
||||
|
||||
if (recPlay->ms_sample == NULL) {
|
||||
std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
if (recPlay->ms_sample == NULL) {
|
||||
std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -65,17 +65,8 @@ void rxAddInput( struct complex16 *input_sig, struct complex16 *after_channel_si
|
||||
// Fixme: not sure when it is "volts" so dB is 20*log10(...) or "power", so dB is 10*log10(...)
|
||||
const double pathLossLinear = pow(10,channelDesc->path_loss_dB/20.0);
|
||||
// Energy in one sample to calibrate input noise
|
||||
//Fixme: modified the N0W computation, not understand the origin value
|
||||
const double KT=1.38e-23*290; //Boltzman*temperature
|
||||
// sampling rate is linked to acquisition band (the input pass band filter)
|
||||
const double noise_figure_watt = KT*channelDesc->sampling_rate;
|
||||
// Fixme: how to convert a noise in Watt into a 12 bits value out of the RF ADC ?
|
||||
// the parameter "-s" is declared as SNR, but the input power is not well defined
|
||||
// −132.24 dBm is a LTE subcarrier noise, that was used in origin code (15KHz BW thermal noise)
|
||||
const double rxGain= 132.24 - channelmod_get_snr_dB();
|
||||
// sqrt(4*noise_figure_watt) is the thermal noise factor (volts)
|
||||
// fixme: the last constant is pure trial results to make decent noise
|
||||
const double noise_per_sample = sqrt(4*noise_figure_watt) * pow(10,rxGain/20) *10;
|
||||
// the normalized OAI value seems to be 256 as average amplitude (numerical amplification = 1)
|
||||
const double noise_per_sample = pow(10,channelDesc->noise_power_dB/10.0) * 256;
|
||||
// Fixme: we don't fill the offset length samples at begining ?
|
||||
// anyway, in today code, channel_offset=0
|
||||
const int dd = abs(channelDesc->channel_offset);
|
||||
|
||||
@@ -69,7 +69,9 @@ extern RAN_CONTEXT_t RC;
|
||||
|
||||
#define RFSIMU_SECTION "rfsimulator"
|
||||
#define RFSIMU_OPTIONS_PARAMNAME "options"
|
||||
# define RFSIM_CONFIG_HELP_OPTIONS " list of comma separated options to enable rf simulator functionalities. Available options: \n"\
|
||||
|
||||
|
||||
#define RFSIM_CONFIG_HELP_OPTIONS " list of comma separated options to enable rf simulator functionalities. Available options: \n"\
|
||||
" chanmod: enable channel modelisation\n"\
|
||||
" saviq: enable saving written iqs to a file\n"
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
@@ -78,21 +80,21 @@ extern RAN_CONTEXT_t RC;
|
||||
/*-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define simOpt PARAMFLAG_NOFREE|PARAMFLAG_CMDLINE_NOPREFIXENABLED
|
||||
#define RFSIMULATOR_PARAMS_DESC { \
|
||||
{"serveraddr", "<ip address to connect to>\n", simOpt , strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
|
||||
{"serverport", "<port to connect to>\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
|
||||
{RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\
|
||||
{"IQfile", "<file path to use when saving IQs>\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
|
||||
{"modelname", "<channel model name>\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
|
||||
{"ploss", "<channel path loss in dB>\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
|
||||
{"forgetfact", "<channel forget factor ((0 to 1)>\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
|
||||
{"offset", "<channel offset in samps>\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
|
||||
{"serveraddr", "<ip address to connect to>\n", simOpt, strptr:&(rfsimulator->ip), defstrval:"127.0.0.1", TYPE_STRING, 0 },\
|
||||
{"serverport", "<port to connect to>\n", simOpt, u16ptr:&(rfsimulator->port), defuintval:PORT, TYPE_UINT16, 0 },\
|
||||
{RFSIMU_OPTIONS_PARAMNAME, RFSIM_CONFIG_HELP_OPTIONS, 0, strlistptr:NULL, defstrlistval:NULL, TYPE_STRINGLIST,0 },\
|
||||
{"IQfile", "<file path to use when saving IQs>\n",simOpt, strptr:&(saveF), defstrval:"/tmp/rfsimulator.iqs",TYPE_STRING, 0 },\
|
||||
{"modelname", "<channel model name>\n", simOpt, strptr:&(modelname), defstrval:"AWGN", TYPE_STRING, 0 },\
|
||||
{"ploss", "<channel path loss in dB>\n", simOpt, dblptr:&(rfsimulator->chan_pathloss), defdblval:0, TYPE_DOUBLE, 0 },\
|
||||
{"forgetfact", "<channel forget factor ((0 to 1)>\n", simOpt, dblptr:&(rfsimulator->chan_forgetfact), defdblval:0, TYPE_DOUBLE, 0 },\
|
||||
{"offset", "<channel offset in samps>\n", simOpt, iptr:&(rfsimulator->chan_offset), defintval:0, TYPE_INT, 0 }\
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt, void *arg);
|
||||
static telnetshell_cmddef_t rfsimu_cmdarray[] = {
|
||||
{"setmodel","<model name>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||
{"setmodel","<model name> <model type>",(cmdfunc_t)rfsimu_setchanmod_cmd,TELNETSRV_CMDFLAG_PUSHINTPOOLQ},
|
||||
{"","",NULL},
|
||||
};
|
||||
|
||||
@@ -133,6 +135,7 @@ typedef struct {
|
||||
double chan_pathloss;
|
||||
double chan_forgetfact;
|
||||
int chan_offset;
|
||||
float noise_power_dB;
|
||||
void *telnetcmd_qid;
|
||||
poll_telnetcmdq_func_t poll_telnetcmdq;
|
||||
} rfsimulator_state_t;
|
||||
@@ -182,15 +185,9 @@ static void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
|
||||
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,
|
||||
bridge->tx_bw,
|
||||
30e-9, // TDL delay-spread parameter
|
||||
bridge->chan_forgetfact, // forgetting_factor
|
||||
bridge->chan_offset, // maybe used for TA
|
||||
bridge->chan_pathloss); // path_loss in dB
|
||||
char *modelname = (bridge->typeStamp == ENB_MAGICDL) ? "rfsimu_channel_ue0":"rfsimu_channel_enB0";
|
||||
ptr->channel_model=find_channel_desc_fromname(modelname); // path_loss in dB
|
||||
AssertFatal((ptr->channel_model!= NULL),"Channel model %s not found, check config file\n",modelname);
|
||||
set_channeldesc_owner(ptr->channel_model, RFSIMU_MODULEID);
|
||||
random_channel(ptr->channel_model,false);
|
||||
}
|
||||
@@ -299,7 +296,8 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
||||
break;
|
||||
} else if (strcmp(rfsimu_params[p].strlistptr[i],"chanmod") == 0) {
|
||||
init_channelmod();
|
||||
rfsimulator->channelmod=modelid_fromname(modelname);
|
||||
load_channellist(rfsimulator->tx_num_channels, rfsimulator->rx_num_channels, rfsimulator->sample_rate, rfsimulator->tx_bw);
|
||||
rfsimulator->channelmod=true;
|
||||
} else {
|
||||
fprintf(stderr,"Unknown rfsimulator option: %s\n",rfsimu_params[p].strlistptr[i]);
|
||||
exit(-1);
|
||||
@@ -320,20 +318,27 @@ static void rfsimulator_readconfig(rfsimulator_state_t *rfsimulator) {
|
||||
|
||||
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);
|
||||
char *modeltype=NULL;
|
||||
if (debug)
|
||||
prnt("rfsimu_setchanmod_cmd buffer \"%s\"\n",buff);
|
||||
int s = sscanf(buff,"%m[^ ] %ms\n",&modelname, &modeltype);
|
||||
|
||||
if (s == 1) {
|
||||
int channelmod=modelid_fromname(modelname);
|
||||
if (s == 2) {
|
||||
int channelmod=modelid_fromstrtype(modeltype);
|
||||
|
||||
if (channelmod<0)
|
||||
prnt("ERROR: model %s unknown\n",modelname);
|
||||
prnt("ERROR: model type %s unknown\n",modeltype);
|
||||
else {
|
||||
rfsimulator_state_t *t = (rfsimulator_state_t *)arg;
|
||||
|
||||
int found=0;
|
||||
for (int i=0; i<FD_SETSIZE; i++) {
|
||||
buffer_t *b=&t->buf[i];
|
||||
if ( b->channel_model==NULL)
|
||||
continue;
|
||||
if (b->channel_model->model_name==NULL)
|
||||
continue;
|
||||
if (b->conn_sock >= 0 && (strcmp(b->channel_model->model_name,modelname)==0)) {
|
||||
|
||||
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,
|
||||
@@ -341,21 +346,29 @@ static int rfsimu_setchanmod_cmd(char *buff, int debug, telnet_printfunc_t prnt,
|
||||
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
|
||||
t->chan_pathloss,
|
||||
t->noise_power_dB
|
||||
); // path_loss in dB
|
||||
set_channeldesc_owner(newmodel, RFSIMU_MODULEID);
|
||||
set_channeldesc_name(newmodel,modelname);
|
||||
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);
|
||||
prnt("New model type %s applied to channel %s connected to sock %d\n",modeltype,modelname,i);
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* for */
|
||||
if (found==0)
|
||||
prnt("Channel %s not found or not currently used\n",modelname);
|
||||
}
|
||||
} else {
|
||||
prnt("ERROR: no model specified\n");
|
||||
prnt("ERROR: 2 parameters required: model name and model type (%i found)\n",s);
|
||||
}
|
||||
|
||||
free(modelname);
|
||||
free(modeltype);
|
||||
return CMDSTATUS_FOUND;
|
||||
}
|
||||
|
||||
@@ -774,6 +787,11 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
// to change the log level, use this on command line
|
||||
// --log_config.hw_log_level debug
|
||||
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
|
||||
// initialize channel simulation
|
||||
rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
|
||||
rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
|
||||
rfsimulator->sample_rate=openair0_cfg->sample_rate;
|
||||
rfsimulator->tx_bw=openair0_cfg->tx_bw;
|
||||
rfsimulator_readconfig(rfsimulator);
|
||||
pthread_mutex_init(&Sockmutex, NULL);
|
||||
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL ? "server waiting opposite rfsimulators to connect" : "client: will connect to a rfsimulator server side");
|
||||
@@ -798,11 +816,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||
rfsimulator->buf[i].conn_sock=-1;
|
||||
|
||||
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
|
||||
// initialize channel simulation
|
||||
rfsimulator->tx_num_channels=openair0_cfg->tx_num_channels;
|
||||
rfsimulator->rx_num_channels=openair0_cfg->rx_num_channels;
|
||||
rfsimulator->sample_rate=openair0_cfg->sample_rate;
|
||||
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 */
|
||||
|
||||
@@ -201,7 +201,6 @@ int main(int argc, char *argv[]) {
|
||||
void *buff=malloc(bufSize);
|
||||
uint64_t timestamp=0;
|
||||
const int blockSize=1920;
|
||||
|
||||
// If fileSize is not multiple of blockSize*4 then discard remaining samples
|
||||
fileSize = (fileSize/(blockSize<<2))*(blockSize<<2);
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
# include "enb_app.h"
|
||||
# include "openair2/LAYER2/MAC/mac_proto.h"
|
||||
#include <executables/split_headers.h>
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
|
||||
extern RAN_CONTEXT_t RC;
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
# include "mce_app.h"
|
||||
# include "mme_app.h"
|
||||
|
||||
#include <openair3/ocp-gtpu/gtp_itf.h>
|
||||
//extern RAN_CONTEXT_t RC;
|
||||
|
||||
int create_tasks_mbms(uint32_t enb_nb) {
|
||||
|
||||
@@ -869,7 +869,6 @@ static void *ru_thread_asynch_rxtx( void *param ) {
|
||||
LOG_I(PHY, "devices ok (ru_thread_asynch_rxtx)\n");
|
||||
|
||||
while (!oai_exit) {
|
||||
if (oai_exit) break;
|
||||
|
||||
if (ru->state != RU_RUN) {
|
||||
subframe=0;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <sched.h>
|
||||
|
||||
#include "rt_wrapper.h"
|
||||
#include <common/utils/msc/msc.h>
|
||||
|
||||
|
||||
#undef MALLOC //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
@@ -56,6 +57,8 @@
|
||||
|
||||
//#undef FRAME_LENGTH_COMPLEX_SAMPLES //there are two conflicting definitions, so we better make sure we don't use it at all
|
||||
|
||||
#include <openair1/PHY/phy_extern_ue.h>
|
||||
|
||||
#include "PHY/phy_vars.h"
|
||||
#include "SCHED/sched_common_vars.h"
|
||||
#include "LAYER2/MAC/mac_vars.h"
|
||||
@@ -100,6 +103,8 @@ pthread_cond_t nfapi_sync_cond;
|
||||
pthread_mutex_t nfapi_sync_mutex;
|
||||
int nfapi_sync_var=-1; //!< protected by mutex \ref nfapi_sync_mutex
|
||||
|
||||
msc_interface_t msc_interface;
|
||||
|
||||
|
||||
uint16_t sf_ahead=4;
|
||||
|
||||
@@ -170,7 +175,6 @@ extern void init_eNB_afterRU(void);
|
||||
int transmission_mode=1;
|
||||
int emulate_rf = 0;
|
||||
int numerology = 0;
|
||||
int usrp_tx_thread = 0;
|
||||
|
||||
THREAD_STRUCT thread_struct;
|
||||
/* struct for ethernet specific parameters given in eNB conf file */
|
||||
|
||||
@@ -95,6 +95,7 @@ extern int oai_nfapi_rx_ind(nfapi_rx_indication_t *ind);
|
||||
extern int multicast_link_write_sock(int groupP, char *dataP, uint32_t sizeP);
|
||||
|
||||
|
||||
int tx_req_num_elems;
|
||||
extern uint16_t sf_ahead;
|
||||
//extern int tx_req_UE_MAC1();
|
||||
|
||||
@@ -181,9 +182,8 @@ PHY_VARS_UE *init_ue_vars(LTE_DL_FRAME_PARMS *frame_parms,
|
||||
uint8_t abstraction_flag)
|
||||
|
||||
{
|
||||
PHY_VARS_UE *ue = (PHY_VARS_UE *)malloc(sizeof(PHY_VARS_UE));
|
||||
memset(ue,0,sizeof(PHY_VARS_UE));
|
||||
|
||||
PHY_VARS_UE *ue = (PHY_VARS_UE *)calloc(1,sizeof(PHY_VARS_UE));
|
||||
AssertFatal(ue,"");
|
||||
if (frame_parms!=(LTE_DL_FRAME_PARMS *)NULL) { // if we want to give initial frame parms, allocate the PHY_VARS_UE structure and put them in
|
||||
memcpy(&(ue->frame_parms), frame_parms, sizeof(LTE_DL_FRAME_PARMS));
|
||||
}
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
#include "lte-softmodem.h"
|
||||
|
||||
|
||||
msc_interface_t msc_interface;
|
||||
/* temporary compilation wokaround (UE/eNB split */
|
||||
uint16_t sf_ahead;
|
||||
|
||||
@@ -168,7 +169,6 @@ extern void get_uethreads_params(void);
|
||||
|
||||
int transmission_mode=1;
|
||||
|
||||
int usrp_tx_thread = 0;
|
||||
|
||||
|
||||
char *usrp_args=NULL;
|
||||
|
||||
@@ -361,6 +361,7 @@ void init_ocm(void) {
|
||||
DS_TDL,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
random_channel(sim.RU2UE[ru_id][UE_id][CC_id],0);
|
||||
LOG_D(OCM,"[SIM] Initializing channel (%s) from UE %d to ru %d\n", "AWGN", UE_id, ru_id);
|
||||
@@ -374,6 +375,7 @@ void init_ocm(void) {
|
||||
DS_TDL,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
0);
|
||||
random_channel(sim.UE2RU[UE_id][ru_id][CC_id],0);
|
||||
// to make channel reciprocal uncomment following line instead of previous. However this only works for SISO at the moment. For MIMO the channel would need to be transposed.
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <sys/sysinfo.h>
|
||||
#include "rt_wrapper.h"
|
||||
#include <errno.h>
|
||||
#include <common/utils/msc/msc.h>
|
||||
|
||||
#include "openair1/PHY/defs_common.h"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user