Пример #1
0
static int print_frontend_stats(FILE *fd,
				struct dvb_v5_fe_parms *parms)
{
	char buf[512], *p;
	int rc, i, len, show, n_status_lines = 0;

	rc = dvb_fe_get_stats(parms);
	if (rc) {
		ERROR(_("dvb_fe_get_stats failed"));
		return -1;
	}

	p = buf;
	len = sizeof(buf);
	dvb_fe_snprintf_stat(parms,  DTV_STATUS, NULL, 0, &p, &len, &show);

	for (i = 0; i < MAX_DTV_STATS; i++) {
		show = 1;

		dvb_fe_snprintf_stat(parms, DTV_QUALITY, _("Quality"),
				     i, &p, &len, &show);

		dvb_fe_snprintf_stat(parms, DTV_STAT_SIGNAL_STRENGTH, _("Signal"),
				     i, &p, &len, &show);

		dvb_fe_snprintf_stat(parms, DTV_STAT_CNR, _("C/N"),
				     i, &p, &len, &show);

		dvb_fe_snprintf_stat(parms, DTV_STAT_ERROR_BLOCK_COUNT, _("UCB"),
				     i,  &p, &len, &show);

		dvb_fe_snprintf_stat(parms, DTV_BER, _("postBER"),
				     i,  &p, &len, &show);

		dvb_fe_snprintf_stat(parms, DTV_PRE_BER, _("preBER"),
				     i,  &p, &len, &show);

		dvb_fe_snprintf_stat(parms, DTV_PER, _("PER"),
				     i,  &p, &len, &show);
		if (p != buf) {
			if (isatty(fileno(fd))) {
				enum dvb_quality qual;
				int color;

				qual = dvb_fe_retrieve_quality(parms, 0);

				switch (qual) {
				case DVB_QUAL_POOR:
					color = 31;
					break;
				case DVB_QUAL_OK:
					color = 36;
					break;
				case DVB_QUAL_GOOD:
					color = 32;
					break;
				case DVB_QUAL_UNKNOWN:
				default:
					color = 0;
					break;
				}
				fprintf(fd, "\033[%dm", color);
				/*
				 * It would be great to change the BELL
				 * tone depending on the quality. The legacy
				 * femon used to to that, but this doesn't
				 * work anymore with modern Linux distros.
				 *
				 * So, just print a bell if quality is good.
				 *
				 * The console audio should be enabled
				 * at the window manater for this to
				 * work.
				 */
				if (acoustical) {
					if (qual == DVB_QUAL_GOOD)
						fprintf(fd, "\a");
				}
			}

			if (n_status_lines)
				fprintf(fd, "\t%s\n", buf);
			else
				fprintf(fd, "%s\n", buf);

			n_status_lines++;

			p = buf;
			len = sizeof(buf);
		}
	}

	fflush(fd);

	return 0;
}
Пример #2
0
int dvb_fe_snprintf_stat(struct dvb_v5_fe_parms *p, uint32_t cmd,
			  char *display_name, int layer,
		          char **buf, int *len, int *show_layer_name)
{
	struct dvb_v5_fe_parms_priv *parms = (void *)p;
	struct dtv_stats *stat = NULL;
	enum dvb_quality qual = DVB_QUAL_UNKNOWN;
	enum fecap_scale_params scale;
	float val = -1;
	int initial_len = *len;
	int size, i;

	/* Print status, if layer == 0, as there is only global status */
	if (cmd == DTV_STATUS) {
		fe_status_t status;

		if (layer)
			return 0;

		if (dvb_fe_retrieve_stats(&parms->p, DTV_STATUS, &status)) {
			dvb_logerr (_("Error: no adapter status"));
			return -1;
		}
		if (display_name) {
			size = snprintf(*buf, *len, " %s=", display_name);
			*buf += size;
			*len -= size;
		}

		/* Get the name of the highest status bit */
		for (i = ARRAY_SIZE(sig_bits) - 1; i >= 0 ; i--) {
			if ((1 << i) & status) {
				size = snprintf(*buf, *len, _("%-7s"), _(sig_bits[i]));
				*buf += size;
				*len -= size;
				break;
			}
		}
		if (i < 0) {
			size = snprintf(*buf, *len, _("%7s"), "");
			*buf += size;
			*len -= size;
		}

		/* Add the status bits */
		size = snprintf(*buf, *len, "(0x%02x)", status);
		*buf += size;
		*len -= size;

		return initial_len - *len;
	}

	/* Retrieve the statistics */
	switch (cmd) {
	case DTV_PRE_BER:
		val = calculate_preBER(parms, layer);
		if (val < 0)
			return 0;
		scale = FE_SCALE_COUNTER;
		break;
	case DTV_BER:
		val = dvb_fe_retrieve_ber(&parms->p, layer, &scale);
		if (scale == FE_SCALE_NOT_AVAILABLE)
			return 0;
		break;
	case DTV_PER:
		val = dvb_fe_retrieve_per(&parms->p, layer);
		if (val < 0)
			return 0;
		scale = FE_SCALE_COUNTER;
		break;
	case DTV_QUALITY:
		qual = dvb_fe_retrieve_quality(&parms->p, layer);
		if (qual == DVB_QUAL_UNKNOWN)
			return 0;
		break;
	default:
		stat = dvb_fe_retrieve_stats_layer(&parms->p, cmd, layer);
		if (!stat || stat->scale == FE_SCALE_NOT_AVAILABLE)
			return 0;
	}

	/* If requested, prints the layer name */
	if (*show_layer_name && layer) {
		size = snprintf(*buf, *len, _("  Layer %c:"), 'A' + layer - 1);
		*buf += size;
		*len -= size;
		*show_layer_name = 0;
	}
	if (display_name) {
		size = snprintf(*buf, *len, " %s=", display_name);
		*buf += size;
		*len -= size;
	}

	/* Quality measure */
	if (qual != DVB_QUAL_UNKNOWN) {
		size = snprintf(*buf, *len, " %-4s", _(qual_name[qual]));
		*buf += size;
		*len -= size;
		return initial_len - *len;
	}


	/* Special case: float point measures like BER/PER */
	if (!stat) {
		switch (scale) {
		case FE_SCALE_RELATIVE:
			size = snprintf(*buf, *len, " %u", (unsigned int)val);
			break;
		case FE_SCALE_COUNTER:
			size = dvb_fe_snprintf_eng(*buf, *len, val);
			break;
		default:
			size = 0;
		}
		*buf += size;
		*len -= size;
		return initial_len - *len;
	}

	/* Prints the scale */
	switch (stat->scale) {
	case FE_SCALE_DECIBEL:
		if (cmd == DTV_STAT_SIGNAL_STRENGTH)
			size = snprintf(*buf, *len, " %.2fdBm", stat->svalue / 1000.);
		else
			size = snprintf(*buf, *len, " %.2fdB", stat->svalue / 1000.);
		break;
	case FE_SCALE_RELATIVE:
		size = snprintf(*buf, *len, " %3.2f%%", (100 * stat->uvalue) / 65535.);
		break;
	case FE_SCALE_COUNTER:
		size = snprintf(*buf, *len, " %" PRIu64, (uint64_t)stat->uvalue);
		break;
	default:
		size = 0;
	}
	*buf += size;
	*len -= size;

	return initial_len - *len;
}