Added options for bladeRF and HackRF
This commit is contained in:
parent
d1e8f91569
commit
f8f1270d04
275
gpssim.c
275
gpssim.c
@ -6,12 +6,19 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <omp.h>
|
#include <omp.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "getopt.h"
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MAX_CHAR (100)
|
#define MAX_CHAR (100)
|
||||||
|
|
||||||
#define MAX_SAT (32)
|
#define MAX_SAT (32)
|
||||||
#define MAX_CHAN (16)
|
#define MAX_CHAN (16)
|
||||||
|
|
||||||
|
#define USER_MOTION_SIZE (1000) // max 300 sec at 10Hz
|
||||||
|
|
||||||
#define N_SBF (51) // 6 seconds per subframe, 6 sec * 51 = 306 sec (max)
|
#define N_SBF (51) // 6 seconds per subframe, 6 sec * 51 = 306 sec (max)
|
||||||
#define N_DWRD (N_SBF*10) // 10 word per subframe
|
#define N_DWRD (N_SBF*10) // 10 word per subframe
|
||||||
|
|
||||||
@ -42,12 +49,119 @@
|
|||||||
#define CARR_FREQ (1575.42e6)
|
#define CARR_FREQ (1575.42e6)
|
||||||
#define CODE_FREQ (1.023e6)
|
#define CODE_FREQ (1.023e6)
|
||||||
#define CARR_TO_CODE (1.0/1540.0)
|
#define CARR_TO_CODE (1.0/1540.0)
|
||||||
#define SAMP_FREQ (4.0e6)
|
|
||||||
#define ADC_GAIN (250.0) // for bladeRF txvga1 = -25dB with 50dB external attenuation
|
|
||||||
|
|
||||||
#define USER_MOTION_SIZE (3000) // max 300 sec at 10Hz
|
// Sampling data format
|
||||||
#define IQ_BUFF_SIZE (400000) // 0.4Msps per 0.1sec
|
#define SC08 (8)
|
||||||
|
#define SC16 (16)
|
||||||
|
|
||||||
|
int sinTable512[] = {
|
||||||
|
0,6,12,18,25,31,37,43,50,56,62,
|
||||||
|
68,75,81,87,93,99,106,112,118,124,
|
||||||
|
130,136,142,148,154,160,166,172,178,184,
|
||||||
|
190,195,201,207,213,218,224,230,235,241,
|
||||||
|
246,252,257,263,268,273,279,284,289,294,
|
||||||
|
299,304,310,314,319,324,329,334,339,343,
|
||||||
|
348,353,357,362,366,370,375,379,383,387,
|
||||||
|
391,395,399,403,407,411,414,418,422,425,
|
||||||
|
429,432,435,439,442,445,448,451,454,457,
|
||||||
|
460,462,465,468,470,473,475,477,479,482,
|
||||||
|
484,486,488,489,491,493,495,496,498,499,
|
||||||
|
500,502,503,504,505,506,507,508,508,509,
|
||||||
|
510,510,511,511,511,511,511,512,511,511,
|
||||||
|
511,511,511,510,510,509,508,508,507,506,
|
||||||
|
505,504,503,502,500,499,498,496,495,493,
|
||||||
|
491,489,488,486,484,482,479,477,475,473,
|
||||||
|
470,468,465,462,460,457,454,451,448,445,
|
||||||
|
442,439,435,432,429,425,422,418,414,411,
|
||||||
|
407,403,399,395,391,387,383,379,375,370,
|
||||||
|
366,362,357,353,348,343,339,334,329,324,
|
||||||
|
319,314,310,304,299,294,289,284,279,273,
|
||||||
|
268,263,257,252,246,241,235,230,224,218,
|
||||||
|
213,207,201,195,190,184,178,172,166,160,
|
||||||
|
154,148,142,136,130,124,118,112,106,99,
|
||||||
|
93,87,81,75,68,62,56,50,43,37,
|
||||||
|
31,25,18,12,6,0,-7,-13,-19,-26,
|
||||||
|
-32,-38,-44,-51,-57,-63,-69,-76,-82,-88,
|
||||||
|
-94,-100,-107,-113,-119,-125,-131,-137,-143,-149,
|
||||||
|
-155,-161,-167,-173,-179,-185,-191,-196,-202,-208,
|
||||||
|
-214,-219,-225,-231,-236,-242,-247,-253,-258,-264,
|
||||||
|
-269,-274,-280,-285,-290,-295,-300,-305,-311,-315,
|
||||||
|
-320,-325,-330,-335,-340,-344,-349,-354,-358,-363,
|
||||||
|
-367,-371,-376,-380,-384,-388,-392,-396,-400,-404,
|
||||||
|
-408,-412,-415,-419,-423,-426,-430,-433,-436,-440,
|
||||||
|
-443,-446,-449,-452,-455,-458,-461,-463,-466,-469,
|
||||||
|
-471,-474,-476,-478,-480,-483,-485,-487,-489,-490,
|
||||||
|
-492,-494,-496,-497,-499,-500,-501,-503,-504,-505,
|
||||||
|
-506,-507,-508,-509,-509,-510,-511,-511,-512,-512,
|
||||||
|
-512,-512,-512,-512,-512,-512,-512,-512,-512,-511,
|
||||||
|
-511,-510,-509,-509,-508,-507,-506,-505,-504,-503,
|
||||||
|
-501,-500,-499,-497,-496,-494,-492,-490,-489,-487,
|
||||||
|
-485,-483,-480,-478,-476,-474,-471,-469,-466,-463,
|
||||||
|
-461,-458,-455,-452,-449,-446,-443,-440,-436,-433,
|
||||||
|
-430,-426,-423,-419,-415,-412,-408,-404,-400,-396,
|
||||||
|
-392,-388,-384,-380,-376,-371,-367,-363,-358,-354,
|
||||||
|
-349,-344,-340,-335,-330,-325,-320,-315,-311,-305,
|
||||||
|
-300,-295,-290,-285,-280,-274,-269,-264,-258,-253,
|
||||||
|
-247,-242,-236,-231,-225,-219,-214,-208,-202,-196,
|
||||||
|
-191,-185,-179,-173,-167,-161,-155,-149,-143,-137,
|
||||||
|
-131,-125,-119,-113,-107,-100,-94,-88,-82,-76,
|
||||||
|
-69,-63,-57,-51,-44,-38,-32,-26,-19,-13,-7
|
||||||
|
};
|
||||||
|
|
||||||
|
int cosTable512[] = {
|
||||||
|
512,511,511,511,511,511,510,510,509,508,508,
|
||||||
|
507,506,505,504,503,502,500,499,498,496,
|
||||||
|
495,493,491,489,488,486,484,482,479,477,
|
||||||
|
475,473,470,468,465,462,460,457,454,451,
|
||||||
|
448,445,442,439,435,432,429,425,422,418,
|
||||||
|
414,411,407,403,399,395,391,387,383,379,
|
||||||
|
375,370,366,362,357,353,348,343,339,334,
|
||||||
|
329,324,319,314,310,304,299,294,289,284,
|
||||||
|
279,273,268,263,257,252,246,241,235,230,
|
||||||
|
224,218,213,207,201,195,190,184,178,172,
|
||||||
|
166,160,154,148,142,136,130,124,118,112,
|
||||||
|
106,99,93,87,81,75,68,62,56,50,
|
||||||
|
43,37,31,25,18,12,6,0,-7,-13,
|
||||||
|
-19,-26,-32,-38,-44,-51,-57,-63,-69,-76,
|
||||||
|
-82,-88,-94,-100,-107,-113,-119,-125,-131,-137,
|
||||||
|
-143,-149,-155,-161,-167,-173,-179,-185,-191,-196,
|
||||||
|
-202,-208,-214,-219,-225,-231,-236,-242,-247,-253,
|
||||||
|
-258,-264,-269,-274,-280,-285,-290,-295,-300,-305,
|
||||||
|
-311,-315,-320,-325,-330,-335,-340,-344,-349,-354,
|
||||||
|
-358,-363,-367,-371,-376,-380,-384,-388,-392,-396,
|
||||||
|
-400,-404,-408,-412,-415,-419,-423,-426,-430,-433,
|
||||||
|
-436,-440,-443,-446,-449,-452,-455,-458,-461,-463,
|
||||||
|
-466,-469,-471,-474,-476,-478,-480,-483,-485,-487,
|
||||||
|
-489,-490,-492,-494,-496,-497,-499,-500,-501,-503,
|
||||||
|
-504,-505,-506,-507,-508,-509,-509,-510,-511,-511,
|
||||||
|
-512,-512,-512,-512,-512,-512,-512,-512,-512,-512,
|
||||||
|
-512,-511,-511,-510,-509,-509,-508,-507,-506,-505,
|
||||||
|
-504,-503,-501,-500,-499,-497,-496,-494,-492,-490,
|
||||||
|
-489,-487,-485,-483,-480,-478,-476,-474,-471,-469,
|
||||||
|
-466,-463,-461,-458,-455,-452,-449,-446,-443,-440,
|
||||||
|
-436,-433,-430,-426,-423,-419,-415,-412,-408,-404,
|
||||||
|
-400,-396,-392,-388,-384,-380,-376,-371,-367,-363,
|
||||||
|
-358,-354,-349,-344,-340,-335,-330,-325,-320,-315,
|
||||||
|
-311,-305,-300,-295,-290,-285,-280,-274,-269,-264,
|
||||||
|
-258,-253,-247,-242,-236,-231,-225,-219,-214,-208,
|
||||||
|
-202,-196,-191,-185,-179,-173,-167,-161,-155,-149,
|
||||||
|
-143,-137,-131,-125,-119,-113,-107,-100,-94,-88,
|
||||||
|
-82,-76,-69,-63,-57,-51,-44,-38,-32,-26,
|
||||||
|
-19,-13,-7,-1,6,12,18,25,31,37,
|
||||||
|
43,50,56,62,68,75,81,87,93,99,
|
||||||
|
106,112,118,124,130,136,142,148,154,160,
|
||||||
|
166,172,178,184,190,195,201,207,213,218,
|
||||||
|
224,230,235,241,246,252,257,263,268,273,
|
||||||
|
279,284,289,294,299,304,310,314,319,324,
|
||||||
|
329,334,339,343,348,353,357,362,366,370,
|
||||||
|
375,379,383,387,391,395,399,403,407,411,
|
||||||
|
414,418,422,425,429,432,435,439,442,445,
|
||||||
|
448,451,454,457,460,462,465,468,470,473,
|
||||||
|
475,477,479,482,484,486,488,489,491,493,
|
||||||
|
495,496,498,499,500,502,503,504,505,506,
|
||||||
|
507,508,508,509,510,510,511,511,511,511,511
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int week;
|
int week;
|
||||||
@ -330,7 +444,7 @@ void satpos(ephem_t eph, gpstime_t g, double *pos, double *vel, double *clk)
|
|||||||
double xpk,ypk;
|
double xpk,ypk;
|
||||||
double xpkdot,ypkdot;
|
double xpkdot,ypkdot;
|
||||||
|
|
||||||
double relativistic, OneMinusecosE, sqrtOneMinuse2, tmp;
|
double relativistic, OneMinusecosE, sqrtOneMinuse2, tmp;
|
||||||
|
|
||||||
tk = g.sec - eph.toe.sec;
|
tk = g.sec - eph.toe.sec;
|
||||||
|
|
||||||
@ -342,10 +456,10 @@ void satpos(ephem_t eph, gpstime_t g, double *pos, double *vel, double *clk)
|
|||||||
a = eph.sqrta*eph.sqrta;
|
a = eph.sqrta*eph.sqrta;
|
||||||
|
|
||||||
mkdot = sqrt(GM_EARTH/(a*a*a)) + eph.deltan;
|
mkdot = sqrt(GM_EARTH/(a*a*a)) + eph.deltan;
|
||||||
mk = eph.m0 + mkdot*tk;
|
mk = eph.m0 + mkdot*tk;
|
||||||
|
|
||||||
ek = mk;
|
ek = mk;
|
||||||
ekold = ek + 1.0;
|
ekold = ek + 1.0;
|
||||||
|
|
||||||
while(fabs(ek-ekold)>1.0E-14)
|
while(fabs(ek-ekold)>1.0E-14)
|
||||||
{
|
{
|
||||||
@ -985,6 +1099,19 @@ int readUserMotion(double xyz[USER_MOTION_SIZE][3], char *filename)
|
|||||||
return (numd);
|
return (numd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
printf("Usage: gps-sdr-sim [options]\n"
|
||||||
|
"Options:\n"
|
||||||
|
" -e <gps_nav> RINEX navigation file for GPS ephemerides (required)\n"
|
||||||
|
" -u <user_motion> User motion file (required)\n"
|
||||||
|
" -o <output> I/Q sampling data file (default: gpssim.bin)\n"
|
||||||
|
" -f <furequency> Sampling frequency [Hz] (default: 2.6MHz)\n"
|
||||||
|
" -b <iq_bits> I/Q data format [8/16] (default: 8)\n");
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
clock_t tstart,tend;
|
clock_t tstart,tend;
|
||||||
@ -1015,13 +1142,13 @@ int main(int argc, char *argv[])
|
|||||||
unsigned long prevwrd;
|
unsigned long prevwrd;
|
||||||
int nib;
|
int nib;
|
||||||
|
|
||||||
double ip,qp;
|
int ip,qp;
|
||||||
short *iq_buff = NULL;
|
void *iq_buff = NULL;
|
||||||
|
|
||||||
gpstime_t grx0,grx1;
|
gpstime_t grx0,grx1;
|
||||||
range_t rho0,rho1;
|
range_t rho0,rho1;
|
||||||
|
|
||||||
double delt = 1.0/SAMP_FREQ;
|
double delt; // = 1.0/SAMP_FREQ;
|
||||||
int isamp;
|
int isamp;
|
||||||
|
|
||||||
int iumd;
|
int iumd;
|
||||||
@ -1032,23 +1159,87 @@ int main(int argc, char *argv[])
|
|||||||
char navfile[MAX_CHAR];
|
char navfile[MAX_CHAR];
|
||||||
char outfile[MAX_CHAR];
|
char outfile[MAX_CHAR];
|
||||||
|
|
||||||
|
double samp_freq;
|
||||||
|
int iq_buff_size;
|
||||||
|
int data_format;
|
||||||
|
|
||||||
|
int result;
|
||||||
|
|
||||||
|
int iTable;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Read arguments
|
// Read options
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
if (argc!=3 && argc!=4)
|
// Default options
|
||||||
|
navfile[0] = 0;
|
||||||
|
umfile[0] = 0;
|
||||||
|
strcpy(outfile, "gpssim.bin");
|
||||||
|
samp_freq = 2.6e6;
|
||||||
|
data_format = SC08;
|
||||||
|
|
||||||
|
if (argc<3)
|
||||||
{
|
{
|
||||||
printf("Usage: gps-sdr-sim <gps_nav> <user_motion> [output (default: gpssim.bin)]\n");
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(navfile, argv[1]);
|
while ((result=getopt(argc,argv,"e:u:o:f:b:"))!=-1)
|
||||||
strcpy(umfile, argv[2]);
|
{
|
||||||
|
switch (result)
|
||||||
|
{
|
||||||
|
case 'e':
|
||||||
|
strcpy(navfile, optarg);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
strcpy(umfile, optarg);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
strcpy(outfile, optarg);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
samp_freq = atof(optarg);
|
||||||
|
if (samp_freq<1.0e6)
|
||||||
|
{
|
||||||
|
printf("Invalid sampling frequency.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
data_format = atoi(optarg);
|
||||||
|
if (data_format!=SC08 && data_format!=SC16)
|
||||||
|
{
|
||||||
|
printf("Invalid data format.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
case '?':
|
||||||
|
usage();
|
||||||
|
exit(1);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (argc==3)
|
if (navfile[0]==0)
|
||||||
strcpy(outfile, "gpssim.bin");
|
{
|
||||||
else
|
printf("GPS ephemeris file is not specified.\n");
|
||||||
strcpy(outfile, argv[3]);
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (umfile[0]==0)
|
||||||
|
{
|
||||||
|
printf("User motion file is not specified.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer size
|
||||||
|
samp_freq = floor(samp_freq/10.0);
|
||||||
|
iq_buff_size = (int)samp_freq; // samples per 0.1sec
|
||||||
|
samp_freq *= 10.0;
|
||||||
|
|
||||||
|
delt = 1.0/samp_freq;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Receiver position
|
// Receiver position
|
||||||
@ -1142,21 +1333,20 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
printf("%02d %6.1f %5.1f\n", sv+1, azel[0]*R2D, azel[1]*R2D);
|
printf("%02d %6.1f %5.1f\n", sv+1, azel[0]*R2D, azel[1]*R2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
//printf("%1c%02d %6.1f %5.1f\n", (azel[1]>elvmask)?'*':' ', sv+1, azel[0]*R2D, azel[1]*R2D);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Number of channels = %d\n", nsat);
|
printf("Number of channels = %d\n", nsat);
|
||||||
|
|
||||||
//return(0);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Baseband signal buffer and output file
|
// Baseband signal buffer and output file
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Allocate I/Q buffer
|
// Allocate I/Q buffer
|
||||||
iq_buff = (short *)calloc(2*IQ_BUFF_SIZE, 2);
|
if (data_format==SC08)
|
||||||
|
iq_buff = (signed char *)calloc(2*iq_buff_size, 1);
|
||||||
|
else
|
||||||
|
iq_buff = (short *)calloc(2*iq_buff_size, 2);
|
||||||
|
|
||||||
if (iq_buff==NULL)
|
if (iq_buff==NULL)
|
||||||
{
|
{
|
||||||
@ -1184,10 +1374,10 @@ int main(int argc, char *argv[])
|
|||||||
codegen(chan[i].ca, chan[i].prn);
|
codegen(chan[i].ca, chan[i].prn);
|
||||||
|
|
||||||
// Initialize carrier phase
|
// Initialize carrier phase
|
||||||
chan[i].carr_phase = 0.0;
|
chan[i].carr_phase = 0.0; // !!FIXME!! Need proper initialization for RTK
|
||||||
|
|
||||||
// Allocate I/Q buffer
|
// Allocate I/Q buffer
|
||||||
chan[i].iq_buff = (short *)calloc(2*IQ_BUFF_SIZE, 2);
|
chan[i].iq_buff = (short *)calloc(2*iq_buff_size, 2);
|
||||||
|
|
||||||
if (chan[i].iq_buff==NULL)
|
if (chan[i].iq_buff==NULL)
|
||||||
{
|
{
|
||||||
@ -1280,14 +1470,16 @@ int main(int argc, char *argv[])
|
|||||||
// Properties -> Configuration Properties -> C/C++ -> Language -> Open MP Support -> Yes (/openmp)
|
// Properties -> Configuration Properties -> C/C++ -> Language -> Open MP Support -> Yes (/openmp)
|
||||||
for (i=0; i<nsat; i++)
|
for (i=0; i<nsat; i++)
|
||||||
{
|
{
|
||||||
for (isamp=0; isamp<IQ_BUFF_SIZE; isamp++)
|
for (isamp=0; isamp<iq_buff_size; isamp++)
|
||||||
{
|
{
|
||||||
ip = chan[i].dataBit * chan[i].codeCA * cos(2.0*PI*chan[i].carr_phase);
|
iTable = (int)floor(chan[i].carr_phase*512.0);
|
||||||
qp = chan[i].dataBit * chan[i].codeCA * sin(2.0*PI*chan[i].carr_phase);
|
|
||||||
|
ip = chan[i].dataBit * chan[i].codeCA * cosTable512[iTable];
|
||||||
|
qp = chan[i].dataBit * chan[i].codeCA * sinTable512[iTable];
|
||||||
|
|
||||||
// Sotre I/Q samples into buffer
|
// Sotre I/Q samples into buffer
|
||||||
chan[i].iq_buff[isamp*2] = (short)(ADC_GAIN*ip);
|
chan[i].iq_buff[isamp*2] = (short)(ip>>2);
|
||||||
chan[i].iq_buff[isamp*2+1] = (short)(ADC_GAIN*qp);
|
chan[i].iq_buff[isamp*2+1] = (short)(qp>>2);
|
||||||
|
|
||||||
// Update code phase
|
// Update code phase
|
||||||
chan[i].code_phase += chan[i].f_code * delt;
|
chan[i].code_phase += chan[i].f_code * delt;
|
||||||
@ -1327,15 +1519,26 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
} // End of omp parallel for
|
} // End of omp parallel for
|
||||||
|
|
||||||
for (isamp=0; isamp<2*IQ_BUFF_SIZE; isamp++)
|
for (isamp=0; isamp<2*iq_buff_size; isamp++)
|
||||||
{
|
{
|
||||||
iq_buff[isamp] = 0;
|
if (data_format==SC08)
|
||||||
|
((signed char*)iq_buff)[isamp] = 0;
|
||||||
|
else
|
||||||
|
((short*)iq_buff)[isamp] = 0;
|
||||||
|
|
||||||
for (i=0; i<nsat; i++)
|
for (i=0; i<nsat; i++)
|
||||||
iq_buff[isamp] += chan[i].iq_buff[isamp];
|
{
|
||||||
|
if (data_format==SC08)
|
||||||
|
((signed char*)iq_buff)[isamp] += (signed char)(chan[i].iq_buff[isamp]>>4); // 12-bit bladeRF -> 8-bit HackRF
|
||||||
|
else
|
||||||
|
((short*)iq_buff)[isamp] += chan[i].iq_buff[isamp];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(iq_buff, 2, 2*IQ_BUFF_SIZE, fp); // 2 (I/Q) * 2 (short) * 4 Msps = 16,000,000 byte/s
|
if (data_format==SC08)
|
||||||
|
fwrite(iq_buff, 1, 2*iq_buff_size, fp);
|
||||||
|
else
|
||||||
|
fwrite(iq_buff, 2, 2*iq_buff_size, fp);
|
||||||
|
|
||||||
// Next second
|
// Next second
|
||||||
grx0.sec += 0.1;
|
grx0.sec += 0.1;
|
||||||
|
Loading…
Reference in New Issue
Block a user