diff --git a/Makefile b/Makefile index 8bb26e5e..1c3f28fe 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ KMODULES = drivers/usb/serial/cp210x.ko \ drivers/usb/serial/oti6858.ko MINISATIP_COMMIT=54df9348e7bd7e6075f54f1b93ec4ad36429abe0 +MINISATIP5_COMMIT=6569cb0c1cc790aec9c254fc99de38be5de6d549 BUSYBOX=busybox-1.24.1 @@ -106,6 +107,7 @@ CPIO_SRCS += busybox CPIO_SRCS += dropbear CPIO_SRCS += ethtool CPIO_SRCS += minisatip +CPIO_SRCS += minisatip5 CPIO_SRCS += oscam CPIO_SRCS += tools/axehelper CPIO_SRCS += nfsutils @@ -134,6 +136,14 @@ fs.cpio: $(CPIO_SRCS) -e "apps/minisatip/icons/lr.png:usr/share/minisatip/icons/lr.png" \ -e "apps/minisatip/icons/sm.jpg:usr/share/minisatip/icons/sm.jpg" \ -e "apps/minisatip/icons/sm.png:usr/share/minisatip/icons/sm.png" \ + -e "apps/minisatip5/minisatip:sbin/minisatip5" \ + -e "apps/minisatip5/html/lr.jpg:usr/share/minisatip/html/lr.jpg" \ + -e "apps/minisatip5/html/lr.png:usr/share/minisatip/html/lr.png" \ + -e "apps/minisatip5/html/sm.jpg:usr/share/minisatip/html/sm.jpg" \ + -e "apps/minisatip5/html/sm.png:usr/share/minisatip/html/sm.png" \ + -e "apps/minisatip5/html/dLAN.xml:usr/share/minisatip/html/dLAN.xml" \ + -e "apps/minisatip5/html/satip.xml:usr/share/minisatip/html/satip.xml" \ + -e "apps/minisatip5/html/status.html:usr/share/minisatip/html/status.html" \ -e "apps/$(NANO)/src/nano:usr/bin/nano" \ -e "apps/mtd-utils/nandwrite:usr/sbin/nandwrite2" \ -e "apps/oscam-svn/Distribution/oscam-1.20-unstable_svn$(OSCAM_REV)-sh4-linux:sbin/oscamd" @@ -276,6 +286,30 @@ minisatip: apps/minisatip/minisatip minisatip-clean: rm -rf apps/minisatip +# +# minisatip5 +# + +apps/minisatip5/axe.h: + $(call GIT_CLONE,https://github.com/catalinii/minisatip.git,minisatip5,$(MINISATIP5_COMMIT)) + cd apps/minisatip5; patch -p1 < ../../patches/minisatip5-axe.patch + +apps/minisatip5/minisatip: apps/minisatip5/axe.h + make -C apps/minisatip5 \ + DVBCSA= \ + DVBCA= \ + CC=$(TOOLCHAIN)/bin/sh4-linux-gcc \ + CFLAGS="-O2 -DAXE=1 -DSYS_DVBT2=16 \ + -DDISABLE_DVBCSA -DDISABLE_DVBCA -DDISABLE_TABLES -DDISABLE_NETCVCLIENT \ + -I$(CURDIR)/kernel/include" + +.PHONY: minisatip5 +minisatip5: apps/minisatip5/minisatip + +.PHONY: minisatip5-clean +minisatip5-clean: + rm -rf apps/minisatip5 + # # busybox # diff --git a/fs-add/etc/config.default b/fs-add/etc/config.default index 6255b642..933727ba 100644 --- a/fs-add/etc/config.default +++ b/fs-add/etc/config.default @@ -2,7 +2,7 @@ # SATIP AXE firmware configuration # -CFGVER="10" +CFGVER="11" HOSTNAME="satip-axe" KMODULES="drivers/usb/serial/cp210x.ko drivers/usb/serial/pl2303.ko drivers/usb/serial/ftdi_sio.ko" @@ -57,6 +57,12 @@ DROPBEAR="yes" MINISATIP="yes" MINISATIP_OPTS="" +# +# minisatip 0.5 +# +#MINISATIP5="yes" +#MINISATIP5_OPTS="" + # # inetd (httpd,ftpd) # diff --git a/fs-add/etc/init.d/satip b/fs-add/etc/init.d/satip index 1bdaa951..74dfce48 100755 --- a/fs-add/etc/init.d/satip +++ b/fs-add/etc/init.d/satip @@ -2,7 +2,7 @@ test -r /etc/sysconfig/config && . /etc/sysconfig/config -if test "$MINISATIP" != "yes"; then +if test "$MINISATIP" != "yes" -a "$MINISATIP5" != "yes"; then exit 0 fi @@ -23,8 +23,15 @@ while test ! -f /tmp/nosatip; do nc -l 127.0.0.1:999 -e /etc/init.d/satip-network done . /etc/sysconfig/config - nice -5 minisatip -f -g $MINISATIP_OPTS - logger -p local0.notice "minisatip exited $?, restarting" + if test "$MINISATIP" = "yes"; then + nice -5 minisatip -f -g $MINISATIP_OPTS + logger -p local0.notice "minisatip exited $?, restarting" + elif test "$MINISATIP5" = "yes"; then + nice -5 minisatip5 -f -g $MINISATIP5_OPTS + logger -p local0.notice "minisatip5 exited $?, restarting" + else + exit 0 + fi if test -f /tmp/nosatip; then sleep 87323123 fi diff --git a/patches/minisatip5-axe.patch b/patches/minisatip5-axe.patch new file mode 100644 index 00000000..bcf680ab --- /dev/null +++ b/patches/minisatip5-axe.patch @@ -0,0 +1,1005 @@ +diff --git a/adapter.c b/adapter.c +index 033490a..885188a 100644 +--- a/adapter.c ++++ b/adapter.c +@@ -1162,6 +1162,33 @@ void set_slave_adapters(char *o) + + } + } ++ ++void set_link_adapters(char *o) ++{ ++ int i, la, a_id, b_id; ++ char buf[100], *arg[20], *sep1; ++ ++ strncpy(buf, o, sizeof(buf)-1); ++ buf[sizeof(buf)-1] = '\0'; ++ la = split(arg, buf, sizeof(arg), ','); ++ for (i=0; i= MAX_ADAPTERS) ++ continue; ++ sep1 = strchr(arg[i], ':'); ++ if (!sep1) ++ continue; ++ b_id=map_intd(sep1 + 1, NULL, -1); ++ if (b_id < 0 || b_id >= MAX_ADAPTERS) ++ continue;; ++ if (a_id == b_id || a[a_id]->slave) ++ continue; ++ a[a_id]->slave = a_id + 1; ++ LOG("Setting adapter %d as master for adapter %d", a_id, b_id); ++ } ++} ++ + extern char *fe_delsys[]; + void set_adapters_delsys(char *o) + { +diff --git a/adapter.h b/adapter.h +index e693479..aaa59a0 100644 +--- a/adapter.h ++++ b/adapter.h +@@ -6,7 +6,11 @@ + typedef struct ca_device ca_device_t; + + #define MAX_ADAPTERS 16 ++#ifdef AXE ++#define DVR_BUFFER 14*7*DVB_FRAME ++#else + #define DVR_BUFFER 30*1024*188 ++#endif + #ifdef NO_BACKTRACE + #define MAX_STREAMS_PER_PID 8 + #else +@@ -88,6 +92,7 @@ typedef struct struct_adapter + int ufreq; // unicable/jess frequency + int pin; + int only13v; // unicable - use 13V voltage only ++ int slave; + int committed_no, uncommitted_no; // diseqc info + int id; + int pat_processed, transponder_id, pat_ver; +@@ -129,6 +134,7 @@ void enable_adapters(char *o); + void set_unicable_adapters(char *o, int type); + void set_diseqc_adapters(char *o); + void set_slave_adapters(char *o); ++void set_link_adapters(char *o); + void reset_pids_type(int aid, int clear_pat); + void reset_ecm_type_for_key(int aid, int key); + int delsys_match(adapter *ad, int del_sys); +diff --git a/axe.h b/axe.h +new file mode 100644 +index 0000000..d8b06bc +--- /dev/null ++++ b/axe.h +@@ -0,0 +1,149 @@ ++#ifndef __AXE_H ++#define __AXE_H ++ ++#include ++#include ++ ++typedef struct fe_frontend_status fe_frontend_status_t; ++ ++struct fe_frontend_status { ++ __u32 val0; ++ __u32 val1; ++ __u32 val2; ++ __u32 modulation; ++ __u32 val4; ++ __u32 frequency; ++ __u32 val6; ++ __u32 val7; ++ __u32 symbol_rate; ++ __u32 val9; ++ __u32 fec; ++ __u32 rolloff; ++ __u32 val12; ++ __u32 val13; ++} __attribute__ ((packed)); ++ ++#define FE_FRONTEND_STANDBY _IOW('o', 91, __u32) ++#define FE_FRONTEND_RESET _IO('o', 93) ++#define FE_FRONTEND_STATUS _IOR('o', 96, fe_frontend_status_t) ++#define FE_FRONTEND_INPUT _IOW('o', 97, __u8) ++ ++static inline int axe_fe_standby(int fd, __u32 stdby) ++{ ++ return ioctl(fd, FE_FRONTEND_STANDBY, &stdby); ++} ++ ++static inline int axe_fe_reset(int fd) ++{ ++ return ioctl(fd, FE_FRONTEND_RESET, 0x54); ++} ++ ++static inline int axe_fe_input(int fd, __u8 in) ++{ ++ return ioctl(fd, FE_FRONTEND_INPUT, &in); ++} ++ ++typedef struct dmx_stream_params_s { ++ __u32 srcIp; ++ __u16 srcPort; ++ __u16 dstPort; ++ __u32 dstIp; ++ __u32 ts; /* timestamp */ ++ __u32 ssrc; /* synchronization source */ ++ __u16 seq; ++} dmx_stream_params_t; ++ ++typedef struct rtp_state { ++ __u32 ssrc; ++ __u32 ts; ++ __u32 spc; ++ __u32 soc; ++ __u16 seq; ++} rtp_state_t; ++ ++#define DMXTS_ADD_PID _IOW('o', 1, __u16) ++#define DMXTS_REMOVE_PID _IOW('o', 2, __u16) ++ ++#define DMXTS_TRANSFER_START _IO('o', 5) ++#define DMXTS_TRANSFER_START_RTP _IOW('o', 6, dmx_stream_params_t) ++#define DMXTS_TRANSFER_STOP _IO('o', 7) ++#define DMXTS_RTP_SETUP_SSRC _IOW('o', 8, __u32) ++#define DMXTS_TRANSFER_PAUSE _IO('o', 9) ++#define DMXTS_TRANSFER_RESUME _IO('o', 10) ++ ++#define DMXTS_GET_RTP_STREAM_STATE _IOR('o', 11, rtp_state_t) ++ ++static inline int axe_dmxts_add_pid(int fd, __u16 pid) ++{ ++ return ioctl(fd, DMXTS_ADD_PID, &pid); ++} ++ ++static inline int axe_dmxts_remove_pid(int fd, __u16 pid) ++{ ++ return ioctl(fd, DMXTS_REMOVE_PID, &pid); ++} ++ ++static inline int axe_dmxts_start(int fd) ++{ ++ return ioctl(fd, DMXTS_TRANSFER_START); ++} ++ ++#ifdef AXE_MAIN ++ ++int axe_fp_fd = -1; ++ ++static inline axe_fp_fd_open(void) ++{ ++ if (axe_fp_fd < 0) ++ axe_fp_fd = open("/dev/axe/fp-0", O_WRONLY); ++} ++ ++static inline axe_fp_fd_write(const char *s) ++{ ++ const char *b; ++ size_t len; ++ ssize_t r; ++ ++ axe_fp_fd_open(); ++ len = strlen(b = s); ++ while (len > 0) { ++ r = write(axe_fp_fd, b, len); ++ if (r > 0) { ++ len -= r; ++ b += r; ++ } ++ } ++} ++ ++void axe_set_tuner_led(int tuner, int on) ++{ ++ static int state = 0; ++ char buf[16]; ++ if (((state >> tuner) & 1) != !!on) { ++ sprintf(buf, "T%d_LED %d\n", tuner, on ? 1 : 0); ++ axe_fp_fd_write(buf); ++ if (on) ++ state |= 1 << tuner; ++ else ++ state &= ~(1 << tuner); ++ } ++} ++ ++void axe_set_network_led(int on) ++{ ++ static int state = -1; ++ if (state != on) { ++ axe_fp_fd_write(on ? "NET_LED 1\n" : "NET_LED 0\n"); ++ state = on; ++ } ++} ++ ++#else ++ ++void axe_set_tuner_led(int tuner, int on); ++void axe_set_network_led(int on); ++void axe_status(char *buf, size_t buflen); ++ ++#endif ++ ++#endif +diff --git a/dvb.c b/dvb.c +index 259b93d..57948bc 100644 +--- a/dvb.c ++++ b/dvb.c +@@ -42,6 +42,11 @@ + #include "ca.h" + #include "utils.h" + ++#ifdef AXE ++#define AXE_MAIN 1 ++#include "axe.h" ++#endif ++ + char *fe_pilot[] = + { "on", "off", " ", //auto + NULL }; +@@ -330,13 +335,25 @@ int dvb_open_device(adapter *ad) + char buf[100]; + LOG("trying to open [%d] adapter %d and frontend %d", ad->id, ad->pa, + ad->fn); ++#ifdef AXE ++ sprintf(buf, "/dev/axe/frontend-%d", ad->pa); ++#else + sprintf(buf, "/dev/dvb/adapter%d/frontend%d", ad->pa, ad->fn); ++#endif + ad->fe = open(buf, O_RDWR | O_NONBLOCK); ++#ifdef AXE ++ sprintf(buf, "/dev/axe/demuxts-%d", ad->pa); ++#else + sprintf(buf, "/dev/dvb/adapter%d/dvr%d", ad->pa, ad->fn); ++#endif + ad->dvr = open(buf, O_RDONLY | O_NONBLOCK); + if (ad->fe < 0 || ad->dvr < 0) + { ++#ifdef AXE ++ sprintf(buf, "/dev/axe/frontend-%d", ad->pa); ++#else + sprintf(buf, "/dev/dvb/adapter%d/frontend%d", ad->pa, ad->fn); ++#endif + LOGL(0, "Could not open %s in RW mode (fe: %d, dvr: %d)", buf, ad->fe, + ad->dvr); + if (ad->fe >= 0) +@@ -349,10 +366,12 @@ int dvb_open_device(adapter *ad) + ad->type = ADAPTER_DVB; + + LOG("opened DVB adapter %d fe:%d dvr:%d", ad->id, ad->fe, ad->dvr); ++#ifndef AXE + if (ioctl(ad->dvr, DMX_SET_BUFFER_SIZE, opts.dvr_buffer) < 0) + LOG("couldn't set DVR buffer size error %d: %s", errno, strerror(errno)) + else + LOG("Done setting DVR buffer to %d bytes", opts.dvr_buffer); ++#endif + return 0; + } + +@@ -550,15 +569,107 @@ int setup_switch(int frontend_fd, transponder *tp) + hiband = 1; + } + ++#ifdef AXE ++ adapter *ad, *ad2, *adm; ++ int input = 0, aid; ++ ++ if (tp->switch_type != SWITCH_UNICABLE && tp->switch_type != SWITCH_JESS) { ++ for (aid = 0; aid < 4; aid++) { ++ ad = get_adapter(aid); ++ LOGL(3, "axe adapter %i fe fd %d", aid, ad->fe); ++ if (ad && ad->fe == frontend_fd) ++ break; ++ } ++ if (aid >= 4) { ++ LOG("axe_fe: unknown adapter for fd %d", frontend_fd); ++ return 0; ++ } ++ input = aid; ++ if (ad && !opts.quattro) { ++ adm = get_adapter(ad->slave ? ad->slave - 1 : ad->pa); ++ if (adm == NULL) { ++ LOG("axe_fe: unknown master adapter %d", input); ++ return 0; ++ } ++ if (adm->tp.old_pol >= 0) { ++ for (aid = 0; aid < 4; aid++) { ++ ad2 = get_adapter(aid); ++ if (!ad2 || ad == ad2) continue; ++ if (ad2->slave && ad2->slave - 1 != adm->pa) continue; ++ if (!ad2->slave && ad2 != adm) continue; ++ if (ad2->sid_cnt > 0) break; ++ } ++ if (adm != ad && aid < 4 && ++ (adm->tp.old_pol != pol || ++ adm->tp.old_hiband != hiband || ++ adm->tp.old_diseqc != diseqc)) ++ return 0; ++ } ++ if (ad->slave) { ++ input = ad->slave - 1; ++ adm = get_adapter(input); ++ if (adm == NULL) { ++ LOG("axe_fe: unknown master adapter %d", input); ++ return 0; ++ } ++ if(adm->tp.old_pol != pol || ++ adm->tp.old_hiband != hiband || ++ adm->tp.old_diseqc != diseqc) { ++ send_diseqc(adm->fe, diseqc, pol, hiband, ++ tp->committed_no, tp->uncommitted_no); ++ adm->tp.old_pol = pol; ++ adm->tp.old_hiband = hiband; ++ adm->tp.old_diseqc = diseqc; ++ } ++ goto axe; ++ } ++ } ++ if (ad && opts.quattro) { ++ input = ((hiband ^ 1) << 1) | (pol ^ 1); ++ adm = get_adapter(input); ++ if (adm == NULL) { ++ LOG("axe_fe: unknown master adapter %d", input); ++ return 0; ++ } ++ if(adm->tp.old_pol != pol || adm->tp.old_hiband != hiband) { ++ send_diseqc(adm->fe, 0, pol, hiband, ++ tp->committed_no, tp->uncommitted_no); ++ adm->tp.old_pol = pol; ++ adm->tp.old_hiband = hiband; ++ adm->tp.old_diseqc = diseqc = 0; ++ } ++ } ++ } else { ++ input = opts.axe_unicinp; ++ ad = get_adapter(input); ++ if (ad == NULL) { ++ LOGL(3, "axe setup: unable to find adapter %d", input); ++ return 0; ++ } ++ } ++#endif ++ + if (tp->switch_type == SWITCH_UNICABLE) + { ++#ifdef AXE ++ if (ad) ++ freq = send_unicable(ad->fe, freq / 1000, diseqc, pol, hiband, ++ tp->uslot, tp->ufreq, tp->pin, tp->only13v); ++#else + freq = send_unicable(frontend_fd, freq / 1000, diseqc, pol, hiband, + tp->uslot, tp->ufreq, tp->pin, tp->only13v); ++#endif + } + else if (tp->switch_type == SWITCH_JESS) + { ++#ifdef AXE ++ if (ad) ++ freq = send_jess(ad->fe, freq / 1000, diseqc, pol, hiband, ++ tp->uslot, tp->ufreq, tp->pin, tp->only13v); ++#else + freq = send_jess(frontend_fd, freq / 1000, diseqc, pol, hiband, + tp->uslot, tp->ufreq, tp->pin, tp->only13v); ++#endif + } + else if (tp->switch_type == SWITCH_SLAVE) + { +@@ -576,6 +687,17 @@ int setup_switch(int frontend_fd, transponder *tp) + pol, hiband, diseqc); + } + ++#ifdef AXE ++axe: ++ LOGL(3, "axe_fe: reset for fd %d adapter %d input %d", frontend_fd, ad ? ad->pa : -1, input); ++ if (axe_fe_reset(frontend_fd) < 0) ++ LOG("axe_fe: RESET failed for fd %d: %s", frontend_fd, strerror(errno)); ++ if (axe_fe_input(frontend_fd, input)) ++ LOG("axe_fe: INPUT failed for fd %d input %d: %s", frontend_fd, input, strerror(errno)); ++ if (opts.quattro) ++ return freq; ++#endif ++ + tp->old_pol = pol; + tp->old_hiband = hiband; + tp->old_diseqc = diseqc; +@@ -611,6 +733,14 @@ int dvb_tune(int aid, transponder * tp) + memset(p_cmd, 0, sizeof(p_cmd)); + bclear = getTick(); + ++#ifdef AXE ++ ssize_t drv; ++ char buf[1316]; ++ axe_set_tuner_led(aid + 1, 1); ++ axe_fe_reset(ad->fe); ++ do { drv = read(ad->dvr, buf, sizeof(buf)); } while (drv > 0); ++#endif ++ + if ((ioctl(fd_frontend, FE_SET_PROPERTY, &cmdseq_clear)) == -1) + { + LOG("FE_SET_PROPERTY DTV_CLEAR failed for fd %d: %s", fd_frontend, +@@ -630,8 +760,10 @@ int dvb_tune(int aid, transponder * tp) + + ADD_PROP(DTV_SYMBOL_RATE, tp->sr) + ADD_PROP(DTV_INNER_FEC, tp->fec) ++#ifndef AXE + ADD_PROP(DTV_PILOT, tp->plts) + ADD_PROP(DTV_ROLLOFF, tp->ro) ++#endif + #if DVBAPIVERSION >= 0x0502 + ADD_PROP(DTV_STREAM_ID, tp->plp) + #endif +@@ -640,7 +772,12 @@ int dvb_tune(int aid, transponder * tp) + "tuning to %d(%d) pol: %s (%d) sr:%d fec:%s delsys:%s mod:%s rolloff:%s pilot:%s, ts clear=%d, ts pol=%d", + tp->freq, freq, get_pol(tp->pol), tp->pol, tp->sr, + fe_fec[tp->fec], fe_delsys[tp->sys], fe_modulation[tp->mtype], +- fe_rolloff[tp->ro], fe_pilot[tp->plts], bclear, bpol) ++#ifdef AXE ++ "auto", "auto", ++#else ++ fe_rolloff[tp->ro], fe_pilot[tp->plts], ++#endif ++ bclear, bpol) + break; + + case SYS_DVBT: +@@ -741,29 +878,46 @@ int dvb_tune(int aid, transponder * tp) + if (ioctl(fd_frontend, FE_SET_PROPERTY, &p) == -1) + { + LOG("dvb_tune: set property failed %d %s", errno, strerror(errno)); ++#ifdef AXE ++ axe_set_tuner_led(aid + 1, 0); ++#endif + return -404; + } + ++#ifdef AXE ++ axe_dmxts_start(ad->dvr); ++#endif ++ + return 0; + } + + int dvb_set_pid(adapter *a, uint16_t i_pid) + { ++#ifdef AXE ++ if (i_pid > 8192 || a == NULL) ++ LOG_AND_RETURN(-1, "pid %d > 8192 for ADAPTER %d", i_pid, a->id); ++ if (axe_dmxts_add_pid(a->dvr, i_pid) < 0) ++ { ++ LOG("failed setting filter on PID %d for ADAPTER %d (%s)", i_pid, a->id, strerror (errno)); ++ return -1; ++ } ++ LOG("setting filter on PID %d for ADAPTER %d", i_pid, a->id); ++ return ((a->id + 1) << 16) | i_pid; ++#else + char buf[100]; + int fd; + int hw, ad; + ++ sprintf(buf, "/dev/dvb/adapter%d/demux%d", hw, ad); ++ + hw = a->pa; + ad = a->fn; + if (i_pid > 8192) +- LOG_AND_RETURN(-1, "pid %d > 8192 for /dev/dvb/adapter%d/demux%d", +- i_pid, hw, ad); ++ LOG_AND_RETURN(-1, "pid %d > 8192 for %s", i_pid, buf); + +- sprintf(buf, "/dev/dvb/adapter%d/demux%d", hw, ad); + if ((fd = open(buf, O_RDWR | O_NONBLOCK)) < 0) + { +- LOG("Could not open demux device /dev/dvb/adapter%d/demux%d: %s ", hw, +- ad, strerror (errno)); ++ LOG("Could not open demux device %s: %s ", buf, strerror (errno)); + return -1; + } + +@@ -789,10 +943,22 @@ int dvb_set_pid(adapter *a, uint16_t i_pid) + LOG("setting filter on PID %d for fd %d", i_pid, fd); + + return fd; ++#endif + } + + int dvb_del_filters(int fd, int pid) + { ++#ifdef AXE ++ adapter *a = get_adapter((fd >> 16) - 1); ++ if (a == NULL) ++ return 0; /* closed */ ++ if ((fd & 0xffff) != pid) ++ LOG_AND_RETURN(0, "AXE PID remove on an invalid handle %d, pid %d", fd, pid); ++ if (axe_dmxts_remove_pid(a->dvr, pid) < 0) ++ LOG("AXE PID remove failed on PID %d ADAPTER %d: %s", pid, a->pa, strerror (errno)) ++ else ++ LOG("clearing filters on PID %d ADAPTER %d", pid, a->pa); ++#else + if (fd < 0) + LOG_AND_RETURN(0, "DMX_STOP on an invalid handle %d, pid %d", fd, pid); + if (ioctl(fd, DMX_STOP, NULL) < 0) +@@ -801,10 +967,20 @@ int dvb_del_filters(int fd, int pid) + LOG("clearing filter on PID %d FD %d", pid, fd); + close(fd); + return 0; ++#endif + } + + fe_delivery_system_t dvb_delsys(int aid, int fd, fe_delivery_system_t *sys) + { ++#ifdef AXE ++ int i; ++ LOG ("Delivery System DVB-S/DVB-S2 (AXE)"); ++ for(i = 0 ; i < 10 ; i ++) ++ sys[i] = 0; ++ sys[0] = SYS_DVBS; ++ sys[1] = SYS_DVBS2; ++ return SYS_DVBS2; ++#else + int i, res, rv = 0; + struct dvb_frontend_info fe_info; + +@@ -893,6 +1069,7 @@ fe_delivery_system_t dvb_delsys(int aid, int fd, fe_delivery_system_t *sys) + fe_delsys[sys[i]], sys[i]); + + return (fe_delivery_system_t) rv; ++#endif + + } + +@@ -1005,6 +1182,7 @@ void dvb_get_signal(adapter *ad) + ad->max_strength = (ad->strength > 0) ? ad->strength : 1; + if (ad->max_snr <= ad->snr) + ad->max_snr = (ad->snr > 0) ? ad->snr : 1; ++#ifndef AXE + if (ad->snr > 4096) + new_gs = 0; + if (new_gs) +@@ -1017,6 +1195,14 @@ void dvb_get_signal(adapter *ad) + ad->strength = ad->strength >> 8; + ad->snr = ad->snr >> 8; + } ++#else ++ ad->strength = ad->strength * 240 / 24000; ++ if (ad->strength > 240) ++ ad->strength = 240; ++ ad->snr = ad->snr * 15 / 54000; ++ if (ad->snr > 15) ++ ad->snr = 15; ++#endif + } + + void dvb_commit(adapter *a) +@@ -1024,6 +1210,33 @@ void dvb_commit(adapter *a) + return; + } + ++int dvb_close(adapter *a2) ++{ ++#ifdef AXE ++ adapter *c; ++ int aid, fe = a2->fe; ++ if (fe <= 0) ++ return; ++ axe_fe_reset(fe); ++ for (aid = 0; aid < 4; aid++) ++ if (aid != a2->id && a[aid]->sid_cnt > 0) break; ++ if (aid >= 4) { ++ LOG("AXE standby"); ++ for (aid = 0; aid < 4; aid++) { ++ c = a[aid]; ++ axe_fe_standby(c->fe, -1); ++ axe_set_tuner_led(aid + 1, 0); ++ ioctl(c->fe, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF); ++ c->tp.old_diseqc = c->tp.old_pol = c->tp.old_hiband = -1; ++ } ++ } else { ++ LOG("AXE standby: adapter %d busy (%d), keeping", aid, a[aid]->sid_cnt); ++ } ++ axe_set_tuner_led(a2->id + 1, 0); ++#endif ++ return 0; ++} ++ + void find_dvb_adapter(adapter **a) + { + int na = 0; +@@ -1032,9 +1245,21 @@ void find_dvb_adapter(adapter **a) + int i = 0, j = 0; + adapter *ad; + ++#ifdef AXE ++ axe_set_network_led(0); ++#endif + for (i = 0; i < MAX_ADAPTERS; i++) + for (j = 0; j < MAX_ADAPTERS; j++) + { ++#ifdef AXE ++ if (i < 4 && j == 0) { ++ axe_set_tuner_led(i + 1, 0); ++ sprintf(buf, "/dev/axe/frontend-%d", i); ++ fd = open(buf, O_RDONLY | O_NONBLOCK); ++ } else { ++ continue; ++ } ++#else + sprintf(buf, "/dev/dvb/adapter%d/frontend%d", i, j); + fd = open(buf, O_RDONLY | O_NONBLOCK); + if (fd < 0) +@@ -1042,7 +1267,8 @@ void find_dvb_adapter(adapter **a) + sprintf(buf, "/dev/dvb/adapter%d/ca%d", i, j); + fd = open(buf, O_RDONLY | O_NONBLOCK); + } +- //LOG("testing device %s -> fd: %d",buf,fd); ++#endif ++ LOG("testing device %s -> fd: %d",buf,fd); + if (fd >= 0) + { + // if (is_adapter_disabled(na)) +@@ -1064,7 +1290,7 @@ void find_dvb_adapter(adapter **a) + ad->tune = (Tune) dvb_tune; + ad->delsys = (Dvb_delsys) dvb_delsys; + ad->post_init = NULL; +- ad->close = NULL; ++ ad->close = (Adapter_commit) dvb_close; + ad->get_signal = (Device_signal) dvb_get_signal; + ad->type = ADAPTER_DVB; + close(fd); +@@ -1073,6 +1299,14 @@ void find_dvb_adapter(adapter **a) + if (na == MAX_ADAPTERS) + return; + } ++#ifdef AXE ++ else { ++ if (i < 4) { ++ LOGL(0, "AXE - cannot open %s: %i", buf, errno); ++ sleep(60); ++ } ++ } ++#endif + } + for (; na < MAX_ADAPTERS; na++) + if (a[na]) +diff --git a/minisatip.c b/minisatip.c +index d6b26d3..6b86e4b 100644 +--- a/minisatip.c ++++ b/minisatip.c +@@ -86,6 +86,12 @@ static const struct option long_options[] = + { "xml", required_argument, NULL, 'X' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, ++#ifdef AXE ++ { "link_adapters", required_argument, NULL, 'L' }, ++ { "quattro", required_argument, NULL, 'Q' }, ++ { "axe-uinput", required_argument, NULL, 'U' }, ++ { "skip-mpegts", required_argument, NULL, 'M' }, ++#endif + { 0, 0, 0, 0 } }; + + #define RRTP_OPT 'r' +@@ -117,12 +123,20 @@ static const struct option long_options[] = + #define DOCUMENTROOT_OPT 'R' + #define XML_OPT 'X' + #define THREADS_OPT 'T' ++#define LINK_OPT 'L' ++#define QUATTRO_OPT 'Q' ++#define AXE_UNICINP_OPT 'U' ++#define AXE_SKIP_PKT 'M' ++ + + void print_version(int use_log) + { + char buf[200]; +- sprintf(buf, "%s version %s, compiled with s2api version: %04X", app_name, +- version, LOGDVBAPIVERSION); ++ sprintf(buf, "%s version %s, compiled with s2api version: %04X" ++#ifdef AXE ++ " (AXE)" ++#endif ++ , app_name, version, LOGDVBAPIVERSION); + if (!use_log) + puts(buf); + else +@@ -133,10 +147,19 @@ void usage() + { + print_version(0); + printf( +- "\n\t./%s [-[fgltz]] [-a x:y:z] [-b X:Y] [-c X] [-d A:C-U ] [-D device_id] [-e X-Y,Z] [-i prio] \n\ +- \t[-j A1:S1-F1[-PIN]] [-m mac] [-o oscam_host:dvbapi_port] [-p public_host] [-r remote_rtp_host] \n\ +- \t[-R document_root] [-s [DELSYS:]host[:port] [-u A1:S1-F1[-PIN]] [-w http_server[:port]] \n\ +- \t[-x http_port] [-X xml_path] [-y rtsp_port] \n\n\ ++ "\n\t./%s [-[fgltzQ]] [-a x:y:z] [-b X:Y] [-c X] [-d A:C-U ] [-D device_id] [-e X-Y,Z] [-i prio] \n\ ++ \t[-j A1:S1-F1[-PIN]] [-m mac] " ++#ifndef DISABLE_DVBCSA ++ "[-o oscam_host:dvbapi_port] " ++#endif ++ "[-p public_host] [-r remote_rtp_host] \n\ ++ \t[-R document_root] " ++#ifndef DISABLE_SATIPCLIENT ++ "[-s [DELSYS:]host[:port] " ++#endif ++ "[-u A1:S1-F1[-PIN]] [-w http_server[:port]] \n\ ++ \t[-x http_port] [-X xml_path] [-y rtsp_port] [-L M1:S1[,M2:S2]] [-U unicable_adapter] \n\ ++ \t[-M mpegts_packets]\n\n\ + Help\n\ + -------\n\ + \n\ +@@ -179,13 +202,23 @@ Help\n\ + * -m xx: simulate xx as local mac address, generates UUID based on mac\n\ + * eg: -m 001122334455 \n\ + \n\ ++" ++#ifndef DISABLE_NETCVCLIENT ++"\ + * -n --netceiver if:count: use network interface (default vlan4) and look for netceivers\n\ + * eg: -n vlan4:2 \n\ + \n\ ++" ++#endif ++#ifndef DISABLE_DVBCSA ++"\ + * -o --dvbapi host:port - specify the hostname and port for the dvbapi server (oscam) \n\ + * eg: -o 192.168.9.9:9000 \n\ + 192.168.9.9 is the host where oscam is running and 9000 is the port configured in dvbapi section in oscam.conf\n\ + \n\ ++" ++#endif ++"\ + * -p url: specify playlist url using X_SATIPM3U header \n\ + * eg: -p http://192.168.2.3:8080/playlist\n\ + - this will add X_SATIPM3U tag into the satip description xml\n\ +@@ -195,6 +228,9 @@ Help\n\ + \n\ + * -R --document-root directory: document root for the minisatip web page and images\n\ + \n\ ++" ++#ifndef DISABLE_SATIPCLIENT ++"\ + * -s --satip-servers DELSYS:host:port - specify the remote satip host and port with delivery system DELSYS, it is possible to use multiple -s \n\ + * DELSYS - can be one of: dvbs, dvbs2, dvbt, dvbt2, dvbc, dvbc2, isdbt, atsc, dvbcb ( - DVBC_ANNEX_B ) [default: dvbs2]\n\ + host - the server of the satip server\n\ +@@ -204,6 +240,9 @@ Help\n\ + - specifies 1 dvbt satip server with address 192.168.1.3:554\n\ + - specifies 1 dvbc satip server with address 192.168.1.4:554\n\ + \n\ ++" ++#endif ++"\ + * -S --slave ADAPTER1,ADAPTER2-ADAPTER4[,..] - specify slave adapters \n\ + * Allows specifying bonded adapters (multiple adapters connected with a splitter to the same LNB)\n\ + Only one adapter needs to be master all others needs to have this parameter specified\n\ +@@ -237,7 +276,26 @@ Help\n\ + * eg: -y 5544 \n\ + - changing this to a port > 1024 removes the requirement for minisatip to run as root\n\ + \n\ +-", ++* -L --link-adapters mapping_string: link adapters (identical src,lo/hi,h/v)\n\ ++\t* The format is: M1:S1[,[M2:S2]] - master:slave\n\ ++ * eg: 0:1,0:2,0:3 \n\ ++\n\ ++" ++#ifdef AXE ++"\ ++* -L --link-adapters mapping_string: link adapters (identical src,lo/hi,h/v)\n\ ++\t* The format is: M1:S1[,M2:S2] - master:slave\n\ ++ * eg: 0:1,0:2,0:3 \n\ ++\n\ ++* -Q --quattro quattro LNB config (H/H,H/V,L/H,L/V)\n\ ++\n\ ++* -U --axe-uinput adapterno: AXE unicable/jess input (0-3)\n\ ++\n\ ++* -M --skip-mpegts packets: skip initial MPEG-TS packets for AXE demuxer (default 35)\n\ ++\n\ ++" ++#endif ++, + app_name, + ADAPTER_BUFFER, + DVR_BUFFER, opts.no_threads ? "DISABLED" : "ENABLED"); +@@ -277,17 +335,18 @@ void set_options(int argc, char *argv[]) + opts.satip_setup_pids = 0; + opts.output_buffer = 512 * 1024; + opts.satip_servers[0] = 0; +- opts.document_root = "html"; ++ opts.document_root = "/usr/share/minisatip/html"; + opts.xml_path = DESC_XML; + opts.no_threads = 0; + opts.th_priority = -1; + #ifdef __mips__ + opts.no_threads = 1; + #endif ++ opts.axe_skippkt = 35; + memset(opts.playlist, 0, sizeof(opts.playlist)); + + while ((opt = getopt_long(argc, argv, +- "flr:a:td:w:p:s:n:hc:b:m:p:e:x:u:j:o:gy:i:D:VR:S:TX:Y:", ++ "flr:a:td:w:p:s:n:hc:b:m:p:e:x:u:j:o:gy:i:D:VR:S:TX:Y:L:QU:M:", + long_options, NULL)) != -1) + { + // printf("options %d %c %s\n",opt,opt,optarg); +@@ -359,9 +418,12 @@ void set_options(int argc, char *argv[]) + opts.adapter_buffer = (opts.adapter_buffer / 188) * 188; + if (opts.adapter_buffer < ADAPTER_BUFFER) + opts.adapter_buffer = ADAPTER_BUFFER; ++#ifdef AXE ++ opts.dvr_buffer += 7*188 - 1; ++ opts.dvr_buffer -= opts.dvr_buffer % (7*188); ++#endif + if (opts.dvr_buffer == 0) + opts.dvr_buffer = DVR_BUFFER; +- + break; + } + +@@ -508,6 +570,33 @@ void set_options(int argc, char *argv[]) + LOGL(0, "Not a valid path for the xml file") + ; + break; ++#ifdef AXE ++ case LINK_OPT: ++ set_link_adapters(optarg); ++ break; ++ ++ case QUATTRO_OPT: ++ opts.quattro = 1; ++ break; ++ ++ case AXE_UNICINP_OPT: ++ opts.axe_unicinp = atoi(optarg); ++ if (opts.axe_unicinp < 0 || opts.axe_unicinp > 3) { ++ LOG("unicable input %d out of range, using 0", opts.axe_unicinp); ++ opts.axe_unicinp = 0; ++ } ++ break; ++ ++ case AXE_SKIP_PKT: ++ { ++ opts.axe_skippkt = atoi(optarg); ++ if (opts.axe_skippkt < 0) ++ opts.axe_skippkt = 0; ++ if (opts.axe_skippkt > 200) ++ opts.axe_skippkt = 200; ++ break; ++ } ++#endif + } + + } +@@ -1003,6 +1092,9 @@ int ssdp_reply(sockets * s) + return 0; + } + ++#ifdef AXE ++ axe_set_network_led(1); ++#endif + // not my uuid + LOG("Received SSDP packet from %s:%d -> handle %d", + get_socket_rhost(s->id, ra, sizeof(ra)), get_socket_rport(s->id), +@@ -1138,7 +1230,11 @@ int main(int argc, char *argv[]) + + if (!opts.no_threads) + set_socket_thread(sock_signal, start_new_thread("signal")); ++#ifdef AXE ++ sockets_timeout(sock_signal, 400); ++#else + sockets_timeout(sock_signal, 1000); ++#endif + + if (0 > (sock_bw = sockets_add(SOCK_TIMEOUT, NULL, -1, TYPE_UDP, NULL, + NULL, (socket_action) calculate_bw))) +diff --git a/minisatip.h b/minisatip.h +old mode 100644 +new mode 100755 +index 403af34..e85e54a +--- a/minisatip.h ++++ b/minisatip.h +@@ -10,7 +10,7 @@ + + #define VERSION_BUILD "26" + #define CC(a,b,c) #a b #c +-#define VERSION CC(0.5.,VERSION_BUILD,) ++#define VERSION CC(0.5.,VERSION_BUILD,-axe101) + + void set_options (int argc, char *argv[]); + +@@ -48,6 +48,9 @@ struct struct_opts + int force_scan; + int clean_psi; + int file_line; ++ int quattro; ++ int axe_unicinp; ++ int axe_skippkt; + char *last_log; + int dvbapi_port; + char *dvbapi_host; +diff --git a/socketworks.c b/socketworks.c +index 4c91a40..6cd617f 100644 +--- a/socketworks.c ++++ b/socketworks.c +@@ -431,6 +431,7 @@ int sockets_add(int sock, struct sockaddr_in *sa, int sid, int type, + max_sock = i + 1; + ss->buf = NULL; + ss->lbuf = 0; ++ ss->skiplen = type == TYPE_DVR ? opts.axe_skippkt * 188 : 0; + ss->close_sec = 0; + ss->id = i; + ss->read = (read_action) sockets_read; +@@ -624,6 +625,29 @@ void *select_and_execute(void *arg) + ss->rlen += rlen; + else + ss->rlen = 0; ++#ifdef AXE ++ if (ss->type == TYPE_DVR) { ++ while (rlen > 0 && ss->lbuf - ss->rlen >= 1316) { ++ rlen = read (ss->sock, &ss->buf[ss->rlen], ss->lbuf - ss->rlen); ++ if (rlen > 0) ++ ss->rlen += rlen; ++ } ++ if (rlen == 0 || (rlen < 0 || errno == -EAGAIN)) ++ read_ok = 1; ++ if (ss->skiplen > 0 && ss->rlen > 0) { ++ LOG("AXE skip: before rlen %d skiplen %d", ss->rlen, ss->skiplen); ++ if (ss->skiplen >= ss->rlen) { ++ ss->skiplen -= ss->rlen; ++ ss->rlen = 0; ++ } else { ++ memmove(ss->buf, &ss->buf[ss->skiplen], ss->rlen - ss->skiplen); ++ ss->rlen = ss->rlen - ss->skiplen; ++ ss->skiplen = 0; ++ } ++ LOG("AXE skip: after rlen %d skiplen %d", ss->rlen, ss->skiplen); ++ } ++ } ++#endif + //force 0 at the end of the string + if (ss->lbuf >= ss->rlen) + ss->buf[ss->rlen] = 0; +diff --git a/socketworks.h b/socketworks.h +old mode 100644 +new mode 100755 +index c852e2a..9b77d7d +--- a/socketworks.h ++++ b/socketworks.h +@@ -23,6 +23,7 @@ typedef struct struct_sockets { + unsigned char *buf; + int lbuf; + int rlen; ++ int skiplen; + int close_sec; + int id; // socket id + int err; +diff --git a/utils.c b/utils.c +index eaa0317..8cb7c49 100644 +--- a/utils.c ++++ b/utils.c +@@ -36,6 +36,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -1141,6 +1143,7 @@ pthread_t start_new_thread(char *name) + + void set_thread_prio(pthread_t tid, int prio) + { ++#if 0 + int rv; + struct sched_param param; + memset( ¶m, 0, sizeof(struct sched_param) ); +@@ -1148,6 +1151,12 @@ void set_thread_prio(pthread_t tid, int prio) + if ( (rv = pthread_setschedparam( pthread_self(), SCHED_RR, ¶m )) ) + LOG("pthread_setschedparam failed with error %d", rv); + return; ++#else ++ pid_t xtid; ++ xtid = syscall(SYS_gettid); ++ if (setpriority(PRIO_PROCESS, xtid, prio)) ++ LOG("setpriority(%d) failed with error %d", prio, errno); ++#endif + } + +