16 Commits

Author SHA1 Message Date
Jaroslav Kysela
fb0fd9fdbb minisatip8: more multistream fixes (add PLS ROOT mode support) 2018-10-13 00:51:02 +02:00
Jaroslav Kysela
47de7247b5 i2c_mangle: allow to set PLS mode, too 2018-10-13 00:48:30 +02:00
Jaroslav Kysela
6c7c2fb61e i2c_mangle: fix msi -> mis typo 2018-10-12 11:24:41 +02:00
Jaroslav Kysela
83d670b4c8 updated minisatip8 - multistream, diseqc address 2018-10-12 11:24:41 +02:00
perexg
9c91484e29 Update README 2018-10-12 11:24:40 +02:00
perexg
da33b45c9d Update README.md 2018-10-12 11:24:40 +02:00
Jaroslav Kysela
a0060a0d3a i2c_mangle module: add support for mis/pls settings (multistream) 2018-10-12 09:23:30 +02:00
Jaroslav Kysela
41964656ff dist/README: add note that releases are on github now 2018-10-08 17:40:20 +02:00
Jaroslav Kysela
495bc2efe4 README.md sync 2018-10-08 17:38:30 +02:00
Oliver Kurz
8f633628b9 Delete outdated firmware images which are better provided by github releases 2018-10-08 16:59:00 +02:00
Oliver Kurz
85f777c078 dist: Add notes regarding automount, missing web interface and DLNA 2018-10-08 16:58:42 +02:00
Jaroslav Kysela
516c4b1cb6 minisatip.md: remove -S for minisatip8 in the first table 2018-09-25 13:38:47 +02:00
Jaroslav Kysela
69febad731 added multicast-rtp-2.tar.gz and Python-3.5.6-1.tar.gz 2018-09-25 11:16:42 +02:00
Jaroslav Kysela
686cf548a7 fix python3-makefile.patch 2018-09-25 11:16:42 +02:00
Jaroslav Kysela
6b3ee4236f upgrade multicast-rtp, upgrade to python 3.5.6, upgrade oscam to 11432
Thanks to @lars18th on github for the multicast-rtp improvement.
2018-09-25 11:16:13 +02:00
Jaroslav Kysela
1472ca205c minisatip8: polarization fix 2018-09-24 20:37:20 +02:00
17 changed files with 1111 additions and 145 deletions

View File

@@ -69,18 +69,18 @@ NANO_FILENAME=$(NANO).tar.gz
NANO_DOWNLOAD=http://www.nano-editor.org/dist/v2.8/$(NANO_FILENAME)
PYTHON3_VERSION0=3.5
PYTHON3_VERSION=$(PYTHON3_VERSION0).3
PYTHON3_VERSION=$(PYTHON3_VERSION0).6
PYTHON3=Python-$(PYTHON3_VERSION)
PYTHON3_PACKAGE_NAME=$(PYTHON3)-1
PYTHON3_FILENAME=$(PYTHON3).tgz
PYTHON3_DOWNLOAD=https://www.python.org/ftp/python/$(PYTHON3_VERSION)/$(PYTHON3_FILENAME)
MULTICAST_RTP_PACKAGE_NAME=multicast-rtp-1
MULTICAST_RTP_PACKAGE_NAME=multicast-rtp-2
TVHEADEND_COMMIT=master
# 10663 10937 11234
OSCAM_REV=11398
# 10663 10937 11234 11398
OSCAM_REV=11432
define GIT_CLONE
@mkdir -p apps/host

View File

