[hack] First attempt at a status reporting screen
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
This commit is contained in:
parent
a00ca1f53d
commit
714b9fbd1e
|
@ -21,6 +21,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <osmocom/core/gsmtap.h>
|
#include <osmocom/core/gsmtap.h>
|
||||||
#include <osmocom/core/gsmtap_util.h>
|
#include <osmocom/core/gsmtap_util.h>
|
||||||
|
@ -38,6 +41,7 @@
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct app_state *as;
|
struct app_state *as;
|
||||||
|
struct stat ss;
|
||||||
int rv = 0, i;
|
int rv = 0, i;
|
||||||
|
|
||||||
/* Args */
|
/* Args */
|
||||||
|
@ -62,6 +66,11 @@ int main(int argc, char *argv[])
|
||||||
as->gti = gsmtap_source_init("127.0.0.1", GSMTAP_UDP_PORT, 0);
|
as->gti = gsmtap_source_init("127.0.0.1", GSMTAP_UDP_PORT, 0);
|
||||||
gsmtap_source_add_sink(as->gti);
|
gsmtap_source_add_sink(as->gti);
|
||||||
|
|
||||||
|
/* Open status */
|
||||||
|
rv = stat("/tmp/gmr_rx_status", &ss);
|
||||||
|
if (!rv && (ss.st_mode & S_IFIFO))
|
||||||
|
as->status = fopen("/tmp/gmr_rx_status", "w");
|
||||||
|
|
||||||
/* Buffer */
|
/* Buffer */
|
||||||
as->buf = sbuf_alloc(as->n_chans);
|
as->buf = sbuf_alloc(as->n_chans);
|
||||||
if (!as->buf) {
|
if (!as->buf) {
|
||||||
|
@ -116,7 +125,42 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go forth and process ! */
|
/* Go forth and process ! */
|
||||||
sbuf_work(as->buf);
|
int iter = 0;
|
||||||
|
while (sbuf_work(as->buf))
|
||||||
|
{
|
||||||
|
if (iter++ < 100)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
iter = 0;
|
||||||
|
|
||||||
|
if (!as->status)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fprintf(as->status, "\033c");
|
||||||
|
fprintf(as->status, "GMR-1 RX status\n");
|
||||||
|
fprintf(as->status, "---------------\n");
|
||||||
|
fprintf(as->status, "\n");
|
||||||
|
|
||||||
|
for (i=0; i<as->buf->n_chans; i++)
|
||||||
|
{
|
||||||
|
struct sample_actor *sact, *tmp;
|
||||||
|
|
||||||
|
llist_for_each_entry_safe(sact, tmp, &as->buf->chans[i].consumers, list)
|
||||||
|
{
|
||||||
|
fprintf(as->status, "ARFCN %4d: Task %s (%p)\n",
|
||||||
|
as->chans[i].arfcn,
|
||||||
|
sact->desc->name,
|
||||||
|
sact
|
||||||
|
);
|
||||||
|
if (sact->desc->stat)
|
||||||
|
sact->desc->stat(sact, as->status);
|
||||||
|
fprintf(as->status, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(as->status, "\n");
|
||||||
|
fflush(as->status);
|
||||||
|
}
|
||||||
|
|
||||||
/* Done ! */
|
/* Done ! */
|
||||||
rv = 0;
|
rv = 0;
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define __RTFWK_COMMON_H__
|
#define __RTFWK_COMMON_H__
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <osmocom/dsp/cxvec.h>
|
#include <osmocom/dsp/cxvec.h>
|
||||||
#include <osmocom/dsp/cxvec_math.h>
|
#include <osmocom/dsp/cxvec_math.h>
|
||||||
|
@ -46,6 +47,9 @@ struct app_state
|
||||||
/* GSMTap */
|
/* GSMTap */
|
||||||
struct gsmtap_inst *gti;
|
struct gsmtap_inst *gti;
|
||||||
|
|
||||||
|
/* Status */
|
||||||
|
FILE *status;
|
||||||
|
|
||||||
/* Per-Channel data */
|
/* Per-Channel data */
|
||||||
struct {
|
struct {
|
||||||
int arfcn;
|
int arfcn;
|
||||||
|
|
|
@ -57,6 +57,9 @@ struct bcch_sink_priv {
|
||||||
|
|
||||||
float bcch_energy;
|
float bcch_energy;
|
||||||
int bcch_err;
|
int bcch_err;
|
||||||
|
int bcch_stat_tot;
|
||||||
|
int bcch_stat_err;
|
||||||
|
float bcch_stat_conv;
|
||||||
|
|
||||||
int la_arfcn;
|
int la_arfcn;
|
||||||
int la_tn;
|
int la_tn;
|
||||||
|
@ -187,6 +190,10 @@ _rx_bcch(struct sample_actor *sa,
|
||||||
else
|
else
|
||||||
priv->bcch_err++;
|
priv->bcch_err++;
|
||||||
|
|
||||||
|
priv->bcch_stat_tot++;
|
||||||
|
priv->bcch_stat_err += (crc != 0);
|
||||||
|
priv->bcch_stat_conv = 0.99f * priv->bcch_stat_conv + 0.01f * conv;
|
||||||
|
|
||||||
/* Send to GSMTap if correct */
|
/* Send to GSMTap if correct */
|
||||||
if (!crc)
|
if (!crc)
|
||||||
gsmtap_sendmsg(priv->as->gti, gmr1_gsmtap_makemsg(
|
gsmtap_sendmsg(priv->as->gti, gmr1_gsmtap_makemsg(
|
||||||
|
@ -384,9 +391,23 @@ bcch_sink_work(struct sample_actor *sa,
|
||||||
return frame_len;
|
return frame_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bcch_sink_stat(struct sample_actor *sa,
|
||||||
|
FILE *out)
|
||||||
|
{
|
||||||
|
struct bcch_sink_priv *priv = sa->priv;
|
||||||
|
|
||||||
|
fprintf(out, "\tbcch_tot : %d\n", priv->bcch_stat_tot);
|
||||||
|
fprintf(out, "\tbcch_err : %d (%.1f %%)\n", priv->bcch_stat_err,
|
||||||
|
(100.0f * (float)priv->bcch_stat_err) / (float)priv->bcch_stat_tot);
|
||||||
|
fprintf(out, "\tbcch_conv : %d\n", (int)priv->bcch_stat_conv);
|
||||||
|
}
|
||||||
|
|
||||||
const struct sample_actor_desc bcch_sink = {
|
const struct sample_actor_desc bcch_sink = {
|
||||||
|
.name = "BCCH/CCCH",
|
||||||
.init = bcch_sink_init,
|
.init = bcch_sink_init,
|
||||||
.fini = bcch_sink_fini,
|
.fini = bcch_sink_fini,
|
||||||
.work = bcch_sink_work,
|
.work = bcch_sink_work,
|
||||||
|
.stat = bcch_sink_stat,
|
||||||
.priv_size = sizeof(struct bcch_sink_priv),
|
.priv_size = sizeof(struct bcch_sink_priv),
|
||||||
};
|
};
|
||||||
|
|
|
@ -261,6 +261,7 @@ fcch_sink_work(struct sample_actor *sa,
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct sample_actor_desc fcch_sink = {
|
const struct sample_actor_desc fcch_sink = {
|
||||||
|
.name = "FCCH",
|
||||||
.init = fcch_sink_init,
|
.init = fcch_sink_init,
|
||||||
.fini = fcch_sink_fini,
|
.fini = fcch_sink_fini,
|
||||||
.work = fcch_sink_work,
|
.work = fcch_sink_work,
|
||||||
|
|
|
@ -101,6 +101,7 @@ sa_file_sink_work(struct sample_actor *sc,
|
||||||
|
|
||||||
|
|
||||||
const struct sample_actor_desc sa_file_src = {
|
const struct sample_actor_desc sa_file_src = {
|
||||||
|
.name = "File Source",
|
||||||
.init = sa_file_src_init,
|
.init = sa_file_src_init,
|
||||||
.fini = sa_file_fini,
|
.fini = sa_file_fini,
|
||||||
.work = sa_file_src_work,
|
.work = sa_file_src_work,
|
||||||
|
@ -108,6 +109,7 @@ const struct sample_actor_desc sa_file_src = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct sample_actor_desc sa_file_sink = {
|
const struct sample_actor_desc sa_file_sink = {
|
||||||
|
.name = "File Sink",
|
||||||
.init = sa_file_sink_init,
|
.init = sa_file_sink_init,
|
||||||
.fini = sa_file_fini,
|
.fini = sa_file_fini,
|
||||||
.work = sa_file_sink_work,
|
.work = sa_file_sink_work,
|
||||||
|
|
|
@ -464,6 +464,7 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct sample_actor_desc tch3_sink = {
|
const struct sample_actor_desc tch3_sink = {
|
||||||
|
.name = "TCH3",
|
||||||
.init = tch3_sink_init,
|
.init = tch3_sink_init,
|
||||||
.fini = tch3_sink_fini,
|
.fini = tch3_sink_fini,
|
||||||
.work = tch3_sink_work,
|
.work = tch3_sink_work,
|
||||||
|
|
|
@ -251,6 +251,7 @@ tch9_sink_work(struct sample_actor *sa,
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct sample_actor_desc tch9_sink = {
|
const struct sample_actor_desc tch9_sink = {
|
||||||
|
.name = "TCH9",
|
||||||
.init = tch9_sink_init,
|
.init = tch9_sink_init,
|
||||||
.fini = tch9_sink_fini,
|
.fini = tch9_sink_fini,
|
||||||
.work = tch9_sink_work,
|
.work = tch9_sink_work,
|
||||||
|
|
|
@ -323,39 +323,39 @@ _sbuf_consume(struct sample_buf *sbuf)
|
||||||
return work_done;
|
return work_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
sbuf_work(struct sample_buf *sbuf)
|
sbuf_work(struct sample_buf *sbuf)
|
||||||
{
|
{
|
||||||
int i, rv;
|
int i, rv;
|
||||||
int has_produced, has_consumed;
|
int has_produced, has_consumed;
|
||||||
int has_producers, has_consumers;
|
int has_producers, has_consumers;
|
||||||
|
|
||||||
while (1) {
|
/* Produce / Consume */
|
||||||
/* Produce / Consume */
|
has_produced = _sbuf_produce(sbuf);
|
||||||
has_produced = _sbuf_produce(sbuf);
|
|
||||||
|
|
||||||
has_consumed = 0;
|
has_consumed = 0;
|
||||||
do {
|
do {
|
||||||
rv = _sbuf_consume(sbuf);
|
rv = _sbuf_consume(sbuf);
|
||||||
has_consumed |= rv;
|
has_consumed |= rv;
|
||||||
} while (rv);
|
} while (rv);
|
||||||
|
|
||||||
/* Check if there is any producers left */
|
/* Check if there is any producers left */
|
||||||
has_producers = 0;
|
has_producers = 0;
|
||||||
for (i=0; i<sbuf->n_chans; i++)
|
for (i=0; i<sbuf->n_chans; i++)
|
||||||
has_producers |= (sbuf->chans[i].producer != NULL);
|
has_producers |= (sbuf->chans[i].producer != NULL);
|
||||||
|
|
||||||
/* Check if there is any consumer left */
|
/* Check if there is any consumer left */
|
||||||
for (i=0; i<sbuf->n_chans; i++)
|
for (i=0; i<sbuf->n_chans; i++)
|
||||||
if (!llist_empty(&sbuf->chans[i].consumers))
|
if (!llist_empty(&sbuf->chans[i].consumers))
|
||||||
break;
|
|
||||||
has_consumers = (i != sbuf->n_chans);
|
|
||||||
|
|
||||||
/* Check exit conditions */
|
|
||||||
if (!has_consumers)
|
|
||||||
break;
|
break;
|
||||||
|
has_consumers = (i != sbuf->n_chans);
|
||||||
|
|
||||||
if (!has_consumed && !has_producers)
|
/* Check exit conditions */
|
||||||
break;
|
if (!has_consumers)
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
|
if (!has_consumed && !has_producers)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include <complex.h>
|
#include <complex.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
|
@ -35,10 +36,14 @@
|
||||||
struct sample_actor;
|
struct sample_actor;
|
||||||
|
|
||||||
struct sample_actor_desc {
|
struct sample_actor_desc {
|
||||||
|
const char *name;
|
||||||
|
|
||||||
int (*init)(struct sample_actor *sc, void *params);
|
int (*init)(struct sample_actor *sc, void *params);
|
||||||
void (*fini)(struct sample_actor *sc);
|
void (*fini)(struct sample_actor *sc);
|
||||||
int (*work)(struct sample_actor *sc,
|
int (*work)(struct sample_actor *sc,
|
||||||
float complex *data, unsigned int len);
|
float complex *data, unsigned int len);
|
||||||
|
void (*stat)(struct sample_actor *sc, FILE *fh);
|
||||||
|
|
||||||
int priv_size;
|
int priv_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,7 +112,7 @@ sbuf_add_consumer(struct sample_buf *sbuf, int chan_id,
|
||||||
const struct sample_actor_desc *desc, void *params);
|
const struct sample_actor_desc *desc, void *params);
|
||||||
|
|
||||||
|
|
||||||
void sbuf_work(struct sample_buf *sbuf);
|
int sbuf_work(struct sample_buf *sbuf);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __RTFWK_SAMPBUF_H__ */
|
#endif /* __RTFWK_SAMPBUF_H__ */
|
||||||
|
|
Loading…
Reference in New Issue