mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-12-14 12:10:34 +00:00
Updating RINEX nav file when IONO and UTC data are available (version
3.02)
This commit is contained in:
parent
d3f669cebe
commit
bf85e1fbe1
@ -92,6 +92,7 @@ galileo_e1_pvt_cc::galileo_e1_pvt_cc(unsigned int nchannels, boost::shared_ptr<g
|
|||||||
d_rx_time = 0.0;
|
d_rx_time = 0.0;
|
||||||
|
|
||||||
b_rinex_header_writen = false;
|
b_rinex_header_writen = false;
|
||||||
|
b_rinex_header_updated = false;
|
||||||
rp = std::make_shared<Rinex_Printer>();
|
rp = std::make_shared<Rinex_Printer>();
|
||||||
|
|
||||||
// ############# ENABLE DATA FILE LOG #################
|
// ############# ENABLE DATA FILE LOG #################
|
||||||
@ -211,6 +212,11 @@ int galileo_e1_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_it
|
|||||||
{
|
{
|
||||||
rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
|
rp->log_rinex_obs(rp->obsFile, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
|
||||||
}
|
}
|
||||||
|
if (!b_rinex_header_updated && (d_ls_pvt->galileo_utc_model.A0_6 != 0))
|
||||||
|
{
|
||||||
|
rp->update_nav_header(rp->navGalFile, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac);
|
||||||
|
b_rinex_header_updated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,7 @@ private:
|
|||||||
boost::shared_ptr<gr::msg_queue> d_queue;
|
boost::shared_ptr<gr::msg_queue> d_queue;
|
||||||
bool d_dump;
|
bool d_dump;
|
||||||
bool b_rinex_header_writen;
|
bool b_rinex_header_writen;
|
||||||
|
bool b_rinex_header_updated;
|
||||||
std::shared_ptr<Rinex_Printer> rp;
|
std::shared_ptr<Rinex_Printer> rp;
|
||||||
unsigned int d_nchannels;
|
unsigned int d_nchannels;
|
||||||
std::string d_dump_filename;
|
std::string d_dump_filename;
|
||||||
|
@ -98,6 +98,7 @@ hybrid_pvt_cc::hybrid_pvt_cc(unsigned int nchannels, boost::shared_ptr<gr::msg_q
|
|||||||
d_rx_time = 0.0;
|
d_rx_time = 0.0;
|
||||||
d_TOW_at_curr_symbol_constellation = 0.0;
|
d_TOW_at_curr_symbol_constellation = 0.0;
|
||||||
b_rinex_header_writen = false;
|
b_rinex_header_writen = false;
|
||||||
|
b_rinex_header_updated = false;
|
||||||
rp = std::make_shared<Rinex_Printer>();
|
rp = std::make_shared<Rinex_Printer>();
|
||||||
|
|
||||||
// ############# ENABLE DATA FILE LOG #################
|
// ############# ENABLE DATA FILE LOG #################
|
||||||
@ -250,6 +251,11 @@ int hybrid_pvt_cc::general_work (int noutput_items, gr_vector_int &ninput_items,
|
|||||||
{
|
{
|
||||||
rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
|
rp->log_rinex_obs(rp->obsFile, gps_ephemeris_iter->second, galileo_ephemeris_iter->second, d_rx_time, gnss_pseudoranges_map);
|
||||||
}
|
}
|
||||||
|
if (!b_rinex_header_updated && (d_ls_pvt->gps_utc_model.d_A0 != 0))
|
||||||
|
{
|
||||||
|
rp->update_nav_header(rp->navMixFile, d_ls_pvt->gps_iono, d_ls_pvt->gps_utc_model, d_ls_pvt->galileo_iono, d_ls_pvt->galileo_utc_model, d_ls_pvt->galileo_almanac);
|
||||||
|
b_rinex_header_updated = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,7 @@ private:
|
|||||||
boost::shared_ptr<gr::msg_queue> d_queue;
|
boost::shared_ptr<gr::msg_queue> d_queue;
|
||||||
bool d_dump;
|
bool d_dump;
|
||||||
bool b_rinex_header_writen;
|
bool b_rinex_header_writen;
|
||||||
|
bool b_rinex_header_updated;
|
||||||
std::shared_ptr<Rinex_Printer> rp;
|
std::shared_ptr<Rinex_Printer> rp;
|
||||||
unsigned int d_nchannels;
|
unsigned int d_nchannels;
|
||||||
std::string d_dump_filename;
|
std::string d_dump_filename;
|
||||||
|
@ -503,6 +503,103 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Galileo_Iono& iono
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Rinex_Printer::update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac)
|
||||||
|
{
|
||||||
|
std::vector<std::string> data;
|
||||||
|
std::string line_aux;
|
||||||
|
|
||||||
|
long pos = out.tellp();
|
||||||
|
out.seekp(0);
|
||||||
|
data.clear();
|
||||||
|
|
||||||
|
bool no_more_finds = false;
|
||||||
|
std::string line_str;
|
||||||
|
|
||||||
|
while(!out.eof())
|
||||||
|
{
|
||||||
|
std::getline(out, line_str);
|
||||||
|
|
||||||
|
if(!no_more_finds)
|
||||||
|
{
|
||||||
|
line_aux.clear();
|
||||||
|
|
||||||
|
if ((line_str.find("GAL", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GAL ");
|
||||||
|
line_aux += std::string(1, ' ');
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12);
|
||||||
|
double zero = 0.0;
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12);
|
||||||
|
line_aux += std::string(7, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if ((line_str.find("GAUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GAUT");
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A0_6, 16, 2), 18);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(utc_model.A1_6, 15, 2), 16);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.t0t_6), 7);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.WNot_6), 5);
|
||||||
|
line_aux += std::string(10, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GPGA");
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(galileo_almanac.t_0G_10), 7);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(galileo_almanac.WN_0G_10), 5);
|
||||||
|
line_aux += std::string(10, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if (line_str.find("LEAP SECONDS", 59) != std::string::npos)
|
||||||
|
{
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.Delta_tLS_6), 6);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.Delta_tLSF_6), 6);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.WN_LSF_6), 6);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(utc_model.DN_6), 6);
|
||||||
|
line_aux += std::string(36, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if (line_str.find("END OF HEADER", 59) != std::string::npos)
|
||||||
|
{
|
||||||
|
data.push_back(line_str);
|
||||||
|
no_more_finds = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.push_back(line_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.push_back(line_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.close();
|
||||||
|
out.open(navfilename, std::ios::out | std::ios::trunc);
|
||||||
|
out.seekp(0);
|
||||||
|
for (int i = 0; i < (int) data.size() - 1; i++)
|
||||||
|
{
|
||||||
|
out << data[i] << std::endl;
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
out.open(navfilename, std::ios::out | std::ios::app);
|
||||||
|
out.seekp(pos);
|
||||||
|
std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Utc_Model& utc_model, const Gps_Iono& iono)
|
void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Utc_Model& utc_model, const Gps_Iono& iono)
|
||||||
{
|
{
|
||||||
std::vector<std::string> data;
|
std::vector<std::string> data;
|
||||||
@ -833,6 +930,137 @@ void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& iono, co
|
|||||||
out << line << std::endl;
|
out << line << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Rinex_Printer::update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac)
|
||||||
|
{
|
||||||
|
std::vector<std::string> data;
|
||||||
|
std::string line_aux;
|
||||||
|
|
||||||
|
long pos = out.tellp();
|
||||||
|
out.seekp(0);
|
||||||
|
data.clear();
|
||||||
|
|
||||||
|
bool no_more_finds = false;
|
||||||
|
std::string line_str;
|
||||||
|
|
||||||
|
while(!out.eof())
|
||||||
|
{
|
||||||
|
std::getline(out, line_str);
|
||||||
|
|
||||||
|
if(!no_more_finds)
|
||||||
|
{
|
||||||
|
line_aux.clear();
|
||||||
|
|
||||||
|
if (line_str.find("GPSA", 0) != std::string::npos)
|
||||||
|
{
|
||||||
|
line_aux += std::string("GPSA");
|
||||||
|
line_aux += std::string(1, ' ');
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha0, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha1, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha2, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_alpha3, 10, 2), 12);
|
||||||
|
line_aux += std::string(7, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if ((line_str.find("GAL", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GAL ");
|
||||||
|
line_aux += std::string(1, ' ');
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai0_5, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai1_5, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_iono.ai2_5, 10, 2), 12);
|
||||||
|
double zero = 0.0;
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(zero, 10, 2), 12);
|
||||||
|
line_aux += std::string(7, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if ((line_str.find("GPSB", 0) != std::string::npos) && (line_str.find("IONOSPHERIC CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GPSB");
|
||||||
|
line_aux += std::string(1, ' ');
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta0, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta1, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta2, 10, 2), 12);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_iono.d_beta3, 10, 2), 12);
|
||||||
|
line_aux += std::string(7, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("IONOSPHERIC CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if ((line_str.find("GPUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GPUT");
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A0, 16, 2), 18);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(gps_utc_model.d_A1, 15, 2), 16);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.d_t_OT), 7);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.i_WN_T + 1024), 5); // valid until 2019
|
||||||
|
line_aux += std::string(10, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if ((line_str.find("GAUT", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GAUT");
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A0_6, 16, 2), 18);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_utc_model.A1_6, 15, 2), 16);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(galileo_utc_model.t0t_6), 7);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(galileo_utc_model.WNot_6), 5);
|
||||||
|
line_aux += std::string(10, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if ((line_str.find("GPGA", 0) != std::string::npos) && (line_str.find("TIME SYSTEM CORR", 59) != std::string::npos))
|
||||||
|
{
|
||||||
|
line_aux += std::string("GPGA");
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_0G_10, 16, 2), 18);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(Rinex_Printer::doub2for(galileo_almanac.A_1G_10, 15, 2), 16);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(galileo_almanac.t_0G_10), 7);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(galileo_almanac.WN_0G_10), 5);
|
||||||
|
line_aux += std::string(10, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("TIME SYSTEM CORR", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if (line_str.find("LEAP SECONDS", 59) != std::string::npos)
|
||||||
|
{
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.d_DeltaT_LS), 6);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.d_DeltaT_LSF), 6);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.i_WN_LSF), 6);
|
||||||
|
line_aux += Rinex_Printer::rightJustify(boost::lexical_cast<std::string>(gps_utc_model.i_DN), 6);
|
||||||
|
line_aux += std::string(36, ' ');
|
||||||
|
line_aux += Rinex_Printer::leftJustify("LEAP SECONDS", 20);
|
||||||
|
data.push_back(line_aux);
|
||||||
|
}
|
||||||
|
else if (line_str.find("END OF HEADER", 59) != std::string::npos)
|
||||||
|
{
|
||||||
|
data.push_back(line_str);
|
||||||
|
no_more_finds = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.push_back(line_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data.push_back(line_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.close();
|
||||||
|
out.open(navfilename, std::ios::out | std::ios::trunc);
|
||||||
|
out.seekp(0);
|
||||||
|
for (int i = 0; i < (int) data.size() - 1; i++)
|
||||||
|
{
|
||||||
|
out << data[i] << std::endl;
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
out.open(navfilename, std::ios::out | std::ios::app);
|
||||||
|
out.seekp(pos);
|
||||||
|
std::cout << "The RINEX Navigation file header has been updated with UTC and IONO info." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac)
|
void Rinex_Printer::rinex_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac)
|
||||||
{
|
{
|
||||||
std::string line;
|
std::string line;
|
||||||
|
@ -184,6 +184,10 @@ public:
|
|||||||
|
|
||||||
void update_nav_header(std::fstream& out, const Gps_Utc_Model& gps_utc, const Gps_Iono& gps_iono);
|
void update_nav_header(std::fstream& out, const Gps_Utc_Model& gps_utc, const Gps_Iono& gps_iono);
|
||||||
|
|
||||||
|
void update_nav_header(std::fstream& out, const Gps_Iono& gps_iono, const Gps_Utc_Model& gps_utc_model, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& galileo_utc_model, const Galileo_Almanac& galileo_almanac);
|
||||||
|
|
||||||
|
void update_nav_header(std::fstream& out, const Galileo_Iono& galileo_iono, const Galileo_Utc_Model& utc_model, const Galileo_Almanac& galileo_almanac);
|
||||||
|
|
||||||
std::map<std::string,std::string> satelliteSystem; //<! GPS, GLONASS, SBAS payload, Galileo or Compass
|
std::map<std::string,std::string> satelliteSystem; //<! GPS, GLONASS, SBAS payload, Galileo or Compass
|
||||||
std::map<std::string,std::string> observationType; //<! PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH
|
std::map<std::string,std::string> observationType; //<! PSEUDORANGE, CARRIER_PHASE, DOPPLER, SIGNAL_STRENGTH
|
||||||
std::map<std::string,std::string> observationCode; //<! GNSS observation descriptors
|
std::map<std::string,std::string> observationCode; //<! GNSS observation descriptors
|
||||||
|
Loading…
Reference in New Issue
Block a user