Import: Clean up gasmix / tank usage.
Separate the usage enums and remove the unneeded values from each. Signed-off-by: Michael Keller <github@ike.ch>
This commit is contained in:
parent
edfb1a9c67
commit
39bc2fe05c
@ -207,6 +207,8 @@ AX_APPEND_COMPILE_FLAGS([ \
|
||||
-Wno-unused-but-set-variable \
|
||||
-Wno-pointer-sign \
|
||||
-Wno-shadow \
|
||||
-Wenum-conversion \
|
||||
-Werror=enum-conversion \
|
||||
-fmacro-prefix-map='$(top_srcdir)/'= \
|
||||
],,[$ERROR_CFLAGS])
|
||||
|
||||
|
||||
@ -174,10 +174,10 @@ typedef struct dc_salinity_t {
|
||||
} dc_salinity_t;
|
||||
|
||||
typedef enum dc_usage_t {
|
||||
DC_USAGE_NONE,
|
||||
DC_USAGE_NONE, // Usage not specified
|
||||
DC_USAGE_OXYGEN,
|
||||
DC_USAGE_DILUENT,
|
||||
DC_USAGE_SIDEMOUNT,
|
||||
DC_USAGE_OPEN_CIRCUIT,
|
||||
} dc_usage_t;
|
||||
|
||||
typedef struct dc_gasmix_t {
|
||||
@ -193,8 +193,6 @@ typedef struct dc_gasmix_t {
|
||||
typedef unsigned int dc_tankinfo_t;
|
||||
#define DC_TANKINFO_METRIC 1
|
||||
#define DC_TANKINFO_IMPERIAL 2
|
||||
#define DC_TANKINFO_CC_DILUENT 4
|
||||
#define DC_TANKINFO_CC_O2 8
|
||||
|
||||
// For backwards compatibility
|
||||
#define DC_TANKVOLUME_NONE 0
|
||||
@ -224,6 +222,11 @@ typedef unsigned int dc_tankinfo_t;
|
||||
* divide by 1 ATM (Vair = Vwater * Pwork / Patm).
|
||||
*/
|
||||
|
||||
typedef enum dc_tank_usage_t {
|
||||
DC_TANK_USAGE_NONE,
|
||||
DC_TANK_USAGE_SIDEMOUNT,
|
||||
} dc_tank_usage_t;
|
||||
|
||||
typedef struct dc_tank_t {
|
||||
unsigned int gasmix; /* Gas mix index, or DC_GASMIX_UNKNOWN */
|
||||
dc_tankinfo_t type; /* Tank type - metric/imperial and oc/cc */
|
||||
@ -231,7 +234,7 @@ typedef struct dc_tank_t {
|
||||
double workpressure; /* Work pressure (bar) */
|
||||
double beginpressure; /* Begin pressure (bar) */
|
||||
double endpressure; /* End pressure (bar) */
|
||||
dc_usage_t usage;
|
||||
dc_tank_usage_t usage;
|
||||
} dc_tank_t;
|
||||
|
||||
typedef enum dc_decomodel_type_t {
|
||||
|
||||
@ -191,7 +191,7 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un
|
||||
tank->gasmix = flags;
|
||||
tank->beginpressure = array_uint16_le(p + 6) * PSI / BAR;
|
||||
tank->endpressure = array_uint16_le(p + 14) * PSI / BAR;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_DIVEMODE:
|
||||
switch(p[0x24]) {
|
||||
|
||||
@ -797,7 +797,7 @@ divesoft_freedom_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
|
||||
} else if (parser->gasmix[flags].type == DILUENT) {
|
||||
gasmix->usage = DC_USAGE_DILUENT;
|
||||
} else {
|
||||
gasmix->usage = DC_USAGE_NONE;
|
||||
gasmix->usage = DC_USAGE_OPEN_CIRCUIT;
|
||||
}
|
||||
gasmix->helium = parser->gasmix[flags].helium / 100.0;
|
||||
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
|
||||
@ -820,7 +820,7 @@ divesoft_freedom_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
|
||||
tank->beginpressure = parser->tank[flags].beginpressure * 2.0;
|
||||
tank->endpressure = parser->tank[flags].endpressure * 2.0;
|
||||
tank->gasmix = flags;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_DECOMODEL:
|
||||
if (parser->vpm) {
|
||||
|
||||
@ -304,7 +304,7 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
|
||||
tank->beginpressure = parser->tank[flags].beginpressure;
|
||||
tank->endpressure = parser->tank[flags].endpressure;
|
||||
tank->gasmix = DC_GASMIX_UNKNOWN;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_ATMOSPHERIC:
|
||||
if (ISIX3M(parser->model)) {
|
||||
|
||||
@ -26,7 +26,7 @@ typedef struct dc_field_cache {
|
||||
// dc_tank_t TANK[MAXGASES]
|
||||
// but that's for later
|
||||
dc_tankinfo_t tankinfo[MAXGASES];
|
||||
dc_usage_t tankusage[MAXGASES];
|
||||
dc_tank_usage_t tankusage[MAXGASES];
|
||||
double tanksize[MAXGASES];
|
||||
double tankworkingpressure[MAXGASES];
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ struct record_data {
|
||||
double ceiling;
|
||||
|
||||
// RECORD_GASMIX
|
||||
int index, gas_status, gas_type;
|
||||
int index, gas_status;
|
||||
dc_gasmix_t gasmix;
|
||||
|
||||
// RECORD_EVENT
|
||||
@ -129,7 +129,7 @@ typedef struct garmin_parser_t {
|
||||
unsigned int setpoint_low_cbar, setpoint_high_cbar;
|
||||
unsigned int setpoint_low_switch_depth_mm, setpoint_high_switch_depth_mm;
|
||||
unsigned int setpoint_low_switch_mode, setpoint_high_switch_mode;
|
||||
dc_tankinfo_t *current_tankinfo;
|
||||
dc_gasmix_t *current_gasmix;
|
||||
} dive;
|
||||
|
||||
// I count nine (!) different GPS fields Hmm.
|
||||
@ -239,11 +239,11 @@ static void garmin_event(struct garmin_parser_t *garmin,
|
||||
sample.gasmix = data;
|
||||
garmin->callback(DC_SAMPLE_GASMIX, &sample, garmin->userdata);
|
||||
|
||||
dc_tankinfo_t *tankinfo = &garmin->cache.tankinfo[data];
|
||||
if (!garmin->dive.current_tankinfo || (*tankinfo & DC_TANKINFO_CC_DILUENT) != (*garmin->dive.current_tankinfo & DC_TANKINFO_CC_DILUENT)) {
|
||||
dc_gasmix_t *gasmix = &garmin->cache.GASMIX[data];
|
||||
if (!garmin->dive.current_gasmix || gasmix->usage != garmin->dive.current_gasmix->usage) {
|
||||
dc_sample_value_t sample2 = {0};
|
||||
sample2.event.type = SAMPLE_EVENT_STRING;
|
||||
if (*tankinfo & DC_TANKINFO_CC_DILUENT) {
|
||||
if (gasmix->usage == DC_USAGE_DILUENT) {
|
||||
sample2.event.name = "Switched to closed circuit";
|
||||
} else {
|
||||
sample2.event.name = "Switched to open circuit bailout";
|
||||
@ -252,7 +252,7 @@ static void garmin_event(struct garmin_parser_t *garmin,
|
||||
|
||||
garmin->callback(DC_SAMPLE_EVENT, &sample2, garmin->userdata);
|
||||
|
||||
garmin->dive.current_tankinfo = tankinfo;
|
||||
garmin->dive.current_gasmix = gasmix;
|
||||
}
|
||||
|
||||
return;
|
||||
@ -279,17 +279,7 @@ static void flush_pending_record(struct garmin_parser_t *garmin)
|
||||
int index = record->index;
|
||||
if (enabled && index < MAXGASES) {
|
||||
DC_ASSIGN_IDX(garmin->cache, GASMIX, index, record->gasmix);
|
||||
if (index + 1 > garmin->cache.GASMIX_COUNT) {
|
||||
DC_ASSIGN_FIELD(garmin->cache, GASMIX_COUNT, index + 1);
|
||||
garmin->cache.initialized |= 1 << DC_FIELD_TANK_COUNT;
|
||||
}
|
||||
|
||||
dc_tankinfo_t tankinfo = DC_TANKINFO_METRIC;
|
||||
if (record->gas_type == 1) {
|
||||
tankinfo |= DC_TANKINFO_CC_DILUENT;
|
||||
}
|
||||
garmin->cache.tankinfo[index] = tankinfo;
|
||||
garmin->cache.initialized |= 1 << DC_FIELD_TANK;
|
||||
DC_ASSIGN_FIELD(garmin->cache, GASMIX_COUNT, index + 1);
|
||||
}
|
||||
}
|
||||
if (pending & RECORD_DEVICE_INFO && record->device_index == 0) {
|
||||
@ -699,7 +689,10 @@ DECLARE_FIELD(DIVE_GAS, status, ENUM)
|
||||
DECLARE_FIELD(DIVE_GAS, type, ENUM)
|
||||
{
|
||||
// 0 - open circuit, 1 - CCR diluent
|
||||
garmin->record_data.gas_type = data;
|
||||
if (data == 1)
|
||||
garmin->record_data.gasmix.usage = DC_USAGE_DILUENT;
|
||||
else
|
||||
garmin->record_data.gasmix.usage = DC_USAGE_OPEN_CIRCUIT;
|
||||
garmin->record_data.pending |= RECORD_GASMIX;
|
||||
}
|
||||
|
||||
@ -1663,10 +1656,8 @@ garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsi
|
||||
//
|
||||
// There's no way to match them up unless they are an identity
|
||||
// mapping, so having two different ones doesn't actually work.
|
||||
if (garmin->dive.nr_sensor > garmin->cache.GASMIX_COUNT) {
|
||||
if (garmin->dive.nr_sensor > garmin->cache.GASMIX_COUNT)
|
||||
DC_ASSIGN_FIELD(garmin->cache, GASMIX_COUNT, garmin->dive.nr_sensor);
|
||||
garmin->cache.initialized |= 1 << DC_FIELD_TANK_COUNT;
|
||||
}
|
||||
|
||||
for (int i = 0; i < garmin->dive.nr_sensor; i++) {
|
||||
static const char *name[] = { "Sensor 1", "Sensor 2", "Sensor 3", "Sensor 4", "Sensor 5" };
|
||||
|
||||
@ -575,14 +575,10 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
|
||||
}
|
||||
|
||||
gasmix->usage = parser->gasmix[flags].diluent ?
|
||||
DC_USAGE_DILUENT : DC_USAGE_NONE;
|
||||
DC_USAGE_DILUENT : DC_USAGE_OPEN_CIRCUIT;
|
||||
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
|
||||
gasmix->helium = parser->gasmix[flags].helium / 100.0;
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
if (!parser->gasmix[flags].enabled) {
|
||||
// Indicate that this gasmix is not active
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
break;
|
||||
case DC_FIELD_TANK:
|
||||
@ -595,7 +591,7 @@ hw_ostc_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned
|
||||
tank->volume = 0.0;
|
||||
tank->gasmix = flags;
|
||||
tank->workpressure = 0.0;
|
||||
tank->type = DC_TANKINFO_METRIC | (parser->gasmix[flags].diluent ? DC_TANKINFO_CC_DILUENT : 0);
|
||||
tank->type = DC_TANKINFO_METRIC;
|
||||
|
||||
break;
|
||||
case DC_FIELD_SALINITY:
|
||||
|
||||
@ -305,7 +305,7 @@ liquivision_lynx_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
|
||||
tank->beginpressure = parser->tank[flags].beginpressure / 100.0;
|
||||
tank->endpressure = parser->tank[flags].endpressure / 100.0;
|
||||
tank->gasmix = DC_GASMIX_UNKNOWN;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
|
||||
@ -177,7 +177,7 @@ mares_darwin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
tank->gasmix = 0;
|
||||
tank->beginpressure = array_uint16_be (p + 0x17);
|
||||
tank->endpressure = array_uint16_be (p + 0x19);
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
} else {
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
@ -828,7 +828,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
} else {
|
||||
tank->gasmix = DC_GASMIX_UNKNOWN;
|
||||
}
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_ATMOSPHERIC:
|
||||
*((double *) value) = array_uint16_le (p + parser->layout->atmospheric) / (1000.0 * parser->layout->atmospheric_divisor);
|
||||
|
||||
@ -270,7 +270,7 @@ mares_nemo_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
|
||||
} else {
|
||||
tank->gasmix = DC_GASMIX_UNKNOWN;
|
||||
}
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_TEMPERATURE_MINIMUM:
|
||||
*((double *) value) = (signed char) p[53 - 11];
|
||||
|
||||
@ -205,7 +205,7 @@ oceanic_vtpro_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, uns
|
||||
tank->gasmix = flags;
|
||||
tank->beginpressure = beginpressure * 2 * PSI / BAR;
|
||||
tank->endpressure = endpressure * 2 * PSI / BAR;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
default:
|
||||
return DC_STATUS_UNSUPPORTED;
|
||||
|
||||
@ -123,7 +123,7 @@ typedef struct shearwater_predator_tank_t {
|
||||
unsigned int serial;
|
||||
char name[2];
|
||||
unsigned int battery;
|
||||
dc_usage_t usage;
|
||||
dc_tank_usage_t usage;
|
||||
} shearwater_predator_tank_t;
|
||||
|
||||
struct shearwater_predator_parser_t {
|
||||
@ -271,7 +271,7 @@ shearwater_common_parser_create (dc_parser_t **out, dc_context_t *context, const
|
||||
parser->tank[i].serial = 0;
|
||||
memset (parser->tank[i].name, 0, sizeof (parser->tank[i].name));
|
||||
parser->tank[i].battery = 0;
|
||||
parser->tank[i].usage = DC_USAGE_NONE;
|
||||
parser->tank[i].usage = DC_TANK_USAGE_NONE;
|
||||
parser->tankidx[i] = i;
|
||||
}
|
||||
parser->aimode = AI_OFF;
|
||||
@ -603,7 +603,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
|
||||
tank[id].enabled = 1;
|
||||
tank[id].beginpressure = pressure;
|
||||
tank[id].endpressure = pressure;
|
||||
tank[id].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN;
|
||||
//tank[id].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN; //TODO: Link this tank to the correct gasmix
|
||||
hpccr = 1;
|
||||
}
|
||||
tank[id].endpressure = pressure;
|
||||
@ -648,7 +648,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
|
||||
if (aimode == AI_HPCCR) {
|
||||
for (unsigned int i = 0; i < 2; ++i) {
|
||||
tank[4 + i].enabled = 1;
|
||||
tank[4 + i].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN;
|
||||
//tank[4 + i].usage = i == 0 ? DC_USAGE_DILUENT : DC_USAGE_OXYGEN; //TODO: Link this tank to the correct gasmix
|
||||
}
|
||||
hpccr = 1;
|
||||
}
|
||||
@ -665,7 +665,7 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser)
|
||||
if (popcount(gtrmode) >= 2) {
|
||||
for (unsigned int i = 0; i < 4; ++i) {
|
||||
if (gtrmode & (1 << i)) {
|
||||
tank[i].usage = DC_USAGE_SIDEMOUNT;
|
||||
tank[i].usage = DC_TANK_USAGE_SIDEMOUNT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -895,7 +895,7 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
|
||||
*((unsigned int *) value) = parser->ngasmixes;
|
||||
break;
|
||||
case DC_FIELD_GASMIX:
|
||||
gasmix->usage = parser->gasmix[flags].diluent ? DC_USAGE_DILUENT : DC_USAGE_NONE;
|
||||
gasmix->usage = parser->gasmix[flags].diluent ? DC_USAGE_DILUENT : DC_USAGE_OPEN_CIRCUIT;
|
||||
gasmix->oxygen = parser->gasmix[flags].oxygen / 100.0;
|
||||
gasmix->helium = parser->gasmix[flags].helium / 100.0;
|
||||
gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium;
|
||||
@ -910,21 +910,7 @@ shearwater_predator_parser_get_field (dc_parser_t *abstract, dc_field_type_t typ
|
||||
tank->beginpressure = parser->tank[flags].beginpressure * 2 * PSI / BAR;
|
||||
tank->endpressure = parser->tank[flags].endpressure * 2 * PSI / BAR;
|
||||
tank->gasmix = DC_GASMIX_UNKNOWN;
|
||||
if (shearwater_predator_is_ccr (parser->divemode) && !parser->hpccr) {
|
||||
switch (parser->tank[flags].name[0]) {
|
||||
case 'O':
|
||||
tank->usage = DC_USAGE_OXYGEN;
|
||||
break;
|
||||
case 'D':
|
||||
tank->usage = DC_USAGE_DILUENT;
|
||||
break;
|
||||
default:
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
tank->usage = parser->tank[flags].usage;
|
||||
}
|
||||
tank->usage = parser->tank[flags].usage;
|
||||
break;
|
||||
case DC_FIELD_SALINITY:
|
||||
if (parser->density == 1000)
|
||||
|
||||
@ -225,7 +225,7 @@ suunto_eon_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign
|
||||
tank->gasmix = 0;
|
||||
tank->beginpressure = beginpressure;
|
||||
tank->endpressure = endpressure;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_TEMPERATURE_MINIMUM:
|
||||
if (parser->spyder)
|
||||
|
||||
@ -985,15 +985,6 @@ static int traverse_samples(unsigned short type, const struct type_desc *desc, c
|
||||
used += bytes;
|
||||
}
|
||||
|
||||
if (info->ndl < 0 && info->ceiling) {
|
||||
dc_sample_value_t sample = {0};
|
||||
|
||||
sample.deco.type = DC_DECO_DECOSTOP;
|
||||
sample.deco.time = 0;
|
||||
sample.deco.depth = info->ceiling;
|
||||
if (info->callback) info->callback(DC_SAMPLE_DECO, &sample, info->userdata);
|
||||
}
|
||||
|
||||
// Warn if there are left-over bytes for something we did use part of
|
||||
if (used && len)
|
||||
ERROR(eon->base.context, "Entry for '%s' had %d bytes, only used %d", desc->desc, len+used, used);
|
||||
@ -1136,9 +1127,11 @@ static dc_status_t add_gas_type(suunto_eonsteel_parser_t *eon, const struct type
|
||||
tankinfo = DC_TANKVOLUME_NONE;
|
||||
else if (strcasecmp(name, "Primary"))
|
||||
DEBUG(eon->base.context, "Unknown gas type %u (%s)", type, name);
|
||||
if (name && strcasecmp(name, "Diluent") && strcasecmp(name, "Oxygen"))
|
||||
usage = DC_USAGE_OPEN_CIRCUIT;
|
||||
|
||||
eon->cache.tankinfo[idx] = tankinfo;
|
||||
eon->cache.tankusage[idx] = usage;
|
||||
eon->cache.tankusage[idx] = DC_TANK_USAGE_NONE;
|
||||
eon->cache.GASMIX[idx].usage = usage;
|
||||
|
||||
eon->cache.initialized |= 1 << DC_FIELD_GASMIX_COUNT;
|
||||
|
||||
@ -274,7 +274,7 @@ suunto_vyper_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
tank->gasmix = 0;
|
||||
tank->beginpressure = beginpressure;
|
||||
tank->endpressure = endpressure;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_TEMPERATURE_SURFACE:
|
||||
*((double *) value) = (signed char) data[8];
|
||||
|
||||
@ -189,7 +189,7 @@ uwatec_memomouse_parser_get_field (dc_parser_t *abstract, dc_field_type_t type,
|
||||
}
|
||||
tank->endpressure = 0.0;
|
||||
tank->gasmix = 0;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_TEMPERATURE_MINIMUM:
|
||||
*((double *) value) = (signed char) data[15] / 4.0;
|
||||
|
||||
@ -802,7 +802,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi
|
||||
tank->beginpressure = parser->tank[flags].beginpressure / 128.0;
|
||||
tank->endpressure = parser->tank[flags].endpressure / 128.0;
|
||||
tank->gasmix = parser->tank[flags].gasmix;
|
||||
tank->usage = DC_USAGE_NONE;
|
||||
tank->usage = DC_TANK_USAGE_NONE;
|
||||
break;
|
||||
case DC_FIELD_TEMPERATURE_MINIMUM:
|
||||
*((double *) value) = (signed short) array_uint16_le (data + table->temp_minimum) / 10.0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user