From aeac33b1a9cb3d3f7f71eb42d718a2e17753bb84 Mon Sep 17 00:00:00 2001 From: Ralph Metzler Date: Tue, 28 Jun 2016 10:42:01 +0200 Subject: [PATCH] - support quad/quattro switching - also offer status values as json files --- octoserve/dvb.c | 54 +++++++-------- octoserve/http.c | 156 +++++++++++++++++++++++++++++++++++++++++- octoserve/octoserve.c | 2 +- octoserve/octoserve.h | 3 +- octoserve/version.h | 2 +- 5 files changed, 183 insertions(+), 34 deletions(-) diff --git a/octoserve/dvb.c b/octoserve/dvb.c index aa2390b..79658c0 100644 --- a/octoserve/dvb.c +++ b/octoserve/dvb.c @@ -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); } diff --git a/octoserve/http.c b/octoserve/http.c index bb44c59..a7b6ad6 100644 --- a/octoserve/http.c +++ b/octoserve/http.c @@ -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; diff --git a/octoserve/octoserve.c b/octoserve/octoserve.c index 6156585..174f2e8 100644 --- a/octoserve/octoserve.c +++ b/octoserve/octoserve.c @@ -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; diff --git a/octoserve/octoserve.h b/octoserve/octoserve.h index bbb0ed7..869b19e 100644 --- a/octoserve/octoserve.h +++ b/octoserve/octoserve.h @@ -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; diff --git a/octoserve/version.h b/octoserve/version.h index aae30df..b84db01 100644 --- a/octoserve/version.h +++ b/octoserve/version.h @@ -19,5 +19,5 @@ #ifndef _OCTOSERVE_VERSION_ #define _OCTOSERVE_VERSION_ -#define OCTOSERVE_VERSION "1.0.68" +#define OCTOSERVE_VERSION "1.0.67" #endif