@@ -5,47 +5,23 @@ A firmware with minisatip for Inverto IDL-400s/Grundig GSS.BOX/Telestar Digibit
[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](http://paypal.me/perex)
The firmware contains various versions of [minisatip](https://github.com/catalinii/minisatip)
which is tuned to get the best performance on this hardware. There are many extensions for
the complex hobby satellite reception (like free input mode - use any tuner with any physical input,
DVB-S2 multistream support etc.).
There is no DLNA server, but there is HTTP and FTP server to server for
example m3u playlists to clients.
Releases:
---------
- download from [github releases](https://github.com/perexg/satip-axe/releases)
- see to [dist](https://github.com/perexg/satip-axe/tree/master/dist) directory - README file
- a TTL USB serial is not required to boot this precompiled firmware
from the USB stick or an installation to the internal flash
A notes for developers (might be outdated):
-------------------------------------------
Developers:
-----------
Requirements:
- git, python
- STLinux 2.4 (all-sh4-glibc) - http://www.stlinux.com - installed to /opt/STM/STLinux-2.4/
- fakeroot package/tools
Compilation:
- just type 'make'
- kernel with rootfs is in kernel/arch/sh/boot/uImage.gz
Booting uImage.gz on Inverto IDL-400S/Grundig GSS.BOX/Telestar Digibit R1 from USB:
- connect TTL USB serial adapter to J3 connector (4 pins at the power supply)
- pin 1 = 3.6V (do not use), pin 2 = GND, pin 3 = RXD (STM CPU), pin 4 = TXD (STM CPU)
- parameters: 115200,8N1
- press 'Enter' when you turn on the box (you have only one second) to get 'idl4k> ' prompt
(it seems that 'Enter' is required also to enable the serial console)
- modify bootargs (optional - for original firmware)
set bootargs=console=ttyAS0,115200
- set debugfw environment variable
set debugfw "debugfw=usb start;usb start;fatload usb 0 0x84000000 uimage.gz;set bootargs console=ttyAS0,115200 bigphysarea=20000;bootm 0x84000000"
- you may type 'save' to store this settings permanently
- to execute the debugfw type 'run debugfw'
- note that the USB stick should be in the first (upper) USB connector
Configuration
- dhcp client, telnetd, dropbear (ssh daemon) and minisatip are active by default
- configuration is stored in /etc/sysconfig/config
- see [debug](https://github.com/perexg/satip-axe/tree/master/debug)

37
debug/README.md Normal file
View File

@@ -0,0 +1,37 @@
A notes for developers (might be outdated):
-------------------------------------------
Requirements:
- git, python
- STLinux 2.4 (all-sh4-glibc) - http://www.stlinux.com - installed to /opt/STM/STLinux-2.4/
- fakeroot package/tools
Compilation:
- just type 'make'
- kernel with rootfs is in kernel/arch/sh/boot/uImage.gz
Booting uImage.gz on Inverto IDL-400S/Grundig GSS.BOX/Telestar Digibit R1 from USB:
- connect TTL USB serial adapter to J3 connector (4 pins at the power supply)
- pin 1 = 3.6V (do not use), pin 2 = GND, pin 3 = RXD (STM CPU), pin 4 = TXD (STM CPU)
- parameters: 115200,8N1
- press 'Enter' when you turn on the box (you have only one second) to get 'idl4k> ' prompt
(it seems that 'Enter' is required also to enable the serial console)
- modify bootargs (optional - for original firmware)
set bootargs=console=ttyAS0,115200
- set debugfw environment variable
set debugfw "debugfw=usb start;usb start;fatload usb 0 0x84000000 uimage.gz;set bootargs console=ttyAS0,115200 bigphysarea=20000;bootm 0x84000000"
- you may type 'save' to store this settings permanently
- to execute the debugfw type 'run debugfw'
- note that the USB stick should be in the first (upper) USB connector
Configuration
- dhcp client, telnetd, dropbear (ssh daemon) and minisatip are active by default
- configuration is stored in /etc/sysconfig/config

10
dist/README vendored
View File

@@ -79,6 +79,7 @@ Customization:
- if /etc/sysconfig/profile script exists, it is executed at login
- writeable ftp - copy /etc/inetd.conf to /etc/sysconfig/inetd.conf and
add -w argument to the ftpd daemon
- flash drives are automounted on /media
httpd:
------
@@ -200,6 +201,11 @@ Notes:
- the original firmware uses fw1-nand0 flash region (32M)
- the satip-axe firmware uses fw2-nand0 flash region (32M)
- data block is named data-nand0 - uses rest of flash
- the original firmware provides a web interface for administration, the
satip-axe uses local files for configuration.
- the original firmware provides a DLNA server. Within satip-axe the http
server can be used to provide for example channels maps in the form of
.m3u files
Disclaimer:
-----------
@@ -244,12 +250,14 @@ Bugs:
History:
--------
satip-axe-2018 - ??
satip-axe-2018 (build15) - ??
- moved the releases (firmware files) to github
- added minisatip8
- updated minisatip code (latest minisatip 0.7.16)
- note that some options were removed (-M) or added (-2)
- follow /etc/config.default and this file
- fixed reported VDR problem (issue #108)
- added DVB-S2 multistream support
- fixed the improper tuner release problem for complex diseqc settings
where one input is used by multiple tuners (minisatip7 and minisatip8)
- added SYSLOGD_OPTS to pass extra options to syslog

2
dist/minisatip.md vendored
View File

@@ -11,7 +11,7 @@ NOTE: Some options identifiers were changed between minisatip5 and minisatip7:
minisatip7,8 | minisatip5/minisatip | description
-------------|----------------------|-----------------------------------
-7 | -L | tuner linking
-9 | -X | unicable input (-S for minisatip8)
-9 | -X | unicable input
-W | -P | AXE power
-8 | -Z | quattro hiband mode

BIN
dist/packages/Python-3.5.6-1.tar.gz vendored Normal file

Binary file not shown.

BIN
dist/packages/multicast-rtp-2.tar.gz vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,8 +1,49 @@
diff --git a/html/status.html b/html/status.html
index 8812322..519f3da 100755
--- a/html/status.html
+++ b/html/status.html
@@ -133,6 +133,7 @@
myTable += "<th class='dt-right'>Pos.</th>";
myTable += "<th class='dt-right'>Frequency</th>";
myTable += "<th class='dt-right'>SR/BW</th>";
+ myTable += "<th class='dt-right'>Stream</th>";
myTable += "<th class='dt-right'>Signal</th>";
if (has_axe) {
myTable += "<th class='dt-right'>Packets</th>";
@@ -202,6 +203,12 @@
else
myTable += "<td class='dt-right'></td>";
+ // STREAM
+ var stream = state['ad_stream'][i];
+ if (parseInt(stream) <= 0)
+ stream = '';
+ myTable += "<td class='dt-right'>" + stream + " </td>";
+
// SIGNAL
var signal = "";
if (!ad_enabled) {
@@ -227,6 +234,7 @@
}
myTable += "<td class='dt-right'>" + signal + " </td>";
+ // AXE
if (has_axe) {
myTable += "<td class='dt-right'>" + state['ad_axe_pktc'][i] + " </td>";
myTable += "<td class='dt-right'>" + state['ad_axe_ccerr'][i] + " </td>";
diff --git a/src/adapter.c b/src/adapter.c
index e034e3e..f7727b8 100644
index e034e3e..9862114 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -550,7 +550,7 @@ int getAdaptersCount()
@@ -75,6 +75,7 @@ adapter *adapter_alloc()
/* diseqc setup */
ad->diseqc_param.fast = opts.diseqc_fast;
+ ad->diseqc_param.addr = opts.diseqc_addr;
ad->diseqc_param.committed_no = opts.diseqc_committed_no;
ad->diseqc_param.uncommitted_no = opts.diseqc_uncommitted_no;
@@ -550,7 +551,7 @@ int getAdaptersCount()
memset(&fe_map, -1, sizeof(fe_map));
k = 0;
@@ -11,7 +52,7 @@ index e034e3e..f7727b8 100644
{
int sys = order[i];
for (j = 0; j < ifes[sys]; j++)
@@ -676,7 +676,7 @@ int get_free_adapter(transponder *tp)
@@ -676,7 +677,7 @@ int get_free_adapter(transponder *tp)
adapter *ad = a[0];
@@ -20,7 +61,7 @@ index e034e3e..f7727b8 100644
{
fe = fe_map[fe - 1];
ad = a[fe];
@@ -878,7 +878,7 @@ int update_pids(int aid)
@@ -878,7 +879,7 @@ int update_pids(int aid)
if (dp)
dump_pids(aid);
dp = 0;
@@ -29,7 +70,7 @@ index e034e3e..f7727b8 100644
if ((ad->pids[i].fd = ad->set_pid(ad, ad->pids[i].pid)) < 0)
{
@@ -888,6 +888,8 @@ int update_pids(int aid)
@@ -888,6 +889,8 @@ int update_pids(int aid)
LOG0("Maximum pid filter reached, lowering the value to %d", opts.max_pids);
break;
}
@@ -38,7 +79,7 @@ index e034e3e..f7727b8 100644
ad->pids[i].flags = 1;
if (ad->pids[i].pid == 0)
ad->pat_processed = 0;
@@ -895,7 +897,6 @@ int update_pids(int aid)
@@ -895,7 +898,6 @@ int update_pids(int aid)
ad->pids[i].cc = 255;
ad->pids[i].cc_err = 0;
ad->pids[i].dec_err = 0;
@@ -46,7 +87,7 @@ index e034e3e..f7727b8 100644
}
if (ad->commit)
ad->commit(ad);
@@ -906,7 +907,9 @@ int update_pids(int aid)
@@ -906,7 +908,9 @@ int update_pids(int aid)
void post_tune(adapter *ad)
{
@@ -56,7 +97,7 @@ index e034e3e..f7727b8 100644
#ifndef DISABLE_PMT
SPid *p = find_pid(aid, 0);
SPid *p_all = find_pid(aid, 8192);
@@ -1066,7 +1069,7 @@ void mark_pids_deleted(int aid, int sid, char *pids) //pids==NULL -> delete all
@@ -1066,7 +1070,7 @@ void mark_pids_deleted(int aid, int sid, char *pids) //pids==NULL -> delete all
pids ? pids : "NULL");
if (pids)
{
@@ -65,7 +106,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
pid = map_int(arg[i], NULL);
@@ -1146,7 +1149,7 @@ int mark_pids_add(int sid, int aid, char *pids)
@@ -1146,7 +1150,7 @@ int mark_pids_add(int sid, int aid, char *pids)
LOG("adding pids to adapter %d, sid %d, pids=%s", aid, sid,
pids ? pids : "NULL");
@@ -74,7 +115,40 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
pid = map_intd(arg[i], NULL, -1);
@@ -1242,7 +1245,7 @@ int set_adapter_parameters(int aid, int sid, transponder *tp)
@@ -1165,11 +1169,11 @@ int compare_tunning_parameters(int aid, transponder *tp)
if (!ad)
return -1;
- LOGM("new parameters: f:%d, plp:%d, diseqc:%d, pol:%d, sr:%d, mtype:%d",
- tp->freq, tp->plp, tp->diseqc, tp->pol, tp->sr, tp->mtype);
- LOGM("old parameters: f:%d, plp:%d, diseqc:%d, pol:%d, sr:%d, mtype:%d",
- ad->tp.freq, ad->tp.plp, ad->tp.diseqc, ad->tp.pol, ad->tp.sr, ad->tp.mtype);
- if (tp->freq != ad->tp.freq || tp->plp != ad->tp.plp || tp->diseqc != ad->tp.diseqc || (tp->pol > 0 && tp->pol != ad->tp.pol) || (tp->sr > 1000 && tp->sr != ad->tp.sr) || (tp->mtype > 0 && tp->mtype != ad->tp.mtype))
+ LOGM("new parameters: f:%d, plp/isi:%d, diseqc:%d, pol:%d, sr:%d, mtype:%d",
+ tp->freq, tp->plp_isi, tp->diseqc, tp->pol, tp->sr, tp->mtype);
+ LOGM("old parameters: f:%d, plp/isi:%d, diseqc:%d, pol:%d, sr:%d, mtype:%d",
+ ad->tp.freq, ad->tp.plp_isi, ad->tp.diseqc, ad->tp.pol, ad->tp.sr, ad->tp.mtype);
+ if (tp->freq != ad->tp.freq || tp->plp_isi != ad->tp.plp_isi || tp->diseqc != ad->tp.diseqc || (tp->pol > 0 && tp->pol != ad->tp.pol) || (tp->sr > 1000 && tp->sr != ad->tp.sr) || (tp->mtype > 0 && tp->mtype != ad->tp.mtype))
return 1;
@@ -1196,11 +1200,11 @@ int set_adapter_parameters(int aid, int sid, transponder *tp)
{
mutex_unlock(&ad->mutex);
LOG(
- "secondary stream requested tune, not gonna happen ad: f:%d sr:%d pol:%d plp:%d src:%d mod %d -> \
- new: f:%d sr:%d pol:%d plp:%d src:%d mod %d",
- ad->tp.freq, ad->tp.sr, ad->tp.pol, ad->tp.plp,
+ "secondary stream requested tune, not gonna happen ad: f:%d sr:%d pol:%d plp/isi:%d src:%d mod %d -> \
+ new: f:%d sr:%d pol:%d plp/isi:%d src:%d mod %d",
+ ad->tp.freq, ad->tp.sr, ad->tp.pol, ad->tp.plp_isi,
ad->tp.diseqc, ad->tp.mtype, tp->freq, tp->sr, tp->pol,
- tp->plp, tp->diseqc, tp->mtype);
+ tp->plp_isi, tp->diseqc, tp->mtype);
return -1;
}
ad->do_tune = 1;
@@ -1242,7 +1246,7 @@ int set_adapter_parameters(int aid, int sid, transponder *tp)
{
char *arg[64];
int i, la;
@@ -83,7 +157,25 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
int pmt = map_int(arg[i], NULL);
@@ -1436,12 +1439,12 @@ void set_disable(int i, int v)
@@ -1346,7 +1350,7 @@ describe_adapter(int sid, int aid, char *dad, int ld)
ad ? ad->tp.fe : aid + 1, strength, status, snr,
(double)t->freq / 1000.0, t->bw / 1000000, get_delsys(t->sys),
get_tmode(t->tmode), get_modulation(t->mtype),
- get_gi(t->gi), get_fec(t->fec), t->plp, t->t2id, t->sm);
+ get_gi(t->gi), get_fec(t->fec), t->plp_isi, t->t2id, t->sm);
else
len =
snprintf(dad, ld,
@@ -1354,7 +1358,7 @@ describe_adapter(int sid, int aid, char *dad, int ld)
ad ? ad->tp.fe : aid + 1, strength, status, snr,
(double)t->freq / 1000, get_delsys(t->sys),
get_modulation(t->mtype), t->sr / 1000, t->c2tft, t->ds,
- t->plp, get_inversion(t->inversion));
+ t->plp_isi, get_inversion(t->inversion));
if (use_ad)
len += strlen(get_stream_pids(sid, dad + len, ld - len));
@@ -1436,12 +1440,12 @@ void set_disable(int i, int v)
void enable_adapters(char *o)
{
int i, la, st, end, j;
@@ -98,7 +190,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
sep = strchr(arg[i], '-');
@@ -1463,10 +1466,10 @@ void enable_adapters(char *o)
@@ -1463,10 +1467,10 @@ void enable_adapters(char *o)
void set_unicable_adapters(char *o, int type)
{
int i, la, a_id, slot, freq, pin, o13v;
@@ -111,11 +203,13 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
a_id = map_intd(arg[i], NULL, -1);
@@ -1504,10 +1507,10 @@ void set_unicable_adapters(char *o, int type)
@@ -1503,11 +1507,11 @@ void set_unicable_adapters(char *o, int type)
void set_diseqc_adapters(char *o)
{
int i, la, a_id, fast, committed_no, uncommitted_no;
- int i, la, a_id, fast, committed_no, uncommitted_no;
- char buf[100], *arg[20], *sep1, *sep2;
+ int i, la, a_id, fast, addr, committed_no, uncommitted_no;
+ char buf[1000], *arg[40], *sep1, *sep2;
adapter *ad;
SAFE_STRCPY(buf, o);
@@ -124,7 +218,69 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
if (arg[i] && arg[i][0] == '*')
@@ -1567,10 +1570,10 @@ void set_diseqc_adapters(char *o)
@@ -1531,8 +1535,28 @@ void set_diseqc_adapters(char *o)
if (!sep1 || !sep2)
continue;
- if ((fast = (sep1[1] == '*')) != 0)
- sep1++;
+
+ fast = 0;
+ addr = 0x10;
+ while (sep1[1] == '*' || sep1[1] == '@' || sep1[1] == '.')
+ {
+ if (sep1[1] == '*')
+ {
+ fast = 1;
+ sep1++;
+ }
+ else if (sep1[1] == '@')
+ {
+ addr = 0;
+ sep1++;
+ }
+ else if (sep1[1] == '.')
+ {
+ addr = 0x11;
+ sep1++;
+ }
+ }
+
committed_no = map_intd(sep1 + 1, NULL, -1);
uncommitted_no = map_intd(sep2 + 1, NULL, -1);
if (committed_no < 0 || uncommitted_no < 0)
@@ -1541,12 +1565,14 @@ void set_diseqc_adapters(char *o)
if (ad)
{
ad->diseqc_param.fast = fast;
+ ad->diseqc_param.addr = addr;
ad->diseqc_param.committed_no = committed_no;
ad->diseqc_param.uncommitted_no = uncommitted_no;
}
else
{
opts.diseqc_fast = fast;
+ opts.diseqc_addr = addr;
opts.diseqc_committed_no = committed_no;
opts.diseqc_uncommitted_no = uncommitted_no;
int j;
@@ -1554,23 +1580,24 @@ void set_diseqc_adapters(char *o)
if (a[j])
{
a[j]->diseqc_param.fast = fast;
+ a[j]->diseqc_param.addr = addr;
a[j]->diseqc_param.committed_no = committed_no;
a[j]->diseqc_param.uncommitted_no = uncommitted_no;
}
}
LOG(
- "Setting diseqc adapter %d fast %d committed_no %d uncommitted_no %d",
- a_id, fast, committed_no, uncommitted_no);
+ "Setting diseqc adapter %d fast %d addr 0x%02x committed_no %d uncommitted_no %d",
+ a_id, fast, addr, committed_no, uncommitted_no);
}
}
void set_diseqc_multi(char *o)
{
int i, la, a_id, position;
@@ -137,7 +293,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
if (arg[i] && arg[i][0] == '*')
@@ -1619,10 +1622,10 @@ void set_diseqc_multi(char *o)
@@ -1619,10 +1646,10 @@ void set_diseqc_multi(char *o)
void set_lnb_adapters(char *o)
{
int i, la, a_id, lnb_low, lnb_high, lnb_switch;
@@ -150,7 +306,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
if (arg[i] && arg[i][0] == '*')
@@ -1692,11 +1695,11 @@ void set_diseqc_timing(char *o)
@@ -1692,11 +1719,11 @@ void set_diseqc_timing(char *o)
int i, la, a_id;
int before_cmd, after_cmd, after_repeated_cmd;
int after_switch, after_burst, after_tone;
@@ -164,7 +320,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
if (arg[i] && arg[i][0] == '*')
@@ -1773,10 +1776,10 @@ void set_diseqc_timing(char *o)
@@ -1773,10 +1800,10 @@ void set_diseqc_timing(char *o)
void set_slave_adapters(char *o)
{
int i, j, la, a_id, a_id2, master = 0;
@@ -177,7 +333,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
a_id = map_intd(arg[i], NULL, -1);
@@ -1826,13 +1829,13 @@ void set_timeout_adapters(char *o)
@@ -1826,13 +1853,13 @@ void set_timeout_adapters(char *o)
{
int i, j, la, a_id, a_id2;
int timeout = opts.adapter_timeout / 1000;
@@ -193,7 +349,7 @@ index e034e3e..f7727b8 100644
if (arg[0] && (arg[0][0] == '*'))
{
opts.adapter_timeout = timeout * 1000;
@@ -1876,10 +1879,10 @@ extern char *fe_delsys[];
@@ -1876,10 +1903,10 @@ extern char *fe_delsys[];
void set_adapters_delsys(char *o)
{
int i, la, a_id, ds;
@@ -206,7 +362,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
a_id = map_intd(arg[i], NULL, -1);
@@ -1916,10 +1919,10 @@ void set_adapters_delsys(char *o)
@@ -1916,10 +1943,10 @@ void set_adapters_delsys(char *o)
void set_adapter_dmxsource(char *o)
{
int i, j, la, st, end, fd;
@@ -219,7 +375,7 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
sep = strchr(arg[i], '-');
@@ -1956,10 +1959,10 @@ void set_signal_multiplier(char *o)
@@ -1956,10 +1983,10 @@ void set_signal_multiplier(char *o)
{
int i, la, a_id;
float strength_multiplier, snr_multiplier;
@@ -232,8 +388,16 @@ index e034e3e..f7727b8 100644
for (i = 0; i < la; i++)
{
if (arg[i] && arg[i][0] == '*')
@@ -2193,6 +2220,7 @@ _symbols adapters_sym[] =
{"ad_sr", VAR_AARRAY_INT, a, 1. / 1000, MAX_ADAPTERS, offsetof(adapter, tp.sr)},
{"ad_bw", VAR_AARRAY_INT, a, 1. / 1000, MAX_ADAPTERS, offsetof(adapter, tp.bw)},
{"ad_diseqc", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, tp.diseqc)},
+ {"ad_stream", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, tp.plp_isi)},
{"ad_fe", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, fe)},
{"ad_master", VAR_AARRAY_UINT8, a, 1, MAX_ADAPTERS, offsetof(adapter, master_sid)},
{"ad_sidcount", VAR_AARRAY_UINT8, a, 1, MAX_ADAPTERS, offsetof(adapter, sid_cnt)},
diff --git a/src/axe.c b/src/axe.c
index 52e8dad..cbe1855 100644
index 52e8dad..466f699 100644
--- a/src/axe.c
+++ b/src/axe.c
@@ -48,7 +48,7 @@
@@ -245,7 +409,71 @@ index 52e8dad..cbe1855 100644
int send_jess(adapter *ad, int fd, int freq, int pos, int pol, int hiband, diseqc *d);
int send_unicable(adapter *ad, int fd, int freq, int pos, int pol, int hiband, diseqc *d);
int send_diseqc(adapter *ad, int fd, int pos, int pos_change, int pol, int hiband, diseqc *d);
@@ -210,7 +210,7 @@ static inline int extra_quattro(int input, int diseqc, int *equattro)
@@ -68,6 +68,8 @@ static inline void axe_fp_fd_write(const char *s)
ssize_t r;
axe_fp_fd_open();
+ if (axe_fp_fd < 0)
+ return;
len = strlen(b = s);
while (len > 0)
{
@@ -152,6 +154,54 @@ void axe_post_init(adapter *ad)
sockets_setread(ad->sock, axe_read);
}
+static void axe_stv0900_i2c_4(const char *name, int pa, int v)
+{
+ char buf[64];
+ const char *b;
+ int fd;
+ size_t len;
+ ssize_t r;
+
+ snprintf(buf, sizeof(buf), "/sys/devices/platform/i2c-stm.0/i2c-0/stv0900_%s%d", name, pa + 1);
+ fd = open(buf, O_WRONLY);
+ if (fd < 0)
+ return;
+ snprintf(buf, sizeof(buf), "%d", v);
+ len = strlen(b = buf);
+ while (len > 0)
+ {
+ r = write(fd, b, len);
+ if (r > 0)
+ {
+ len -= r;
+ b += r;
+ }
+ }
+ close(fd);
+}
+
+static void axe_pls_isi(adapter *ad, transponder *tp)
+{
+ static int isi[4] = { -2, -2, -2, -2 };
+ static int pls_code[4] = { -2, -2, -2, -2 };
+ int v;
+ LOGM("axe: isi %d pls %d mode %d\n", tp->plp_isi, tp->pls_code, tp->pls_mode);
+ if (tp->plp_isi != isi[ad->pa]) {
+ v = tp->plp_isi < 0 ? -1 : (tp->plp_isi & 0xff);
+ axe_stv0900_i2c_4("mis", ad->pa, v);
+ isi[ad->pa] = tp->plp_isi;
+ }
+ if (tp->pls_code != pls_code[ad->pa]) {
+ v = tp->pls_code < 0 ? 0 : (tp->pls_code & 0x3ffff);
+ if (tp->pls_mode == PLS_MODE_GOLD)
+ v |= 0x40000;
+ else if (tp->pls_mode == PLS_MODE_COMBO)
+ v |= 0x80000; /* really? */
+ axe_stv0900_i2c_4("pls", ad->pa, v);
+ pls_code[ad->pa] = tp->pls_code;
+ }
+}
+
void axe_wakeup(void *_ad, int fe_fd, int voltage)
{
int i, mask;
@@ -210,7 +260,7 @@ static inline int extra_quattro(int input, int diseqc, int *equattro)
return *equattro;
}
@@ -254,7 +482,7 @@ index 52e8dad..cbe1855 100644
{
int input2 = input < 4 ? input : -1;
adapter *ad = get_configured_adapter(input2);
@@ -229,11 +229,33 @@ adapter *use_adapter(int input)
@@ -229,8 +279,30 @@ adapter *use_adapter(int input)
return ad;
}
@@ -281,16 +509,12 @@ index 52e8dad..cbe1855 100644
+
+int axe_tune_check(adapter *ad, transponder *tp, diseqc *diseqc_param, int diseqc)
+{
+ int pol = tp->pol;
+ int pol = (tp->pol - 1) & 1;
+ int hiband = axe_get_hiband(tp, diseqc_param);
LOGM("axe: tune check for adapter %d, pol %d/%d, hiband %d/%d, diseqc %d/%d",
ad->id, ad->old_pol, pol, ad->old_hiband, hiband, ad->old_diseqc, diseqc);
- if (ad->old_pol != pol)
+ if (ad->old_pol != tp->pol)
return 0;
if (ad->old_hiband != hiband)
return 0;
@@ -249,33 +271,25 @@ int axe_setup_switch(adapter *ad)
if (ad->old_pol != pol)
@@ -249,33 +321,25 @@ int axe_setup_switch(adapter *ad)
{
int frontend_fd = ad->fe;
transponder *tp = &ad->tp;
@@ -336,7 +560,7 @@ index 52e8dad..cbe1855 100644
{
input = ad->id;
if (!opts.quattro || extra_quattro(input, diseqc, &equattro))
@@ -298,7 +312,7 @@ int axe_setup_switch(adapter *ad)
@@ -298,7 +362,7 @@ int axe_setup_switch(adapter *ad)
continue;
if ((ad2->axe_used & ~(1 << ad->id)) == 0)
continue;
@@ -345,7 +569,7 @@ index 52e8dad..cbe1855 100644
continue;
break;
}
@@ -327,7 +341,7 @@ int axe_setup_switch(adapter *ad)
@@ -327,7 +391,7 @@ int axe_setup_switch(adapter *ad)
}
diseqc = pos;
master = aid;
@@ -354,7 +578,7 @@ index 52e8dad..cbe1855 100644
if (adm == NULL)
{
LOG("axe_fe: unknown master adapter for input %d", input);
@@ -337,7 +351,7 @@ int axe_setup_switch(adapter *ad)
@@ -337,7 +401,7 @@ int axe_setup_switch(adapter *ad)
else
{
master = (ad->master_source >= 0) ? ad->master_source : ad->pa;
@@ -363,7 +587,7 @@ index 52e8dad..cbe1855 100644
if (adm == NULL)
{
LOG("axe_fe: unknown master adapter for input %d", input);
@@ -357,7 +371,7 @@ int axe_setup_switch(adapter *ad)
@@ -357,7 +421,7 @@ int axe_setup_switch(adapter *ad)
if (ad2->sid_cnt > 0)
break;
}
@@ -372,7 +596,7 @@ index 52e8dad..cbe1855 100644
{
LOG("unable to use slave adapter %d (master %d)", input, adm->pa);
return 0;
@@ -368,10 +382,13 @@ int axe_setup_switch(adapter *ad)
@@ -368,10 +432,13 @@ int axe_setup_switch(adapter *ad)
if (master >= 0)
{
input = master;
@@ -388,7 +612,7 @@ index 52e8dad..cbe1855 100644
adm->old_pol = pol;
adm->old_hiband = hiband;
adm->old_diseqc = diseqc;
@@ -381,6 +398,7 @@ int axe_setup_switch(adapter *ad)
@@ -381,6 +448,7 @@ int axe_setup_switch(adapter *ad)
}
else if (opts.quattro)
{
@@ -396,7 +620,7 @@ index 52e8dad..cbe1855 100644
if (opts.quattro_hiband == 1 && hiband)
{
LOG("axe_fe: hiband is not allowed for quattro config (adapter %d)", input);
@@ -392,17 +410,19 @@ int axe_setup_switch(adapter *ad)
@@ -392,17 +460,19 @@ int axe_setup_switch(adapter *ad)
return 0;
}
input = ((hiband ^ 1) << 1) | (pol ^ 1);
@@ -420,7 +644,7 @@ index 52e8dad..cbe1855 100644
adm->old_pol = pol;
adm->old_hiband = hiband;
adm->old_diseqc = 0;
@@ -414,9 +434,15 @@ int axe_setup_switch(adapter *ad)
@@ -414,9 +484,15 @@ int axe_setup_switch(adapter *ad)
else
{
aid = ad->id & 3;
@@ -438,7 +662,7 @@ index 52e8dad..cbe1855 100644
if (ad == NULL)
{
LOGM("axe setup: unable to find adapter %d", input);
@@ -429,17 +455,20 @@ int axe_setup_switch(adapter *ad)
@@ -429,17 +505,20 @@ int axe_setup_switch(adapter *ad)
ad->id, input, ad->fe, ad->fe2);
}
@@ -464,7 +688,7 @@ index 52e8dad..cbe1855 100644
{
LOG("FD %d (%d) is a slave adapter", frontend_fd);
}
@@ -447,7 +476,7 @@ int axe_setup_switch(adapter *ad)
@@ -447,7 +526,7 @@ int axe_setup_switch(adapter *ad)
{
if (ad->old_pol != pol || ad->old_hiband != hiband || ad->old_diseqc != diseqc)
send_diseqc(ad, frontend_fd, diseqc, ad->old_diseqc != diseqc, pol,
@@ -473,7 +697,53 @@ index 52e8dad..cbe1855 100644
else
LOGM("Skip sending diseqc commands since "
"the switch position doesn't need to be changed: "
@@ -669,8 +698,8 @@ fe_delivery_system_t axe_delsys(int aid, int fd, fe_delivery_system_t *sys)
@@ -545,7 +624,11 @@ int axe_tune(int aid, transponder *tp)
ADD_PROP(DTV_SYMBOL_RATE, tp->sr)
ADD_PROP(DTV_INNER_FEC, tp->fec)
#if DVBAPIVERSION >= 0x0502
- ADD_PROP(DTV_STREAM_ID, tp->plp)
+ if (tp->plp_isi >= 0)
+ ADD_PROP(DTV_STREAM_ID, tp->plp_isi & 0xFF)
+#endif
+#if DVBAPIVERSION >= 0x050b /* 5.11 */
+ ADD_PROP(DTV_SCRAMBLING_SEQUENCE_INDEX, tp->pls_code)
#endif
LOG("tuning to %d(%d) pol: %s (%d) sr:%d fec:%s delsys:%s mod:%s rolloff:%s pilot:%s, ts clear=%jd, ts pol=%jd",
@@ -569,7 +652,8 @@ int axe_tune(int aid, transponder *tp)
ADD_PROP(DTV_TRANSMISSION_MODE, tp->tmode)
ADD_PROP(DTV_HIERARCHY, HIERARCHY_AUTO)
#if DVBAPIVERSION >= 0x0502
- ADD_PROP(DTV_STREAM_ID, tp->plp & 0xFF)
+ if (tp->plp_isi >= 0)
+ ADD_PROP(DTV_STREAM_ID, tp->plp_isi & 0xFF)
#endif
LOG(
@@ -588,7 +672,12 @@ int axe_tune(int aid, transponder *tp)
freq = freq * 1000;
ADD_PROP(DTV_SYMBOL_RATE, tp->sr)
#if DVBAPIVERSION >= 0x0502
- ADD_PROP(DTV_STREAM_ID, ((tp->ds & 0xFF) << 8) | (tp->plp & 0xFF))
+ if (tp->plp_isi >= 0) {
+ int v = tp->plp_isi & 0xFF;
+ if (tp->ds >= 0)
+ v |= (tp->ds & 0xFF) << 8;
+ ADD_PROP(DTV_STREAM_ID, v);
+ }
#endif
// valid for DD DVB-C2 devices
@@ -617,6 +706,8 @@ int axe_tune(int aid, transponder *tp)
break;
}
+ axe_pls_isi(ad, tp);
+
if ((ioctl(fd_frontend, FE_SET_PROPERTY, &p)) == -1)
if (ioctl(fd_frontend, FE_SET_PROPERTY, &p) == -1)
{
@@ -669,8 +760,8 @@ fe_delivery_system_t axe_delsys(int aid, int fd, fe_delivery_system_t *sys)
void axe_get_signal(adapter *ad)
{
@@ -484,7 +754,7 @@ index 52e8dad..cbe1855 100644
get_signal(ad, &status, &ber, &strength, &snr);
strength = strength * 240 / 24000;
@@ -819,9 +848,11 @@ void free_axe_input(adapter *ad)
@@ -819,9 +910,11 @@ void free_axe_input(adapter *ad)
for (aid = 0; aid < 4; aid++)
{
@@ -498,7 +768,7 @@ index 52e8dad..cbe1855 100644
}
}
@@ -829,11 +860,11 @@ void free_axe_input(adapter *ad)
@@ -829,11 +922,11 @@ void free_axe_input(adapter *ad)
void set_link_adapters(char *o)
{
int i, la, a_id, b_id;
@@ -512,7 +782,7 @@ index 52e8dad..cbe1855 100644
for (i = 0; i < la; i++)
{
a_id = map_intd(arg[i], NULL, -1);
@@ -857,11 +888,11 @@ void set_link_adapters(char *o)
@@ -857,11 +950,11 @@ void set_link_adapters(char *o)
void set_absolute_src(char *o)
{
int i, la, src, inp, pos;
@@ -527,10 +797,40 @@ index 52e8dad..cbe1855 100644
{
inps = strchr(arg[i], ':');
diff --git a/src/dvb.c b/src/dvb.c
index 5184c4d..f3b6ac3 100644
index 5184c4d..fd2b6cf 100644
--- a/src/dvb.c
+++ b/src/dvb.c
@@ -192,7 +192,7 @@ int detect_dvb_parameters(char *s, transponder *tp)
@@ -120,6 +120,10 @@ char *fe_pol[] =
{"none", "v", "h", "r", "l",
NULL};
+char *fe_pls_mode[] =
+ {"root", "gold", "combo",
+ NULL};
+
#define make_func(a) \
char *get_##a(int i) \
{ \
@@ -142,6 +146,7 @@ make_func(gi);
make_func(specinv);
make_func(inversion);
make_func(pol);
+make_func(pls_mode);
#define INVALID_URL(a) \
{ \
@@ -177,7 +182,9 @@ int detect_dvb_parameters(char *s, transponder *tp)
tp->diseqc = -1;
tp->c2tft = -1;
tp->ds = -1;
- tp->plp = -1;
+ tp->plp_isi = -1;
+ tp->pls_mode = -1;
+ tp->pls_code = -1;
tp->pids = tp->apids = tp->dpids = tp->x_pmt = NULL;
@@ -192,7 +199,7 @@ int detect_dvb_parameters(char *s, transponder *tp)
init_dvb_parameters(tp);
LOG("detect_dvb_parameters (S)-> %s", s);
@@ -539,11 +839,203 @@ index 5184c4d..f3b6ac3 100644
for (i = 0; i < la; i++)
{
@@ -228,8 +235,13 @@ int detect_dvb_parameters(char *s, transponder *tp)
tp->c2tft = map_int(arg[i] + 6, NULL);
if (strncmp("ds=", arg[i], 3) == 0)
tp->ds = map_int(arg[i] + 3, NULL);
- if (strncmp("plp=", arg[i], 4) == 0)
- tp->plp = map_int(arg[i] + 4, NULL);
+ if (strncmp("plp=", arg[i], 4) == 0 ||
+ strncmp("isi=", arg[i], 4) == 0)
+ tp->plp_isi = map_int(arg[i] + 4, NULL);
+ if (strncmp("plsm=", arg[i], 5) == 0)
+ tp->pls_mode = map_int(arg[i] + 5, fe_pls_mode);
+ if (strncmp("plsc=", arg[i], 5) == 0)
+ tp->pls_code = map_int(arg[i] + 5, NULL);
if (strncmp("x_pmt=", arg[i], 6) == 0)
tp->x_pmt = arg[i] + 6;
@@ -275,6 +287,10 @@ void init_dvb_parameters(transponder *tp)
tp->mtype = QAM_AUTO;
tp->plts = PILOT_AUTO;
tp->fec = FEC_AUTO;
+ tp->ds = TP_VALUE_NOT_ENABLED;
+ tp->plp_isi = TP_VALUE_NOT_ENABLED;
+ tp->pls_mode = TP_VALUE_NOT_ENABLED;
+ tp->pls_code = 1;
}
void copy_dvb_parameters(transponder *s, transponder *d)
@@ -323,8 +339,12 @@ void copy_dvb_parameters(transponder *s, transponder *d)
d->c2tft = s->c2tft;
if (s->ds != -1)
d->ds = s->ds;
- if (s->plp != -1)
- d->plp = s->plp;
+ if (s->plp_isi != -1)
+ d->plp_isi = s->plp_isi;
+ if (s->pls_mode != -1)
+ d->pls_mode = s->pls_mode;
+ if (s->pls_code != -1)
+ d->pls_code = s->pls_code;
d->x_pmt = s->x_pmt;
d->apids = s->apids;
@@ -506,7 +526,9 @@ int send_diseqc(adapter *ad, int fd, int pos, int pos_change, int pol, int hiban
posu = pos / 4;
}
+ cmd.msg[1] = d->addr;
cmd.msg[3] = 0xf0 | (((posc << 2) & 0x0c) | (hiband ? 1 : 0) | (pol ? 2 : 0));
+ uncmd.msg[1] = d->addr;
uncmd.msg[3] = 0xf0 | (posu & 0x0f);
LOGM("send_diseqc fd %d, pos = %d (c %d u %d), pol = %d, hiband = %d",
@@ -554,12 +576,13 @@ int send_unicable(adapter *ad, int fd, int freq, int pos, int pol, int hiband, d
{
struct dvb_diseqc_master_cmd cmd =
{
- {0xe0, 0x11, 0x5a, 0x00, 0x00}, 5};
+ {0xe0, 0x10, 0x5a, 0x00, 0x00}, 5};
int t;
int committed_no = d->committed_no;
t = (freq + d->ufreq + 2) / 4 - 350;
+ cmd.msg[1] = d->addr;
cmd.msg[3] = ((t & 0x0300) >> 8) | (d->uslot << 5) | (pos ? 0x10 : 0) | (hiband ? 4 : 0) | (pol ? 8 : 0);
cmd.msg[4] = t & 0xff;
@@ -825,7 +848,11 @@ int dvb_tune(int aid, transponder *tp)
ADD_PROP(DTV_PILOT, tp->plts)
ADD_PROP(DTV_ROLLOFF, tp->ro)
#if DVBAPIVERSION >= 0x0502
- ADD_PROP(DTV_STREAM_ID, tp->plp)
+ if (tp->plp_isi >= 0)
+ ADD_PROP(DTV_STREAM_ID, tp->plp_isi)
+#endif
+#if DVBAPIVERSION >= 0x050b /* 5.11 */
+ ADD_PROP(DTV_SCRAMBLING_SEQUENCE_INDEX, tp->pls_code)
#endif
#ifdef USE_DVBAPI3
@@ -856,7 +883,8 @@ int dvb_tune(int aid, transponder *tp)
ADD_PROP(DTV_TRANSMISSION_MODE, tp->tmode)
ADD_PROP(DTV_HIERARCHY, HIERARCHY_AUTO)
#if DVBAPIVERSION >= 0x0502
- ADD_PROP(DTV_STREAM_ID, tp->plp & 0xFF)
+ if (tp->plp_isi >= 0)
+ ADD_PROP(DTV_STREAM_ID, tp->plp_isi & 0xFF)
#endif
// old DVBAPI version 3
@@ -894,7 +922,12 @@ int dvb_tune(int aid, transponder *tp)
freq = freq * 1000;
ADD_PROP(DTV_SYMBOL_RATE, tp->sr)
#if DVBAPIVERSION >= 0x0502
- ADD_PROP(DTV_STREAM_ID, ((tp->ds & 0xFF) << 8) | (tp->plp & 0xFF))
+ if (tp->plp_isi >= 0) {
+ int v = tp->plp_isi & 0xFF;
+ if (tp->ds >= 0)
+ v |= (tp->ds & 0xFF) << 8;
+ ADD_PROP(DTV_STREAM_ID, v);
+ }
#endif
// valid for DD DVB-C2 devices
diff --git a/src/dvb.h b/src/dvb.h
index 9830487..b9fd223 100644
--- a/src/dvb.h
+++ b/src/dvb.h
@@ -143,6 +143,12 @@ typedef enum fe_modulation {
} fe_modulation_t;
#endif
+typedef enum fe_pls_mode {
+ PLS_MODE_ROOT,
+ PLS_MODE_GOLD,
+ PLS_MODE_COMBO,
+} fe_pls_mode_t;
+
#if DVBAPIVERSION < 0x0505
#define DTV_ENUM_DELSYS 44
#define SYS_DVBC_ANNEX_A SYS_DVBC_ANNEX_AC
@@ -182,6 +188,8 @@ typedef enum fe_modulation {
#define MIN_FRQ_DVBS 950000
#define MAX_FRQ_DVBS 2150000
+#define TP_VALUE_NOT_ENABLED (-255)
+
typedef struct diseqc
{
#define SWITCH_UNICABLE 1
@@ -189,12 +197,14 @@ typedef struct diseqc
#define SWITCH_SLAVE 3
int switch_type;
/* parameters */
- int uslot; // unicable/jess slot
- int ufreq; // unicable/jess frequency
- int pin;
- int only13v; // unicable - use 13V voltage only
- int fast; // don't send diseqc without position change
- int committed_no, uncommitted_no; // diseqc info
+ int uslot; // unicable/jess slot
+ int ufreq; // unicable/jess frequency
+ int pin; // unicable pin code
+ int only13v; // unicable - use 13V voltage only
+ int fast; // don't send diseqc without position change
+ int addr; // diseqc address (second byte in the sequence)
+ int committed_no; // committed switch number
+ int uncommitted_no; // uncommitted switch number
/* timing */
int before_cmd;
int after_cmd;
@@ -232,10 +242,11 @@ typedef struct struct_transponder
diseqc diseqc_param;
- // DVB-C2
- int c2tft;
- int ds;
- int plp;
+ int c2tft; // DVB-C2
+ int ds; // DVB-C2 (data slice)
+ int plp_isi; // DVB-T2/DVB-S2
+ int pls_mode; // DVB-S2
+ int pls_code; // DVB-S2
char *apids, *pids, *dpids, *x_pmt;
} transponder;
@@ -279,6 +290,7 @@ char *get_gi(int i);
char *get_specinv(int i);
char *get_pol(int i);
char *get_inversion(int i);
+char *get_pls_mode(int i);
extern char *fe_delsys[];
extern char *fe_fec[];
diff --git a/src/minisatip.c b/src/minisatip.c
index 0cd9b0b..a35ef19 100644
index 0cd9b0b..884f14c 100644
--- a/src/minisatip.c
+++ b/src/minisatip.c
@@ -552,7 +552,7 @@ void set_options(int argc, char *argv[])
@@ -286,6 +286,8 @@ Help\n\
* eg: -d 0:1-0 (which is the default for each adapter).\n\
- note: * as adapter means apply to all adapters\n\
- note: * before committed number enables fast-switch (only voltage/tone)\n\
+ - note: @ before committed number sets 'Any Device' diseqc address (0x00)\n\
+ - note: . before committed number sets 'LNB' diseqc address (0x11)\n\
\n\
* -q --diseqc-timing ADAPTER1:BEFORE_CMD1-AFTER_CMD1-AFTER_REPEATED_CMD1-AFTER_SWITCH1-AFTER_BURST1-AFTER_TONE1[,...]\n\
\t* All timing values are in ms, default adapter values are: 15-54-15-15-15-0\n\
@@ -513,6 +515,7 @@ void set_options(int argc, char *argv[])
opts.document_root = "html";
opts.xml_path = DESC_XML;
opts.th_priority = -1;
+ opts.diseqc_addr = 0x10;
opts.diseqc_before_cmd = 15;
opts.diseqc_after_cmd = 54;
opts.diseqc_after_repeated_cmd = 15;
@@ -552,7 +555,7 @@ void set_options(int argc, char *argv[])
#endif
#ifdef AXE
opts.no_threads = 1;
@@ -552,7 +1044,7 @@ index 0cd9b0b..a35ef19 100644
#define AXE_OPTS "7:QW:8:A:"
#else
#define AXE_OPTS ""
@@ -614,7 +614,7 @@ void set_options(int argc, char *argv[])
@@ -614,7 +617,7 @@ void set_options(int argc, char *argv[])
int i;
memset(buf, 0, sizeof(buf));
strncpy(buf, optarg, sizeof(buf) - 1);
@@ -561,7 +1053,7 @@ index 0cd9b0b..a35ef19 100644
for (i = 0; i < la; i++)
{
int level = map_intd(arg[i], loglevels, -1);
@@ -1046,7 +1046,7 @@ int read_rtsp(sockets *s)
@@ -1046,7 +1049,7 @@ int read_rtsp(sockets *s)
return 0;
}
@@ -570,7 +1062,7 @@ index 0cd9b0b..a35ef19 100644
cseq = 0;
if (la < 2)
LOG_AND_RETURN(0,
@@ -1311,7 +1311,7 @@ int read_http(sockets *s)
@@ -1311,7 +1314,7 @@ int read_http(sockets *s)
LOG("read HTTP from %d sid: %d: ", s->sock, s->sid);
LOGM("%s", s->buf);
@@ -580,7 +1072,7 @@ index 0cd9b0b..a35ef19 100644
if (strncmp(arg[0], "GET", 3) && strncmp(arg[0], "POST", 4) && !is_head)
REPLY_AND_RETURN(503);
diff --git a/src/minisatip.h b/src/minisatip.h
index 6512250..59067f0 100644
index 6512250..520de73 100644
--- a/src/minisatip.h
+++ b/src/minisatip.h
@@ -9,7 +9,7 @@
@@ -588,12 +1080,20 @@ index 6512250..59067f0 100644
#define VERSION_BUILD "16"
#define CC(a, b, c) #a b #c
-#define VERSION CC(0.7., VERSION_BUILD, )
+#define VERSION CC(0.7., VERSION_BUILD, -axe210)
+#define VERSION CC(0.7., VERSION_BUILD, -axe214)
void set_options(int argc, char *argv[]);
@@ -94,6 +94,7 @@ struct struct_opts
char no_threads;
int th_priority;
int diseqc_fast;
+ int diseqc_addr;
int diseqc_committed_no;
int diseqc_uncommitted_no;
int diseqc_before_cmd;
diff --git a/src/satipc.c b/src/satipc.c
index 24c82ff..38df122 100644
index 24c82ff..e748048 100644
--- a/src/satipc.c
+++ b/src/satipc.c
@@ -176,7 +176,7 @@ int satipc_reply(sockets *s)
@@ -605,7 +1105,43 @@ index 24c82ff..38df122 100644
rc = map_int(arg[1], NULL);
if (sip->option_no_session && sip->last_cmd == RTSP_OPTIONS && !sess && sip->session[0])
@@ -1288,7 +1288,7 @@ void find_satip_adapter(adapter **a)
@@ -807,6 +807,12 @@ void get_s2_url(adapter *ad, char *url)
FILL("&fec=%s", tp->fec, FEC_AUTO, get_fec(tp->fec));
FILL("&ro=%s", ro, ROLLOFF_AUTO, get_rolloff(ro));
FILL("&plts=%s", plts, PILOT_AUTO, get_pilot(plts));
+ if (tp->plp_isi >= 0)
+ FILL("&isi=%d", tp->plp_isi, 0, tp->plp_isi);
+ if (tp->pls_mode >= 0)
+ FILL("&plsm=%s", tp->pls_mode, -1, get_pls_mode(tp->pls_mode));
+ if (tp->pls_code >= 0)
+ FILL("&plsc=%d", tp->pls_code, -1, tp->pls_code);
url[len] = 0;
return;
}
@@ -831,7 +837,8 @@ void get_c2_url(adapter *ad, char *url)
FILL("&specinv=%d", tp->inversion, INVERSION_AUTO, tp->inversion);
FILL("&t2id=%d", tp->t2id, 0, tp->t2id);
FILL("&sm=%d", tp->sm, 0, tp->sm);
- FILL("&plp=%d", tp->plp, 0, tp->plp);
+ if (tp->plp_isi >= 0)
+ FILL("&plp=%d", tp->plp_isi, 0, tp->plp_isi);
url[len] = 0;
return;
}
@@ -854,8 +861,10 @@ void get_t2_url(adapter *ad, char *url)
FILL("&tmode=%s", tp->tmode, TRANSMISSION_MODE_AUTO, get_tmode(tp->tmode));
FILL("&specinv=%d", tp->inversion, INVERSION_AUTO, tp->inversion);
FILL("&c2tft=%d", tp->c2tft, 0, tp->c2tft);
- FILL("&ds=%d", tp->ds, 0, tp->ds);
- FILL("&plp=%d", tp->plp, 0, tp->plp);
+ if (tp->ds >= 0)
+ FILL("&ds=%d", tp->ds, 0, tp->ds);
+ if (tp->plp_isi >= 0)
+ FILL("&plp=%d", tp->plp_isi, 0, tp->plp_isi);
url[len] = 0;
return;
}
@@ -1288,7 +1297,7 @@ void find_satip_adapter(adapter **a)
return;
char satip_servers[strlen(opts.satip_servers) + 10];
strcpy(satip_servers, opts.satip_servers);
@@ -614,7 +1150,7 @@ index 24c82ff..38df122 100644
for (i = 0; i < la; i++)
{
@@ -1420,7 +1420,7 @@ void satip_getxml_data(char *data, int len, void *opaque, Shttp_client *h)
@@ -1420,7 +1429,7 @@ void satip_getxml_data(char *data, int len, void *opaque, Shttp_client *h)
eos = strchr(sep, '<');
if (eos)
*eos = 0;
@@ -623,7 +1159,7 @@ index 24c82ff..38df122 100644
for (i = 0; i < la; i++)
{
int ds = map_intd(arg[i], satip_delsys, -1);
@@ -1474,7 +1474,7 @@ int satip_getxml(void *x)
@@ -1474,7 +1483,7 @@ int satip_getxml(void *x)
memset(satip_xml, 0, sizeof(satip_xml));
memset(sxd, 0, sizeof(sxd));
strncpy(satip_xml, opts.satip_xml, sizeof(satip_xml) - 1);

View File

@@ -1,6 +1,6 @@
--- Makefile.orig 2017-05-03 16:45:40.962475569 +0200
+++ Makefile 2017-05-03 16:48:52.644079190 +0200
@@ -618,7 +618,7 @@
--- Makefile.orig 2018-09-25 11:01:33.853198226 +0200
+++ Makefile 2018-09-25 11:07:57.416371544 +0200
@@ -587,7 +587,7 @@
*) quiet="";; \
esac; \
$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
@@ -9,7 +9,7 @@
$(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build
# Build static library
@@ -728,17 +728,19 @@
@@ -697,6 +697,8 @@
############################################################################
# Importlib
@@ -18,30 +18,35 @@
Programs/_freeze_importlib.o: Programs/_freeze_importlib.c Makefile
Programs/_freeze_importlib: Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN)
$(LINKCC) $(PY_LDFLAGS) -o $@ Programs/_freeze_importlib.o $(LIBRARY_OBJS_OMIT_FROZEN) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
Python/importlib_external.h: # $(srcdir)/Lib/importlib/_bootstrap_external.py Programs/_freeze_importlib
@@ -706,12 +708,12 @@
regen-importlib: Programs/_freeze_importlib
# Regenerate Python/importlib_external.h
# from Lib/importlib/_bootstrap_external.py using _freeze_importlib
- ./Programs/_freeze_importlib \
+ $(FREEZE_IMPORTLIB) \
$(srcdir)/Lib/importlib/_bootstrap_external.py Python/importlib_external.h
Python/importlib.h: # $(srcdir)/Lib/importlib/_bootstrap.py Programs/_freeze_importlib
$(srcdir)/Lib/importlib/_bootstrap_external.py \
$(srcdir)/Python/importlib_external.h
# Regenerate Python/importlib.h from Lib/importlib/_bootstrap.py
# using _freeze_importlib
- ./Programs/_freeze_importlib \
+ $(FREEZE_IMPORTLIB) \
$(srcdir)/Lib/importlib/_bootstrap.py Python/importlib.h
$(srcdir)/Lib/importlib/_bootstrap.py \
$(srcdir)/Python/importlib.h
@@ -778,11 +780,8 @@
@@ -805,9 +807,6 @@
$(GRAMMAR_C): # $(GRAMMAR_H)
touch $(GRAMMAR_C)
$(IO_OBJS): $(IO_H)
-$(PGEN): $(PGENOBJS)
- $(CC) $(OPT) $(PY_LDFLAGS) $(PGENOBJS) $(LIBS) -o $(PGEN)
-
Parser/grammar.o: $(srcdir)/Parser/grammar.c \
$(srcdir)/Include/token.h \
$(srcdir)/Include/grammar.h
@@ -1620,7 +1619,7 @@
.PHONY: regen-grammar
-regen-grammar: $(PGEN)
+regen-grammar:
# Regenerate Include/graminit.h and Python/graminit.c
# from Grammar/Grammar using pgen
@$(MKDIR_P) Include
@@ -1625,7 +1624,7 @@
rm -rf $(COVERAGE_REPORT)
clobber: clean profile-removal

View File

@@ -14,6 +14,8 @@
#define STV6120_1 (0xc0 >> 1)
#define STV6120_2 (0xc6 >> 1)
#define STV0900_1 (0xd0 >> 1)
#define STV0900_2 (0xd2 >> 1)
extern int (*i2c_transfer_mangle)(struct i2c_adapter *adap, struct i2c_msg *msg, int num);
int i2c_transfer2(struct i2c_adapter *adap, struct i2c_msg *msg, int num);
@@ -22,17 +24,34 @@ static struct i2c_adapter *i2c_adapter0;
static int i2c_mangle_enable = 1;
static int i2c_mangle_debug = 0;
static int stv6120_gain = 8;
static int stv0900_mis[4] = { -1, -1, -1, -1 };
static int stv0900_pls[4] = { -1, -1, -1, -1 };
static void i2c_transfer_axe_dump(struct i2c_msg *msgs, int num)
{
struct i2c_msg *m;
int ret;
u8 *b;
for (ret = 0; ret < num; ret++) {
m = msgs + ret;
b = m->buf;
printk("i2c master_xfer[%d] %c, addr=0x%02x, "
"len=%d%s, flags=0x%x\n", ret, (msgs[ret].flags & I2C_M_RD)
? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
(msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "",
msgs[ret].flags);
"len=%d%s, flags=0x%04x, "
"data[%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x]\n",
ret,
(m->flags & I2C_M_RD) ? 'R' : 'W',
m->addr, m->len,
(m->flags & I2C_M_RECV_LEN) ? "+" : "",
m->flags,
m->len > 0 ? b[0] : 0,
m->len > 1 ? b[1] : 0,
m->len > 2 ? b[2] : 0,
m->len > 3 ? b[3] : 0,
m->len > 4 ? b[4] : 0,
m->len > 5 ? b[5] : 0,
m->len > 6 ? b[6] : 0,
m->len > 7 ? b[7] : 0);
}
}
@@ -48,7 +67,66 @@ static void mangle(u8 *dst, struct i2c_msg *m, int i, int val, int shift, int ma
m->buf = dst;
}
static void i2c_transfer_axe_mangle(struct i2c_msg *msgs, int num)
#define REG_SET3(b, b1, b2, b3) \
b[0] = b1, b[1] = b2, b[2] = b3
static void demod_set_pls_and_mis(struct i2c_adapter *adap, struct i2c_msg *src, int p)
{
struct i2c_msg m[6];
u8 buf[6][3];
int num, r, mis, idx = p ? 1 : 0;
u32 pls;
u8 iaddr = p ? 0xf3 : 0xf5;
switch (src->addr) {
case STV0900_1: idx += 0; break;
case STV0900_2: idx += 2; break;
default: return;
}
mis = stv0900_mis[idx];
if (mis >= 0 && mis <= 255) {
/* PDELCTRL1 - enable filter */
REG_SET3(buf[0], iaddr, 0x50, 0x20);
/* ISIENTRY */
REG_SET3(buf[1], iaddr, 0x5e, mis);
/* ISIBITENA */
REG_SET3(buf[2], iaddr, 0x5f, 0xff);
/* set PLS code and mode (upper three bits) */
pls = stv0900_pls[idx];
REG_SET3(buf[3], iaddr-1, 0xae, pls); /* PLROOT0 */
REG_SET3(buf[4], iaddr-1, 0xad, pls >> 8); /* PLROOT1 */
REG_SET3(buf[5], iaddr-1, 0xac, (pls >> 16) & 0x0f); /* PLROOT3 */
num = 6;
if (i2c_mangle_debug & 4)
printk("i2c idx=%d: pls=%d mis=%d\n", idx, pls, mis);
} else {
/* SWRST */
REG_SET3(buf[0], iaddr, 0x72, 0xd1);
/* PDELCTRL1 - disable filter */
REG_SET3(buf[1], iaddr, 0x50, 0x00);
/* set PLS code to 1 and mode to ROOT */
REG_SET3(buf[2], iaddr-1, 0xae, 1); /* PLROOT0 */
REG_SET3(buf[3], iaddr-1, 0xad, 0); /* PLROOT1 */
REG_SET3(buf[4], iaddr-1, 0xac, 0); /* PLROOT3 */
num = 5;
if (i2c_mangle_debug & 4)
printk("i2c idx=%d: disable mis filter\n", idx);
}
for (r = 0; r < num; r++) {
m[r] = *src;
m[r].len = 3;
m[r].buf = buf[r];
}
if (i2c_mangle_debug & 1)
i2c_transfer_axe_dump(m, num);
r = i2c_transfer2(adap, m, num);
if (r < 0)
printk("i2c mangle demod pls and mis error! (%d)\n", r);
}
static void i2c_transfer_axe_mangle(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
static u8 mbuf[4][32];
struct i2c_msg *m;
@@ -58,20 +136,27 @@ static void i2c_transfer_axe_mangle(struct i2c_msg *msgs, int num)
m = msgs + ret;
if (m->len < 1 || (m->flags & I2C_M_RD) != 0)
continue;
if (m->addr == STV6120_1 || m->addr == STV6120_2)
if (m->addr == STV6120_1 || m->addr == STV6120_2) {
for (r = m->buf[0], i = 1; i < m->len; i++, r++)
if (r == 0x01 || r == 0x0b)
mangle(mbuf[ret], m, i, stv6120_gain, 0, 0x0f);
} else if (m->addr == STV0900_1 || m->addr == STV0900_2) {
/* inject pls/mis settings before TSCFGH path merger reset */
if (m->flags == 0 && m->len == 3 &&
(m->buf[0] == 0xf3 || m->buf[0] == 0xf5) &&
m->buf[1] == 0x72 && m->buf[2] == 0xd1)
demod_set_pls_and_mis(adap, m, m->buf[0] == 0xf3);
}
}
}
static int i2c_transfer_axe(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
if (adap == i2c_adapter0) {
if (i2c_mangle_enable)
i2c_transfer_axe_mangle(adap, msgs, num);
if (i2c_mangle_debug & 1)
i2c_transfer_axe_dump(msgs, num);
if (i2c_mangle_enable)
i2c_transfer_axe_mangle(msgs, num);
}
return i2c_transfer2(adap, msgs, num);
}
@@ -140,6 +225,166 @@ static DEVICE_ATTR(stv6120_gain, 0644,
stv6120_gain_show,
stv6120_gain_store);
static ssize_t stv0900_mis1_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_mis[0]);
}
static ssize_t stv0900_mis1_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_mis[0] = val;
return count;
}
static DEVICE_ATTR(stv0900_mis1, 0644,
stv0900_mis1_show,
stv0900_mis1_store);
static ssize_t stv0900_mis2_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_mis[1]);
}
static ssize_t stv0900_mis2_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_mis[1] = val;
return count;
}
static DEVICE_ATTR(stv0900_mis2, 0644,
stv0900_mis2_show,
stv0900_mis2_store);
static ssize_t stv0900_mis3_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_mis[2]);
}
static ssize_t stv0900_mis3_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_mis[2] = val;
return count;
}
static DEVICE_ATTR(stv0900_mis3, 0644,
stv0900_mis3_show,
stv0900_mis3_store);
static ssize_t stv0900_mis4_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_mis[3]);
}
static ssize_t stv0900_mis4_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_mis[3] = val;
return count;
}
static DEVICE_ATTR(stv0900_mis4, 0644,
stv0900_mis4_show,
stv0900_mis4_store);
static ssize_t stv0900_pls1_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_pls[0]);
}
static ssize_t stv0900_pls1_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_pls[0] = val;
return count;
}
static DEVICE_ATTR(stv0900_pls1, 0644,
stv0900_pls1_show,
stv0900_pls1_store);
static ssize_t stv0900_pls2_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_pls[1]);
}
static ssize_t stv0900_pls2_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_pls[1] = val;
return count;
}
static DEVICE_ATTR(stv0900_pls2, 0644,
stv0900_pls2_show,
stv0900_pls2_store);
static ssize_t stv0900_pls3_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_pls[2]);
}
static ssize_t stv0900_pls3_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_pls[2] = val;
return count;
}
static DEVICE_ATTR(stv0900_pls3, 0644,
stv0900_pls3_show,
stv0900_pls3_store);
static ssize_t stv0900_pls4_show
(struct device *dev, struct device_attribute *attr, char *page)
{
return sprintf(page, "%i\n", stv0900_pls[3]);
}
static ssize_t stv0900_pls4_store
(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
int val = 0;
if (sscanf(buf, "%i", &val) != 1)
return -EINVAL;
stv0900_pls[3] = val;
return count;
}
static DEVICE_ATTR(stv0900_pls4, 0644,
stv0900_pls4_show,
stv0900_pls4_store);
static void sysfs_create_entries(void)
{
struct kobject *kobj = &i2c_adapter0->dev.kobj;
@@ -147,6 +392,14 @@ static void sysfs_create_entries(void)
sysfs_create_file(kobj, &dev_attr_i2c_mangle_enable.attr);
sysfs_create_file(kobj, &dev_attr_i2c_mangle_debug.attr);
sysfs_create_file(kobj, &dev_attr_stv6120_gain.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_mis1.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_mis2.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_mis3.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_mis4.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_pls1.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_pls2.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_pls3.attr);
sysfs_create_file(kobj, &dev_attr_stv0900_pls4.attr);
}
static void sysfs_remove_entries(void)
@@ -156,6 +409,14 @@ static void sysfs_remove_entries(void)
sysfs_remove_file(kobj, &dev_attr_i2c_mangle_enable.attr);
sysfs_remove_file(kobj, &dev_attr_i2c_mangle_debug.attr);
sysfs_remove_file(kobj, &dev_attr_stv6120_gain.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_mis1.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_mis2.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_mis3.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_mis4.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_pls1.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_pls2.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_pls3.attr);
sysfs_remove_file(kobj, &dev_attr_stv0900_pls4.attr);
}
/*

View File

@@ -2,6 +2,7 @@
#
# Tiny SAT>IP client which activates multicast streaming.
#
# Use command line parameters of
# Create /etc/sysconfig/multicast file with syntax:
#
# <mport>:<satip-params>
@@ -9,12 +10,12 @@
# You can modify this file when the program is active and
# reload the configuration using the SIGHUP signal.
#
# Example:
# Configuration Example:
#
# # Channel 1 on multicast port 5554, using first tuner (fe=1)
# 5554:fe=1&src=1&freq=12525&sr=27500&\
# msys=dvbs&mtype=qpsk&pol=v&fec=34&\
# pids=0,1,16,17,18,52,57,100,104,165,299,1029,3002,3003
# # Channel 1 on multicast port 5554, using first orbital position
# 5554:src=1&freq=11347&pol=v&ro=0.35&msys=dvbs2&\
# mtype=8psk&plts=on&sr=22000&fec=23&\
# pids=0,17,18,6600,6610,6620,6630
#
# The SAT>IP parameters should match the SAT>IP specification:
# http://www.satip.info/resources
@@ -23,27 +24,100 @@
# option -r <ipv4_mcast> or --remote-rtp <ipv4_mcast>. By default,
# this address is 239.255.255.250.
#
# Command-line example:
#
# ./multicast-rtp \
# -s 192.168.1.100:554 -d 239.0.0.1 -p 5554 \
# -u "src=1&freq=11347&pol=v&ro=0.35&msys=dvbs2&mtype=8psk&plts=on&sr=22000&fec=23&pids=0,17,18,6600,6610,6620,6630"
#
# Note: The SAT>IP server needs to support "target" spoofing
# and multicast address as "unicast" (minisatip project does it)
#
import os
import signal
import functools
import asyncio
import syslog
import argparse,sys
import signal
VERSION='0.1'
VERSION='0.2'
SYSLOG=False
SERVER='127.0.0.1:554'
CONFIG='/etc/sysconfig/multicast'
SYSLOG=True
if not os.path.exists('/etc/init.d/axe-settings'):
SERVER='gssbox1:554'
CONFIG='multicast'
SYSLOG=False
CONFIG=''
REQUEST=''
TARGET_ADDR=''
TARGET_PORT=0
USE_CONFIG=True
QUIET=False
#
# Command line parameters
#
parser = argparse.ArgumentParser(description='Request multicast streaming from a SAT>IP server.')
parser.add_argument('-q', '--quiet', dest='quiet',
action='store_true',
help='quiet display option')
parser.add_argument('-l', '--syslog', dest='syslog',
action='store_true',
help='enable System LOG')
parser.add_argument('-s', '--server', dest='server',
required=True,
help='server to connect')
parser.add_argument('-d', '--destination', dest='addr',
default='',
help='target address (Note: Only if server accept it!)')
parser.add_argument('-p', '--port', dest='port', type=int,
default=10000,
help='target port (default: 10000)')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-u', '--uri', dest='uri',
default='',
help='URI to request')
group.add_argument('-c', '--config', dest='config',
default='/etc/sysconfig/multicast',
help='config file with static multicast streams (default: /etc/sysconfig/multicast)')
args = parser.parse_args()
SYSLOG = args.syslog
if args.port > 0 and args.port < 65536 :
TARGET_PORT = args.port
else :
parser.print_help()
sys.exit()
if len(args.server) > 0 :
SERVER = args.server
else :
parser.print_help()
sys.exit()
if len(args.uri) > 0 :
REQUEST = args.uri
elif len(args.config) > 0 :
CONFIG = args.config
else :
parser.print_help()
sys.exit()
TARGET_ADDR = args.addr
QUIET = args.quiet
if len(REQUEST) > 0 :
USE_CONFIG = False
#
#
#
def log(msg):
if QUIET :
return
if SYSLOG:
syslog.syslog(msg)
else:
@@ -80,14 +154,19 @@ class RTSP_Protocol:
s = 'rtsp://%s:%d/?%s' % (peer[0], peer[1], self.params)
log('%d (open): %s' % (self.mport, s))
msg = 'SETUP ' + s + ' RTSP/1.0\r\n'
msg += 'Transport: RTP/AVP;multicast;port=%d-%d\r\n' % (self.mport, self.mport + 1)
if len(REQUEST) > 0 :
msg += 'Transport: RTP/AVP;unicast;destination=%s;client_port=%d-%d\r\n' % (TARGET_ADDR, self.mport, self.mport + 1)
else :
msg += 'Transport: RTP/AVP;multicast;port=%d-%d\r\n' % (self.mport, self.mport + 1)
msg += 'CSeq: 1\r\n\r\n'
log(' -----> : %s' % msg)
transport.write(msg.encode())
self.action = 'PLAY'
def data_received(self, data):
if not self.transport:
return
log(' <----- : %s' % data)
lines = data.decode("utf-8").splitlines()
if lines[0] != 'RTSP/1.0 200 OK':
return self.retry()
@@ -131,6 +210,10 @@ class RTSP_Protocol:
self.cseq = 2
elif self.action == 'OPTIONS' and self.cseq == 2:
log('%d (play): OK' % self.mport)
elif self.action == 'TEARDOWN':
log('%d (close): OK' % self.mport)
self.retry()
return
def options(self):
if not self.transport:
@@ -144,6 +227,19 @@ class RTSP_Protocol:
self.transport.write(msg.encode())
self.client.loop.call_at(loop.time() + self.timeout/2, self.options)
def teardown(self):
self.action = 'TEARDOWN'
if not self.transport:
return
peer = self.transport._sock.getpeername()
log('%d (teardown): Session %s, streamID %d' % (self.mport, self.session, self.streamID))
self.cseq += 1
msg = 'TEARDOWN rtsp://%s:%d/stream=%d RTSP/1.0\r\n' % (peer[0], peer[1], self.streamID)
msg += 'Session: %s\r\n' % self.session
msg += 'CSeq: %d\r\n\r\n' % self.cseq
self.transport.write(msg.encode())
self.client.loop.call_at(loop.time() + 1, self.retry)
def eof_received(self):
self.connection_lost(None)
@@ -159,7 +255,7 @@ class RTSP_Protocol:
def fatal(self):
if self.transport:
self.transport.close()
self.teardown()
self.client.protocol = None
self.client.fatal()
@@ -195,7 +291,7 @@ class RTSP_Client:
log("Remove multicast client: %s" % self.params)
self.dead = True
if self.protocol:
self.protocol.fatal()
self.protocol.teardown()
self.clients.remove_client(self)
#
@@ -207,8 +303,12 @@ class RTSP_Clients:
def __init__(self, loop):
self.loop = loop
self.clients = []
self.parse_config_file()
hupfcn = lambda: self.parse_config_file()
if USE_CONFIG :
self.parse_config_file()
hupfcn = lambda: self.parse_config_file()
else :
self.parse_request()
hupfcn = lambda: self.parse_request()
loop.add_signal_handler(signal.SIGHUP,
functools.partial(hupfcn))
@@ -224,6 +324,23 @@ class RTSP_Clients:
return
self.clients.append(RTSP_Client(self, params))
async def close_all(self):
for c in self.clients:
c.fatal()
def parse_request(self):
# mark clients
for c in self.clients:
c.deleteme = True
# parse command line
l = str(TARGET_PORT) + ':' + REQUEST
#print("parse_request: " + l)
self.add_client(l)
# remove marked clients
for c in self.clients:
if c.deleteme:
self.remove_client(c)
def parse_config_file(self):
# mark clients
for c in self.clients:
@@ -251,17 +368,43 @@ class RTSP_Clients:
self.remove_client(c)
#
# configuration file
# configuration
#
if SYSLOG:
syslog.openlog('multicast-rtp', 0, syslog.LOG_LOCAL7)
silent = QUIET
if QUIET :
QUIET = False
log('Version %s' % VERSION)
log('SERVER: %s' % SERVER)
log('CONFIG: %s' % CONFIG)
log('TARGET: %s:%d' % (TARGET_ADDR, TARGET_PORT))
log('REQUEST: %s' % REQUEST)
log('------------')
if silent :
log(' Start.')
QUIET = True
loop = asyncio.get_event_loop()
loop.add_signal_handler(signal.SIGTERM, signal.getsignal(signal.SIGINT))
clients = RTSP_Clients(loop)
try:
loop.run_forever()
except (KeyboardInterrupt, SystemExit) as e:
## Send TEARDOWN before exit!
log(' Closing.')
loop.run_until_complete(clients.close_all())
loop.run_until_complete(asyncio.sleep(1.0))
except:
print('*******')
finally:
QUIET = False
log(' Stop.')
loop.close()
if SYSLOG:
syslog.closelog()
sys.exit(0)