- support quad/quattro switching

- also offer status values as json files
This commit is contained in:
Ralph Metzler 2016-06-28 10:42:01 +02:00
parent 48b5b8ef84
commit aeac33b1a9
5 changed files with 183 additions and 34 deletions

View File

@ -700,7 +700,7 @@ static int32_t dvbsq(uint32_t snr, uint32_t fec,
Quality = ((SignalToNoiseRel + 70) * BERQuality) / 100;
else
Quality = BERQuality;
return (Quality * 3) / 20;
return Quality;
}
@ -753,7 +753,7 @@ int32_t dvbs2q(int32_t snr, uint32_t fec, uint32_t mod,
Quality = ((SignalToNoiseRel + 30) * BERQuality) / 60;
else
Quality = 100;
return (Quality * 3) / 20;
return Quality;
}
static int32_t dvbcq(int32_t snr, uint32_t mod,
@ -777,7 +777,7 @@ static int32_t dvbcq(int32_t snr, uint32_t mod,
Quality = ((SignalToNoiseRel + 70) * BERQuality) / 100;
else
Quality = BERQuality;
return (Quality * 3) / 20;
return Quality;
}
static int32_t dvbtq(int32_t snr, uint32_t mod, uint32_t fec,
@ -825,7 +825,7 @@ static int32_t dvbtq(int32_t snr, uint32_t mod, uint32_t fec,
else
Quality = BERQuality;
return (Quality * 3) / 20;
return Quality;
}
static int32_t dvbt2q(int32_t snr, uint32_t mod, uint32_t fec, uint32_t trans, uint32_t pilot,
@ -915,18 +915,19 @@ static int32_t dvbt2q(int32_t snr, uint32_t mod, uint32_t fec, uint32_t trans, u
else
Quality = 100;
return (Quality * 3) / 20;
return Quality;
}
static void calc_lq(struct dvbfe *fe)
{
struct dtv_fe_stats st;
int64_t str, snr;
uint32_t mod, fec, ber_num, ber_den, trans, pilot = 0;
uint32_t mod, fec, ber_num, ber_den, trans, pilot = 0, quality = 0;
get_stat(fe->fd, DTV_STAT_SIGNAL_STRENGTH, &st);
str = st.stat[0].uvalue;
dbgprintf(DEBUG_DVB, "fe%d: str=%lld\n", fe->nr, str);
fe->strength = str;
str = (str * 48) / 10000 + 344;
if (str < 0)
str = 0;
@ -937,6 +938,7 @@ static void calc_lq(struct dvbfe *fe)
// qual: 0-15 15=BER<2*10^-4 PER<10^-7
get_stat(fe->fd, DTV_STAT_CNR, &st);
snr = st.stat[0].uvalue;
fe->snr = snr;
get_property(fe->fd, DTV_INNER_FEC, &fec);
fe->param[PARAM_FEC] = fec + 1;
get_property(fe->fd, DTV_MODULATION, &mod);
@ -952,27 +954,28 @@ static void calc_lq(struct dvbfe *fe)
dbgprintf(DEBUG_DVB, "fe%d: fec=%u mod=%u\n", fe->nr, fec, mod);
switch (fe->n_param[PARAM_MSYS] - 1) {
case SYS_DVBS:
fe->quality = dvbsq(snr, fec, ber_num, ber_den);
quality = dvbsq(snr, fec, ber_num, ber_den);
break;
case SYS_DVBS2:
fe->quality = dvbs2q(snr, fec, mod, ber_num, ber_den);
quality = dvbs2q(snr, fec, mod, ber_num, ber_den);
break;
case SYS_DVBC_ANNEX_A:
fe->quality = dvbcq(snr, mod, ber_num, ber_den);
quality = dvbcq(snr, mod, ber_num, ber_den);
break;
case SYS_DVBT:
fe->quality = dvbtq(snr, mod, fec, ber_num, ber_den);
quality = dvbtq(snr, mod, fec, ber_num, ber_den);
break;
case SYS_DVBT2:
get_property(fe->fd, DTV_TRANSMISSION_MODE, &trans);
dbgprintf(DEBUG_DVB, "fe%d: trans=%u pilot=%u\n", fe->nr, trans, pilot);
fe->quality = dvbt2q(snr, mod, fec, trans, pilot, ber_num, ber_den);
quality = dvbt2q(snr, mod, fec, trans, pilot, ber_num, ber_den);
break;
case SYS_DVBC2:
break;
default:
break;
}
fe->quality = quality;
dbgprintf(DEBUG_DVB, "fe%d: level=%u quality=%u\n", fe->nr, fe->level, fe->quality);
}
@ -1132,16 +1135,14 @@ static int init_fe(struct octoserve *os, int a, int f, int fd, int nodvbt, int m
}
if (fe->input[3]) {
os->has_feswitch = 1;
if (!msmode) {
if (!os->scif_type && !msmode) {
if (fe->input[2] >= fe->input[1]) {
fe->type = 0;
return -1;
}
} else
os->do_feswitch = msmode;
}
}
os->dvbfe_num++;
os->dvbfe_num++;
pthread_mutex_init(&fe->mutex, 0);
return 0;
}
@ -1750,26 +1751,23 @@ void lnb_config(struct octoserve *os, char *name, char *val)
int init_dvb(struct octoserve *os, int nodvbt, int msmode)
{
int i, j;
uint32_t fmode;
pthread_mutex_init(&nsd_lock, 0);
pthread_mutex_init(&os->uni_lock, 0);
os->scif_type = 0;
parse_config(os, "scif", &scif_config);
scan_dvbfe(os, nodvbt, msmode);
scan_dvbca(os);
os->scif_type = 0;
parse_config(os, "scif", &scif_config);
if (os->has_feswitch) {
uint32_t fmode = 0;
if (os->do_feswitch) {
fmode = msmode;
if (os->scif_type)
fmode = 0;//3;
}
if (os->scif_type)
fmode = 0;
else
fmode = msmode;
if (os->has_feswitch)
set_fmode(fmode);
}
set_lnb(os, 0, 0, 9750000, 10600000, 11700000);
parse_config(os, "LNB", &lnb_config);
}

View File

@ -196,6 +196,10 @@ char httpjava[] =
"HTTP/1.0 200 OK\r\nConnection: close\r\nPragma: no-cache\r\n"
"Content-Type: application/x-javascript\r\n\r\n";
char httpjson[] =
"HTTP/1.0 200 OK\r\nConnection: close\r\nPragma: no-cache\r\n"
"Content-Type: application/json\r\n\r\n";
#define sendstr(_fd_,...) do { \
len = snprintf(buf, sizeof(buf), __VA_ARGS__); \
if (len <= 0 || len >= sizeof(buf)) \
@ -219,7 +223,7 @@ void send_serverinfo(struct os_ssdp *ss)
sendstr(fd, "Octoserve.MAC = \"%02x:%02x:%02x:%02x:%02x:%02x\";\r\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sendstr(fd, "Octoserve.TunerList = new Array();\r\n");
for (i = 0; i < MAX_DVB_FE; i++) {
for (i = 0; i < os->dvbfe_num; i++) {
struct dvbfe *fe = &os->dvbfe[i];
if (fe->type) {
@ -265,6 +269,73 @@ void send_serverinfo(struct os_ssdp *ss)
}
}
void send_json_serverinfo(struct os_ssdp *ss)
{
struct octoserve *os = ss->os;
struct dvbfe *fe;
uint8_t buf[2048];
int i, j, fd = ss->csock, len;
uint8_t *mac = &ss->os->mac[0];
sendlen(fd, httpjson, sizeof(httpjson) - 1);
sendstr(fd, "{\r\n");
sendstr(fd, "\"Version\":" OCTOSERVE_VERSION ",\r\n");
sendstr(fd, "\"BootID\":%u,\r\n", ss->bootid);
sendstr(fd, "\"DeviceID\":%u,\r\n", ss->devid);
sendstr(fd, "\"MAC\":\"%02x:%02x:%02x:%02x:%02x:%02x\",\r\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
sendstr(fd, "TunerList\":[\r\n");
for (i = 0; i < os->dvbfe_num; i++) {
struct dvbfe *fe = &os->dvbfe[i];
if (i)
sendstr(fd, ",\r\n");
sendstr(fd, "{\"Input\":\"%u\"", i);
if (fe->type) {
char types[80];
int pos;
types[0] = 0;
if (fe->type & 0xb00ee) {
strcat(types, "DVB");
pos = strlen(types);
if (fe->type & (1 << SYS_DVBS))
strcat(types, "/S");
if (fe->type & (1 << SYS_DVBS2))
strcat(types, "/S2");
if (fe->type & (1 << SYS_DVBC_ANNEX_A))
strcat(types, "/C");
if (fe->type & (1 << SYS_DVBC2))
strcat(types, "/C2");
if (fe->type & (1 << SYS_DVBT))
strcat(types, "/T");
if (fe->type & (1 << SYS_DVBT2))
strcat(types, "/T2");
strcat(types, " ");
types[pos] = '-';
}
if (fe->type & 0x700) {
strcat(types, "ISDB");
pos = strlen(types);
if (fe->type & (1 << SYS_ISDBT))
strcat(types, "/T");
if (fe->type & (1 << SYS_ISDBS))
strcat(types, "/S");
if (fe->type & (1 << SYS_ISDBC))
strcat(types, "/C");
types[pos] = '-';
}
sendstr(fd, ",\"Present\":true", i);
sendstr(fd, ",\"Type\":0");
sendstr(fd, ",\"Desc\":\"%s\"", types);
} else {
sendstr(fd, "\"Present\":false", i);
}
sendstr(fd, "}");
}
sendstr(fd, "\r\n]\r\n}\r\n");
}
void send_tunerstatus(struct os_ssdp *ss)
{
struct octoserve *os = ss->os;
@ -274,7 +345,7 @@ void send_tunerstatus(struct os_ssdp *ss)
sendlen(fd, httpjava, sizeof(httpjava) - 1);
sendstr(fd, "TunerList = new Array();\r\n");
for (i = 0; i < MAX_DVB_FE; i++) {
for (i = 0; i < os->dvbfe_num; i++) {
fe = &os->dvbfe[i];
sendstr(fd, "TunerList[%d] = new Object();\r\n", i);
sendstr(fd, "TunerList[%d].Active = %s;\r\n", i, fe->state ? "true" : "false");
@ -286,6 +357,31 @@ void send_tunerstatus(struct os_ssdp *ss)
}
}
void send_json_tunerstatus(struct os_ssdp *ss)
{
struct octoserve *os = ss->os;
struct dvbfe *fe;
uint8_t buf[2048];
int len, i, fd = ss->csock;
sendlen(fd, httpjson, sizeof(httpjson) - 1);
sendstr(fd, "{\"TunerList\":[\r\n");
for (i = 0; i < os->dvbfe_num; i++) {
if (i)
sendstr(fd, ",\r\n");
fe = &os->dvbfe[i];
sendstr(fd, "{\"Input\":\"%u\"", i);
sendstr(fd, ",\"Status\":\"%s\"", fe->state ? "Active" : "Inactive");
sendstr(fd, ",\"Lock\":%s", fe->lock ? "true" : "false");
sendstr(fd, ",\"Strength\":\"%d\"", fe->strength);
sendstr(fd, ",\"SNR\":\"%d\"", fe->snr);
sendstr(fd, ",\"Quality\":\"%u\"", fe->quality);
sendstr(fd, ",\"Level\":\"%u\"", fe->level);
sendstr(fd, "}");
}
sendstr(fd, "\r\n]}\r\n");
}
static uint32_t ddreg(int fd, uint32_t reg)
{
struct ddb_reg ddr = { .reg = reg };
@ -343,6 +439,51 @@ static void send_streamstatus(struct os_ssdp *ss)
close(dd);
}
static void send_json_streamstatus(struct os_ssdp *ss)
{
struct octoserve *os = ss->os;
struct osstrm *oss;
uint8_t buf[2048];
int len, i, fd = ss->csock;
struct timeval tval;
struct timespec tp;
int dd;
dd = open("/dev/ddbridge/card0", O_RDWR); /* FIXME: replace with ioctls */
if (dd < 0)
return;
clock_gettime(CLOCK_MONOTONIC, &tp);
gettimeofday(&tval, NULL);
sendlen(fd, httpjson, sizeof(httpjson) - 1);
sendstr(fd, "{\"Timestamp\":%u,\r\n", (uint32_t) (tp.tv_sec * 1000 + tp.tv_nsec / 1000000));
sendstr(fd, "\"StreamList\":[\r\n");
for (i = 0; i < MAX_STREAM; i++) {
uint32_t ctrl = ddreg(dd, 0x400 + i*0x20);
if (i)
sendstr(fd, ",\r\n");
sendstr(fd, "{\"Status\":\"%s\"", (ctrl & 1) ? "Active" : "Inactive");
sendstr(fd, ",\"Input\":%u", (ctrl >> 8) & 7);
sendstr(fd, ",\"Packets\":%u", ddreg(dd, 0x41c + i*0x20));
sendstr(fd, ",\"Bytes\":%u", ddreg(dd, 0x418 + i*0x20));
if (ctrl & 1) {
uint32_t off = 0x2000 + i * 0x200;
uint8_t mem[64];
ddrmem(dd, mem, off, sizeof(mem));
off = 30;
if (mem[12] == 0x81)
off += 4;
sendstr(fd, ",\"Client\":\"%u.%u.%u.%u\"",
mem[off], mem[off + 1], mem[off + 2], mem[off + 3]);
} else
sendstr(fd, ",\"Client\":\"\"");
sendstr(fd, "}");
}
sendstr(fd, "\r\n]\r\n}\r\n");
close(dd);
}
static void send_octoserve(struct os_ssdp *ss)
{
struct octoserve *os = ss->os;
@ -351,7 +492,7 @@ static void send_octoserve(struct os_ssdp *ss)
int len, i;
send(ss->csock, httptxt, sizeof(httptxt), 0);
for (i = 0; i < MAX_DVB_FE; i++) {
for (i = 0; i < os->dvbfe_num; i++) {
fe = &os->dvbfe[i];
if (!fe->state)
continue;
@ -389,12 +530,21 @@ void handle_http(struct os_ssdp *ss)
if (!strncasecmp("GET /octonet.xml", buf, 16)) {
send_xml(ss);
break;
} else if (!strncasecmp("GET /serverinfo.json", buf, 20)) {
send_json_serverinfo(ss);
break;
} else if (!strncasecmp("GET /serverinfo.js", buf, 18)) {
send_serverinfo(ss);
break;
} else if (!strncasecmp("GET /streamstatus.json", buf, 22)) {
send_json_streamstatus(ss);
break;
} else if (!strncasecmp("GET /streamstatus.js", buf, 20)) {
send_streamstatus(ss);
break;
} else if (!strncasecmp("GET /tunerstatus.json", buf, 21)) {
send_json_tunerstatus(ss);
break;
} else if (!strncasecmp("GET /tunerstatus.js", buf, 19)) {
send_tunerstatus(ss);
break;

View File

@ -728,7 +728,7 @@ static int session_string(struct ossess *sess, char *msg, int mlen)
if (str->fe){
level = str->fe->level;
lock = str->fe->lock;
quality = str->fe->quality;
quality = (str->fe->quality * 3) / 20;
tuner = str->fe->nr;
}
p = &sess->p;

View File

@ -202,6 +202,8 @@ struct dvbfe {
uint32_t level;
uint32_t lock;
uint32_t quality;
int32_t strength;
int32_t snr;
int first;
uint32_t tune;
@ -458,7 +460,6 @@ struct octoserve {
int scif_type;
int has_feswitch;
int do_feswitch;
int strict_satip;
int dvbfe_num;

View File

@ -19,5 +19,5 @@
#ifndef _OCTOSERVE_VERSION_
#define _OCTOSERVE_VERSION_
#define OCTOSERVE_VERSION "1.0.68"
#define OCTOSERVE_VERSION "1.0.67"
#endif