1332 lines
38 KiB
Diff
1332 lines
38 KiB
Diff
diff --git a/adapter.c b/adapter.c
|
|
index 285faea..608f323 100755
|
|
--- a/adapter.c
|
|
+++ b/adapter.c
|
|
@@ -29,10 +29,15 @@
|
|
#include <linux/dvb/dmx.h>
|
|
#include <poll.h>
|
|
#include <linux/ioctl.h>
|
|
+#include <errno.h>
|
|
|
|
#include "socketworks.h"
|
|
#include "dvb.h"
|
|
#include "adapter.h"
|
|
+#ifdef AXE
|
|
+#define AXE_MAIN 1
|
|
+#include "axe.h"
|
|
+#endif
|
|
|
|
adapter a[MAX_ADAPTERS];
|
|
extern struct struct_opts opts;
|
|
@@ -49,7 +54,12 @@ find_adapters ()
|
|
for (i = 0; i < 8; i++)
|
|
for (j = 0; j < 8; j++)
|
|
{
|
|
+#ifdef AXE
|
|
+ if (j > 0) continue;
|
|
+ sprintf (buf, "/dev/axe/frontend-%d", i);
|
|
+#else
|
|
sprintf (buf, "/dev/dvb/adapter%d/frontend%d", i, j);
|
|
+#endif
|
|
fd = open (buf, O_RDONLY | O_NONBLOCK);
|
|
//LOG("testing device %s -> fd: %d",buf,fd);
|
|
if (fd >= 0)
|
|
@@ -61,6 +71,17 @@ find_adapters ()
|
|
if (na == MAX_ADAPTERS)
|
|
return;
|
|
}
|
|
+#ifdef AXE
|
|
+ if (i == 0)
|
|
+ axe_set_network_led(0);
|
|
+ if (i < 4)
|
|
+ axe_set_tuner_led(i + 1, 0);
|
|
+ if (i < 4 && fd < 0) {
|
|
+ LOGL(0, "AXE - cannot open %s: %i", buf, errno);
|
|
+ sleep(60);
|
|
+ exit(239);
|
|
+ }
|
|
+#endif
|
|
}
|
|
for (na; na < MAX_ADAPTERS; na++)
|
|
a[na].pa = a[na].fn = -1;
|
|
@@ -122,9 +143,18 @@ init_hw ()
|
|
find_adapters ();
|
|
LOG ("trying to open [%d] adapter %d and frontend %d", i, a[i].pa,
|
|
a[i].fn);
|
|
+#ifdef AXE
|
|
+ sprintf (buf, "/dev/axe/frontend-%d", a[i].pa);
|
|
+#else
|
|
sprintf (buf, "/dev/dvb/adapter%d/frontend%d", a[i].pa, a[i].fn);
|
|
+#endif
|
|
a[i].fe = open (buf, O_RDWR | O_NONBLOCK);
|
|
+
|
|
+#ifdef AXE
|
|
+ sprintf (buf, "/dev/axe/demuxts-%d", a[i].pa);
|
|
+#else
|
|
sprintf (buf, "/dev/dvb/adapter%d/dvr%d", a[i].pa, a[i].fn);
|
|
+#endif
|
|
a[i].dvr = open (buf, O_RDONLY | O_NONBLOCK);
|
|
if (a[i].fe < 0 || a[i].dvr < 0)
|
|
{
|
|
@@ -139,22 +169,24 @@ init_hw ()
|
|
|
|
a[i].enabled = 1;
|
|
if (!a[i].buf)
|
|
- a[i].buf = malloc1 (ADAPTER_BUFFER + 10);
|
|
+ a[i].buf = malloc1 (opts.dvr + 10);
|
|
if (!a[i].buf)
|
|
{
|
|
LOG ("memory allocation failed for %d bytes failed, adapter %d",
|
|
- ADAPTER_BUFFER, i);
|
|
+ opts.dvr, i);
|
|
close_adapter (i);
|
|
continue;
|
|
}
|
|
- memset (a[i].buf, 0, ADAPTER_BUFFER + 1);
|
|
+ //memset (a[i].buf, 0, ADAPTER_BUFFER + 1);
|
|
|
|
num_adapters++;
|
|
LOG ("opened DVB adapter %d fe:%d dvr:%d", i, a[i].fe, a[i].dvr);
|
|
+#ifndef AXE
|
|
if (ioctl (a[i].dvr, DMX_SET_BUFFER_SIZE, opts.dvr) < 0)
|
|
perror ("couldn't set DVR buffer size");
|
|
else
|
|
LOG ("Done setting DVR buffer to %d bytes", DVR_BUFFER);
|
|
+#endif
|
|
init_dvb_parameters (&a[i].tp);
|
|
mark_pids_deleted (i, -1, NULL);
|
|
update_pids (i);
|
|
@@ -165,8 +197,8 @@ init_hw ()
|
|
a[i].sock =
|
|
sockets_add (a[i].dvr, NULL, i, TYPE_DVR, (socket_action) read_dmx,
|
|
(socket_action) close_adapter_for_socket, (socket_action ) adapter_timeout);
|
|
- memset (a[i].buf, 0, ADAPTER_BUFFER + 1);
|
|
- set_socket_buffer (a[i].sock, a[i].buf, ADAPTER_BUFFER);
|
|
+ //memset (a[i].buf, 0, ADAPTER_BUFFER + 1);
|
|
+ set_socket_buffer (a[i].sock, a[i].buf, opts.dvr);
|
|
sockets_timeout (a[i].sock, 60000);
|
|
LOG ("done opening adapter %i fe_sys %d", i, a[i].tp.sys);
|
|
|
|
@@ -194,6 +226,26 @@ close_adapter (int na)
|
|
mark_pids_deleted (na, -1, NULL);
|
|
update_pids (na);
|
|
// if(a[na].dmx>0)close(a[na].dmx);
|
|
+#ifdef AXE
|
|
+ if (a[na].fe > 0) {
|
|
+ int i;
|
|
+ axe_fe_reset(a[na].fe);
|
|
+ for (i = 0; i < 4; i++)
|
|
+ if (i != na && a[i].sid_cnt > 0) break;
|
|
+ if (i >= 4) {
|
|
+ LOG("AXE standby");
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ axe_fe_standby(a[i].fe, -1);
|
|
+ axe_set_tuner_led(i + 1, 0);
|
|
+ ioctl(a[i].fe, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF);
|
|
+ a[i].tp.old_diseqc = a[i].tp.old_pol = a[i].tp.old_hiband = -1;
|
|
+ }
|
|
+ } else {
|
|
+ LOG("AXE standby: adapter %d busy (%d), keeping", i, a[i].sid_cnt);
|
|
+ }
|
|
+ }
|
|
+ axe_set_tuner_led(na + 1, 0);
|
|
+#endif
|
|
if (a[na].fe > 0)
|
|
close (a[na].fe);
|
|
if (a[na].sock >= 0)
|
|
@@ -366,8 +418,8 @@ close_adapter_for_stream (int sid, int aid)
|
|
// delete the attached PIDs as well
|
|
mark_pids_deleted (aid, sid, NULL);
|
|
update_pids (aid);
|
|
-// if (a[aid].sid_cnt == 0)
|
|
-// close_adapter (aid);
|
|
+ if (a[aid].sid_cnt == 0)
|
|
+ close_adapter (aid);
|
|
}
|
|
|
|
|
|
@@ -410,7 +462,11 @@ update_pids (int aid)
|
|
int tune (int aid, int sid)
|
|
{
|
|
adapter *ad = get_adapter(aid);
|
|
- int i, rv = 0;
|
|
+ int rv = 0;
|
|
+#ifdef AXE
|
|
+ ssize_t drv;
|
|
+ char buf[1316];
|
|
+#endif
|
|
|
|
if(!ad) return -400;
|
|
ad->last_sort = getTick ();
|
|
@@ -419,7 +475,12 @@ int tune (int aid, int sid)
|
|
ad->tp.switch_type = ad->switch_type;
|
|
ad->tp.uslot = ad->uslot;
|
|
ad->tp.ufreq = ad->ufreq;
|
|
-
|
|
+
|
|
+#ifdef AXE
|
|
+ axe_set_tuner_led(aid + 1, 1);
|
|
+ axe_fe_reset(ad->fe);
|
|
+ do { drv = read(ad->dvr, buf, sizeof(buf)); } while (drv > 0);
|
|
+#endif
|
|
rv = tune_it_s2 (ad->fe, &ad->tp);
|
|
a[aid].status = 0;
|
|
a[aid].status_cnt = 0;
|
|
@@ -428,6 +489,12 @@ int tune (int aid, int sid)
|
|
close_streams_for_adapter (aid, sid);
|
|
update_pids (aid);
|
|
}
|
|
+#ifdef AXE
|
|
+ //do { drv = read(ad->dvr, buf, sizeof(buf)); } while (drv > 0);
|
|
+ axe_dmxts_start(ad->dvr);
|
|
+ if (rv < 0)
|
|
+ axe_set_tuner_led(aid + 1, 0);
|
|
+#endif
|
|
}
|
|
else
|
|
LOG ("not tuning for SID %d (do_tune=%d, master_sid=%d)", sid,
|
|
@@ -684,7 +751,11 @@ describe_adapter (int sid, int aid)
|
|
memset (dad, 0, sizeof (dad));
|
|
x = 0;
|
|
// do just max 3 signal check 1s after tune
|
|
+#ifndef AXE
|
|
if (use_ad && ((ad->status <= 0 && ad->status_cnt<8 && ad->status_cnt++>4) || opts.force_scan))
|
|
+#else
|
|
+ if (use_ad && (ad->status_cnt++ & 3) == 0)
|
|
+#endif
|
|
{
|
|
int new_gs = 1;
|
|
ts = getTick ();
|
|
@@ -701,11 +772,20 @@ describe_adapter (int sid, int aid)
|
|
if (ad->max_snr <= ad->snr) ad->max_snr = (ad->snr>0)?ad->snr:1;
|
|
LOG ("get_signal%s took %d ms for adapter %d handle %d (status: %d, ber: %d, strength:%d, snr: %d, max_strength: %d, max_snr: %d %d)",
|
|
new_gs?"":"_new", getTick () - ts, aid, ad->fe, ad->status, ad->ber, ad->strength, ad->snr, ad->max_strength, ad->max_snr, opts.force_scan);
|
|
+#ifndef AXE
|
|
if(new_gs)
|
|
{
|
|
ad->strength = ad->strength * 255 / ad->max_strength;
|
|
ad->snr = ad->snr * 15 / ad->max_snr;
|
|
}
|
|
+#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
|
|
}
|
|
if(use_ad)
|
|
{
|
|
@@ -715,14 +795,14 @@ describe_adapter (int sid, int aid)
|
|
}
|
|
if (t->sys == SYS_DVBS || t->sys == SYS_DVBS2)
|
|
sprintf (dad, "ver=1.0;src=%d;tuner=%d,%d,%d,%d,%d,%s,%s,%s,%s,%s,%d,%s;pids=",
|
|
- t->diseqc, aid, strength, status, snr, t->freq / 1000, get_pol(t->pol), get_modulation(t->mtype),
|
|
+ t->diseqc, aid+1, strength, status, snr, t->freq / 1000, get_pol(t->pol), get_modulation(t->mtype),
|
|
get_pilot(t->plts), get_rolloff(t->ro), get_delsys(t->sys), t->sr / 1000, get_fec(t->fec));
|
|
else if (t->sys == SYS_DVBT || t->sys == SYS_DVBT2)
|
|
sprintf (dad, "ver=1.1;src=%d;tuner=%d,%d,%d,%d,%.2f,%d,%s,%s,%s,%s,%s,%d,%d,%d;pids=",
|
|
- t->diseqc, aid, strength, status, snr, (double) t->freq/1000, t->bw, get_delsys(t->sys), get_tmode(t->tmode), get_modulation(t->mtype), get_gi(t->gi),
|
|
+ t->diseqc, aid+1, strength, status, snr, (double) t->freq/1000, t->bw, 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);
|
|
else sprintf (dad, "ver=1.2;src=%d;tuner=%d,%d,%d,%d,%.2f,8,%s,%s,%d,%d,%d,%d,%d;pids=",
|
|
- t->diseqc, aid, strength, status, snr, (double )t->freq/1000, get_delsys(t->sys), get_modulation(t->mtype), t->sr,
|
|
+ t->diseqc, aid+1, strength, status, snr, (double )t->freq/1000, get_delsys(t->sys), get_modulation(t->mtype), t->sr,
|
|
t->c2tft, t->ds, t->plp, t->inversion);
|
|
for (i = 0; i < MAX_PIDS; i++)
|
|
if (use_ad && ad->pids[i].flags == 1)
|
|
@@ -825,7 +905,7 @@ void enable_adapters(char *o)
|
|
|
|
void set_unicable_adapters(char *o, int type)
|
|
{
|
|
- int i, la, a_id, slot, freq;
|
|
+ int i, la, a_id, slot, freq, o13v;
|
|
char buf[100], *arg[20], *sep1, *sep2;
|
|
|
|
strncpy(buf, o, sizeof(buf));
|
|
@@ -839,17 +919,47 @@ void set_unicable_adapters(char *o, int type)
|
|
sep2 = strchr(arg[i], '-');
|
|
if( !sep1 || !sep2)
|
|
continue;
|
|
+ o13v = 0;
|
|
+ if(sep2[1] == '*') {
|
|
+ o13v = 1;
|
|
+ sep2++;
|
|
+ }
|
|
slot = map_intd(sep1 + 1, NULL, -1);
|
|
freq = map_intd(sep2 + 1, NULL, -1);
|
|
if( slot < 0 || freq < 0)
|
|
continue;
|
|
a[a_id].uslot = slot;
|
|
- a[a_id].ufreq = freq;
|
|
+ a[a_id].ufreq = o13v ? -freq : freq;
|
|
a[a_id].switch_type = type;
|
|
LOG("Setting %s adapter %d slot %d freq %d", type==SWITCH_UNICABLE?"unicable":"jess", a_id, slot, freq);
|
|
}
|
|
}
|
|
|
|
+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<la; i++)
|
|
+ {
|
|
+ a_id=map_intd(arg[i], NULL, -1);
|
|
+ if (a_id < 0 || a_id >= 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[b_id].slave = a_id + 1;
|
|
+ LOG("Setting adapter %d as master for adapter %d", a_id, b_id);
|
|
+ }
|
|
+}
|
|
|
|
int delsys_match(adapter *ad, int del_sys)
|
|
{
|
|
@@ -866,3 +976,71 @@ int delsys_match(adapter *ad, int del_sys)
|
|
return 0;
|
|
|
|
}
|
|
+
|
|
+#ifdef AXE
|
|
+
|
|
+#define myf(buf, buflen, fmt, ...) do { \
|
|
+ size_t l = strlen(buf); \
|
|
+ snprintf(buf + l, buflen - l, fmt, ##__VA_ARGS__); \
|
|
+} while (0)
|
|
+
|
|
+extern streams st[];
|
|
+
|
|
+#include <arpa/inet.h>
|
|
+
|
|
+static char *axe_status_pol(int pol)
|
|
+{
|
|
+ switch (pol) {
|
|
+ case 0: return "none";
|
|
+ case 1: return "v";
|
|
+ case 2: return "h";
|
|
+ case 3: return "l";
|
|
+ case 4: return "r";
|
|
+ default: return "unknown";
|
|
+ }
|
|
+}
|
|
+
|
|
+void
|
|
+axe_status(char *buf, size_t buflen)
|
|
+{
|
|
+ size_t idx = 0;
|
|
+ int i, k, j, port, t;
|
|
+ char *host;
|
|
+
|
|
+ t = getTick();
|
|
+ buf[0] = '\0';
|
|
+ myf(buf, buflen, "StatusVersion=1\n");
|
|
+ for (i = 0; i < MAX_ADAPTERS; i++) {
|
|
+ if (!a[i].enabled) continue;
|
|
+ if (a[i].sid_cnt == 0) continue;
|
|
+ myf(buf, buflen, "\nSubscriptions_%d=%d\n", i + 1, a[i].sid_cnt);
|
|
+ myf(buf, buflen, "DiseqC_%d=%d\n", i + 1, a[i].tp.diseqc);
|
|
+ myf(buf, buflen, "Freq_%d=%d\n", i + 1, a[i].tp.freq);
|
|
+ myf(buf, buflen, "Pol_%d=%s\n", i + 1, axe_status_pol(a[i].tp.pol));
|
|
+ for (k = 0; k < MAX_PIDS; k++) {
|
|
+ if (a[i].pids[k].flags == 0) continue;
|
|
+ if (k == 0)
|
|
+ myf(buf, buflen, "Pids_%d=%d", i + 1, a[i].pids[k].pid);
|
|
+ else
|
|
+ myf(buf, buflen, ",%d", a[i].pids[k].pid);
|
|
+ }
|
|
+ if (k > 0)
|
|
+ myf(buf, buflen, "\n");
|
|
+ for (k = j = 0; k < MAX_STREAMS; k++) {
|
|
+ streams *s = &st[k];
|
|
+ if (!s->enabled) continue;
|
|
+ if (s->adapter != i) continue;
|
|
+ port = ntohs(s->sa.sin_port);
|
|
+ host = inet_ntoa(s->sa.sin_addr);
|
|
+ myf(buf, buflen, "Stream_%d_%d=%s:%d\n", i + 1, ++j, host, port);
|
|
+ myf(buf, buflen, "Streaming_%d_%d=%d\n", i + 1, j, s->do_play ? "active" : "inactive");
|
|
+ if (s->sp > 0) {
|
|
+ myf(buf, buflen, "IOCnt_%d_%d=%zu\n", i + 1, j, s->sp);
|
|
+ myf(buf, buflen, "Bytes_%d_%d=%zu\n", i + 1, j, s->sb);
|
|
+ }
|
|
+ myf(buf, buflen, "LastRTSP_%d_%d=%d\n", i + 1, j, t - s->rtime);
|
|
+ myf(buf, buflen, "TimeoutRTSP_%d_%d=%d\n", i + 1, j, s->timeout);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#endif
|
|
diff --git a/adapter.h b/adapter.h
|
|
index 629bd9c..d95e59a 100755
|
|
--- a/adapter.h
|
|
+++ b/adapter.h
|
|
@@ -45,6 +45,7 @@ typedef struct struct_adapter
|
|
int switch_type;
|
|
int uslot; // unicable/jess slot
|
|
int ufreq; // unicable/jess frequency
|
|
+ int slave;
|
|
} adapter;
|
|
|
|
int init_hw ();
|
|
@@ -65,6 +66,7 @@ void dump_pids (int aid);
|
|
void sort_pids (int aid);
|
|
void enable_adapters(char *o);
|
|
void set_unicable_adapters(char *o, int type);
|
|
+void set_link_adapters(char *o);
|
|
|
|
int delsys_match(adapter *ad, int del_sys);
|
|
|
|
diff --git a/axe.h b/axe.h
|
|
new file mode 100644
|
|
index 0000000..cfc1927
|
|
--- /dev/null
|
|
+++ b/axe.h
|
|
@@ -0,0 +1,149 @@
|
|
+#ifndef __AXE_H
|
|
+#define __AXE_H
|
|
+
|
|
+#include <linux/dvb/dmx.h>
|
|
+#include <linux/dvb/frontend.h>
|
|
+
|
|
+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 5701bd2..32fd683 100755
|
|
--- a/dvb.c
|
|
+++ b/dvb.c
|
|
@@ -41,6 +41,10 @@
|
|
#include <ctype.h>
|
|
#include "dvb.h"
|
|
#include "minisatip.h"
|
|
+#ifdef AXE
|
|
+#include "axe.h"
|
|
+#include "adapter.h"
|
|
+#endif
|
|
|
|
extern struct struct_opts opts;
|
|
|
|
@@ -215,6 +219,29 @@ msleep (uint32_t msec)
|
|
;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+void axe_wakeup(int voltage)
|
|
+{
|
|
+ int i;
|
|
+ adapter *a;
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ a = get_adapter(i);
|
|
+ if (a == NULL || a->force_disable)
|
|
+ continue;
|
|
+ if (a->tp.old_pol >= 0)
|
|
+ return;
|
|
+ }
|
|
+ LOG("AXE wakeup");
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ a = get_adapter(i);
|
|
+ if (a == NULL || a->force_disable)
|
|
+ continue;
|
|
+ if (ioctl(a->fe, FE_SET_VOLTAGE, voltage) == -1)
|
|
+ LOG("axe_wakeup: FE_SET_VOLTAGE failed fd %d: %s", a->fe, strerror(errno));
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
int send_diseqc(int fd, int pos, int pol, int hiband)
|
|
{
|
|
struct dvb_diseqc_master_cmd cmd = {
|
|
@@ -229,6 +256,9 @@ int send_diseqc(int fd, int pos, int pol, int hiband)
|
|
|
|
if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
|
|
LOG("send_diseqc: FE_SET_TONE failed for fd %d: %s", fd, strerror(errno));
|
|
+#ifdef AXE
|
|
+ axe_wakeup(pol ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13);
|
|
+#endif
|
|
if (ioctl(fd, FE_SET_VOLTAGE, pol ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13) == -1)
|
|
LOG("send_diseqc: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno));
|
|
|
|
@@ -252,8 +282,12 @@ int send_unicable(int fd, int freq, int pos, int pol, int hiband, int slot, int
|
|
struct dvb_diseqc_master_cmd cmd = {
|
|
{0xe0, 0x11, 0x5a, 0x00, 0x00}, 5
|
|
};
|
|
- int t;
|
|
+ int t, o13v = 0;
|
|
|
|
+ if (ufreq < 0) {
|
|
+ o13v = 1;
|
|
+ ufreq = -ufreq;
|
|
+ }
|
|
t = (freq + ufreq + 2) / 4 - 350;
|
|
|
|
cmd.msg[3] = ((t & 0x0300) >> 8) |
|
|
@@ -262,12 +296,15 @@ int send_unicable(int fd, int freq, int pos, int pol, int hiband, int slot, int
|
|
|
|
LOGL(3, "send_unicable fd %d, freq %d, ufreq %d, pos = %d, pol = %d, hiband = %d, slot %d, diseqc => %02x %02x %02x %02x %02x",
|
|
fd, freq, ufreq, pos, pol, hiband, slot, cmd.msg[0], cmd.msg[1], cmd.msg[2], cmd.msg[3], cmd.msg[4]);
|
|
+#ifdef AXE
|
|
+ axe_wakeup(SEC_VOLTAGE_13);
|
|
+#endif
|
|
if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13) == -1)
|
|
LOG("send_unicable: pre voltage SEC_VOLTAGE_13 failed for fd %d: %s", fd, strerror(errno));
|
|
msleep(15);
|
|
if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
|
|
LOG("send_unicable: FE_SET_TONE failed for fd %d: %s", fd, strerror(errno));
|
|
- if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1)
|
|
+ if (!o13v && ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1)
|
|
LOG("send_unicable: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno));
|
|
msleep(15);
|
|
if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
|
|
@@ -286,6 +323,7 @@ int send_jess(int fd, int freq, int pos, int pol, int hiband, int slot, int ufre
|
|
};
|
|
// int t = (freq / 1000) - 100;
|
|
int t = freq - 100;
|
|
+ int o13v = ufreq < 0;
|
|
|
|
cmd.msg[1] = slot << 3;
|
|
cmd.msg[1] |= ((t << 8) & 0x07);
|
|
@@ -295,12 +333,15 @@ int send_jess(int fd, int freq, int pos, int pol, int hiband, int slot, int ufre
|
|
LOGL(3, "send_jess fd %d, freq %d, ufreq %d, pos = %d, pol = %d, hiband = %d, slot %d, diseqc => %02x %02x %02x %02x %02x",
|
|
fd, freq, ufreq, pos, pol, hiband, slot, cmd.msg[0], cmd.msg[1], cmd.msg[2], cmd.msg[3], cmd.msg[4]);
|
|
|
|
+#ifdef AXE
|
|
+ axe_wakeup(SEC_VOLTAGE_13);
|
|
+#endif
|
|
if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13) == -1)
|
|
LOG("send_jess: pre voltage SEC_VOLTAGE_13 failed for fd %d: %s", fd, strerror(errno));
|
|
msleep(15);
|
|
if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
|
|
LOG("send_jess: FE_SET_TONE failed for fd %d: %s", fd, strerror(errno));
|
|
- if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1)
|
|
+ if (!o13v && ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1)
|
|
LOG("send_jess: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno));
|
|
msleep(15);
|
|
if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1)
|
|
@@ -320,7 +361,7 @@ int setup_switch (int frontend_fd, transponder *tp)
|
|
int diseqc = (tp->diseqc > 0)? tp->diseqc - 1: 0;
|
|
int freq = tp->freq;
|
|
int pol = (tp->pol - 1) & 1;
|
|
-
|
|
+
|
|
if (freq < SLOF)
|
|
{
|
|
freq = (freq - LOF1);
|
|
@@ -330,12 +371,100 @@ 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 (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);
|
|
+ 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);
|
|
+ adm->tp.old_pol = pol;
|
|
+ adm->tp.old_hiband = hiband;
|
|
+ adm->tp.old_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);
|
|
+#else
|
|
freq = send_unicable(frontend_fd, freq / 1000, diseqc, pol, hiband, tp->uslot, tp->ufreq);
|
|
+#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);
|
|
+#else
|
|
freq = send_jess(frontend_fd, freq / 1000, diseqc, pol, hiband, tp->uslot, tp->ufreq);
|
|
+#endif
|
|
}else
|
|
{
|
|
if(tp->old_pol != pol || tp->old_hiband != hiband || tp->old_diseqc != diseqc)
|
|
@@ -343,6 +472,16 @@ int setup_switch (int frontend_fd, transponder *tp)
|
|
else
|
|
LOGL(3, "Skip sending diseqc commands since the switch position doesn't need to be changed: pol %d, hiband %d, switch position %d", 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;
|
|
@@ -383,8 +522,10 @@ tune_it_s2 (int fd_frontend, transponder * tp)
|
|
{.cmd = DTV_INVERSION,.u.data = 0},
|
|
{.cmd = DTV_SYMBOL_RATE,.u.data = 0},
|
|
{.cmd = DTV_INNER_FEC,.u.data = 0},
|
|
+#ifndef AXE
|
|
{.cmd = DTV_PILOT,.u.data = 0},
|
|
{.cmd = DTV_ROLLOFF,.u.data = 0},
|
|
+#endif
|
|
{.cmd = DTV_TUNE},
|
|
};
|
|
static struct dtv_properties dvbs2_cmdseq =
|
|
@@ -462,11 +603,15 @@ tune_it_s2 (int fd_frontend, transponder * tp)
|
|
tp->mtype = QPSK;
|
|
bpol = getTick();
|
|
if_freq = setup_switch (fd_frontend, tp);
|
|
+ if (!if_freq)
|
|
+ return -404;
|
|
p = &dvbs2_cmdseq;
|
|
p->props[DELSYS].u.data = tp->sys;
|
|
p->props[MODULATION].u.data = tp->mtype;
|
|
+#ifndef AXE
|
|
p->props[PILOT].u.data = tp->plts;
|
|
p->props[ROLLOFF].u.data = tp->ro;
|
|
+#endif
|
|
p->props[INVERSION].u.data = tp->inversion;
|
|
p->props[SYMBOL_RATE].u.data = tp->sr;
|
|
p->props[FEC_INNER].u.data = tp->fec;
|
|
@@ -475,7 +620,12 @@ tune_it_s2 (int fd_frontend, transponder * tp)
|
|
LOG("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, p->props[FREQUENCY].u.data, get_pol(tp->pol), tp->pol, p->props[SYMBOL_RATE].u.data, fe_fec[p->props[FEC_INNER].u.data],
|
|
fe_delsys[p->props[DELSYS].u.data], fe_modulation[p->props[MODULATION].u.data],
|
|
- fe_rolloff[p->props[ROLLOFF].u.data], fe_pilot[p->props[PILOT].u.data], bclear, bpol);
|
|
+#ifdef AXE
|
|
+ "auto", "auto",
|
|
+#else
|
|
+ fe_rolloff[p->props[ROLLOFF].u.data], fe_pilot[p->props[PILOT].u.data],
|
|
+#endif
|
|
+ bclear, bpol);
|
|
|
|
break;
|
|
|
|
@@ -560,6 +710,20 @@ set_pid (int hw, int ad, uint16_t i_pid)
|
|
char buf[100];
|
|
int fd;
|
|
|
|
+#ifdef AXE
|
|
+ adapter *a = get_adapter(hw);
|
|
+
|
|
+ if ( i_pid > 8192 || a == NULL)
|
|
+ LOG_AND_RETURN(-1, "pid %d > 8192 for ADAPTER %d", i_pid, hw);
|
|
+
|
|
+ if (axe_dmxts_add_pid(a->dvr, i_pid) < 0)
|
|
+ {
|
|
+ LOG ("failed setting filter on %d (%s)", i_pid, strerror (errno));
|
|
+ return -1;
|
|
+ }
|
|
+ LOG ("setting filter on PID %d for ADAPTER %d", i_pid, a->pa);
|
|
+ return (hw << 16) | i_pid;
|
|
+#else
|
|
if ( i_pid > 8192 )
|
|
LOG_AND_RETURN(-1, "pid %d > 8192 for /dev/dvb/adapter%d/demux%d", i_pid, hw, ad);
|
|
|
|
@@ -585,6 +749,7 @@ set_pid (int hw, int ad, uint16_t i_pid)
|
|
}
|
|
|
|
LOG ("setting filter on PID %d for fd %d", i_pid, fd);
|
|
+#endif
|
|
|
|
return fd;
|
|
}
|
|
@@ -592,6 +757,17 @@ set_pid (int hw, int ad, uint16_t i_pid)
|
|
|
|
int del_filters (int fd, int pid)
|
|
{
|
|
+#ifdef AXE
|
|
+ adapter *a = get_adapter(fd >> 16);
|
|
+ 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) < 0)
|
|
@@ -599,6 +775,7 @@ int del_filters (int fd, int pid)
|
|
else
|
|
LOG ("clearing filters on PID %d FD %d", pid, fd);
|
|
close (fd);
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
@@ -606,6 +783,15 @@ int del_filters (int fd, int pid)
|
|
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;
|
|
|
|
@@ -703,6 +889,7 @@ dvb_delsys (int aid, int fd, fe_delivery_system_t *sys)
|
|
|
|
LOG ("returning default from dvb_delsys => %s (count %d)", fe_delsys[rv] , nsys);
|
|
return (fe_delivery_system_t) rv;
|
|
+#endif
|
|
|
|
}
|
|
|
|
diff --git a/minisatip.c b/minisatip.c
|
|
index d4076ba..dad15ae 100755
|
|
--- a/minisatip.c
|
|
+++ b/minisatip.c
|
|
@@ -36,6 +36,7 @@
|
|
#include <sys/socket.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
+#include <syslog.h>
|
|
#include "socketworks.h"
|
|
#include "stream.h"
|
|
#include "adapter.h"
|
|
@@ -62,10 +63,16 @@ usage ()
|
|
-c X: bandwidth capping for the output to the network (default: unlimited)\n\
|
|
-b X: set the DVR buffer to X KB (default: %dKB)\n\
|
|
-l increases the verbosity (you can use multiple -l), logging to stdout in foreground mode or in /tmp/log when a daemon\n\
|
|
+ -g use syslog instead stdout for logging, multiple -g - print to stderr as well\n\
|
|
-p url: specify playlist url using X_SATIPM3U header \n\
|
|
-u unicable_string: defines the unicable adapters (A) and their slot (S) and frequency (F):\n\
|
|
\tThe format is: A1:S1-F1[,A2:S2-F2[,...]] \n\
|
|
+ \tWhen * character is used before frequency, force 13V for setup\n\
|
|
-j jess_string: same format as unicable_string \n\
|
|
+ -L link adapters (identical src,lo/hi,h/v), the format is M:S (master:slave)\n\
|
|
+ -Q quattro LNB config (H/H,H/V,L/H,L/V)\n\
|
|
+ -X AXE unicable/jess input (0-3)\n\
|
|
+ -M X: skip initial MPEG-TS packets for AXE demuxer (default 35)\n\
|
|
",
|
|
DVR_BUFFER / 1024);
|
|
exit (1);
|
|
@@ -97,11 +104,12 @@ set_options (int argc, char *argv[])
|
|
opts.device_id = 0;
|
|
opts.bootid = 0;
|
|
opts.force_scan = 0;
|
|
- opts.dvr = DVR_BUFFER;
|
|
+ opts.dvr = 14*7*DVB_FRAME;
|
|
opts.file_line = 0;
|
|
+ opts.axe_skippkt = 35;
|
|
memset(opts.playlist, sizeof(opts.playlist), 0);
|
|
|
|
- while ((opt = getopt (argc, argv, "flr:a:t:d:w:p:shc:b:m:p:e:x:u:j:")) != -1)
|
|
+ while ((opt = getopt (argc, argv, "flr:a:t:d:w:p:shc:b:m:p:e:x:u:j:gL:QX:S:")) != -1)
|
|
{
|
|
// printf("options %d %c %s\n",opt,opt,optarg);
|
|
switch (opt)
|
|
@@ -143,6 +151,12 @@ set_options (int argc, char *argv[])
|
|
break;
|
|
}
|
|
|
|
+ case SYSLOG_OPT:
|
|
+ {
|
|
+ opts.slog++;
|
|
+ break;
|
|
+ }
|
|
+
|
|
case HELP_OPT:
|
|
{
|
|
usage ();
|
|
@@ -164,6 +178,10 @@ set_options (int argc, char *argv[])
|
|
case DVRBUFFER_OPT:
|
|
{
|
|
opts.dvr = atoi (optarg) * 1024;
|
|
+#ifdef AXE
|
|
+ opts.dvr += 7*188 - 1;
|
|
+ opts.dvr -= opts.dvr % (7*188);
|
|
+#endif
|
|
break;
|
|
}
|
|
|
|
@@ -209,6 +227,37 @@ set_options (int argc, char *argv[])
|
|
break;
|
|
}
|
|
|
|
+ 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;
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -483,6 +532,11 @@ http_response (sockets *s, int rc, char *ah, char *desc, int cseq, int lr)
|
|
|
|
#define RBUF 4000
|
|
|
|
+static inline end_of_header(char *buf)
|
|
+{
|
|
+ return buf[0] == 0x0d && buf[1] == 0x0a && buf[2] == 0x0d && buf[3] == 0x0a;
|
|
+}
|
|
+
|
|
int
|
|
read_rtsp (sockets * s)
|
|
{
|
|
@@ -507,8 +561,7 @@ read_rtsp (sockets * s)
|
|
}
|
|
}
|
|
|
|
- if (s->rlen < 4
|
|
- || (htonl (*(uint32_t *) & s->buf[s->rlen - 4]) != 0x0D0A0D0A))
|
|
+ if (s->rlen < 4 || !end_of_header(s->buf + s->rlen - 4))
|
|
{
|
|
if( s->rlen > RBUF - 10 )
|
|
{
|
|
@@ -524,6 +577,9 @@ read_rtsp (sockets * s)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+ axe_set_network_led(1);
|
|
+#endif
|
|
rlen = s->rlen;
|
|
s->rlen = 0;
|
|
|
|
@@ -726,8 +782,7 @@ read_http (sockets * s)
|
|
"%s"
|
|
"</device></root>";
|
|
|
|
- if (s->rlen < 5
|
|
- || (htonl (*(uint32_t *) & s->buf[s->rlen - 4]) != 0x0D0A0D0A))
|
|
+ if (s->rlen < 5 || !end_of_header(s->buf + s->rlen - 4))
|
|
{
|
|
if( s->rlen > RBUF - 10 )
|
|
{
|
|
@@ -749,6 +804,9 @@ read_http (sockets * s)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+ axe_set_network_led(1);
|
|
+#endif
|
|
rlen = s->rlen;
|
|
s->rlen = 0;
|
|
|
|
@@ -781,6 +839,15 @@ read_http (sockets * s)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+ if (strncmp (arg[1], "/axe-status.txt", 15) == 0)
|
|
+ {
|
|
+ axe_status(buf, sizeof(buf));
|
|
+ http_response (s, 200, "CACHE-CONTROL: no-cache\r\nContent-type: text/plain", buf, 0, 0);
|
|
+ return 0;
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (strncmp (arg[1], "/icons/", 7) == 0)
|
|
{
|
|
char *ctype = NULL;
|
|
@@ -904,6 +971,9 @@ 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", inet_ntoa(s->sa.sin_addr), ntohs(s->sa.sin_port), s->sock);
|
|
LOGL(3, "%s", s->buf);
|
|
@@ -987,7 +1057,13 @@ main (int argc, char *argv[])
|
|
set_options (argc, argv);
|
|
if (opts.daemon)
|
|
becomeDaemon ();
|
|
+ if (opts.slog)
|
|
+ openlog ("minisatip", LOG_NDELAY|LOG_NOWAIT|LOG_PID|(opts.slog>1?LOG_PERROR:0), LOG_DAEMON);
|
|
+#ifdef AXE
|
|
+ LOGL(0, "Starting minisatip version %s, compiled with AXE DVB API, DVR buffer %d bytes",VERSION,opts.dvr);
|
|
+#else
|
|
LOGL(0, "Starting minisatip version %s, compiled with dvbapi version: %04X",VERSION, DVBAPIVERSION);
|
|
+#endif
|
|
readBootID();
|
|
if ((ssdp = udp_bind (NULL, 1900)) < 1)
|
|
FAIL ("SSDP: Could not bind on udp port 1900");
|
|
@@ -1021,7 +1097,9 @@ main (int argc, char *argv[])
|
|
select_and_execute ();
|
|
unlink(PID_FILE);
|
|
free_all ();
|
|
- return 0;
|
|
+ if (opts.slog)
|
|
+ closelog();
|
|
+ return 0;
|
|
}
|
|
|
|
|
|
@@ -1247,12 +1325,16 @@ void _log(int level, char * file, int line, const char *fmt, ...) {
|
|
idx = 1;
|
|
else if ( idx < 0)
|
|
idx = 0;
|
|
- if(opts.file_line)
|
|
+ if(opts.file_line && !opts.slog)
|
|
len1 = snprintf(output[idx], sizeof(output[0]), "[%s] %s:%d: ", get_current_timestamp_log(), file, line);
|
|
- else
|
|
+ else if (!opts.slog)
|
|
len1 = snprintf(output[idx], sizeof(output[0]), "[%s]: ", get_current_timestamp_log());
|
|
+ else if (opts.file_line) {
|
|
+ len1 = 0;
|
|
+ output[idx][0] = '\0';
|
|
+ }
|
|
/* Write the error message */
|
|
- len = len1;
|
|
+ len = len1 = len1 < sizeof(output[0]) ? len1 : sizeof(output[0]) - 1;
|
|
both = 0;
|
|
va_start(arg, fmt);
|
|
len += vsnprintf(output[idx] + len, sizeof(output[0]) - len, fmt, arg);
|
|
@@ -1271,9 +1353,9 @@ void _log(int level, char * file, int line, const char *fmt, ...) {
|
|
}
|
|
|
|
if(both){
|
|
- puts(output[1-idx]);
|
|
+ if(opts.slog)syslog(LOG_NOTICE, "%s", output[1-idx]); else puts(output[1-idx]);
|
|
both = 0;
|
|
}
|
|
- if(times==0)puts(output[idx]);
|
|
+ if(times==0) if(opts.slog)syslog(LOG_NOTICE, "%s", output[idx]); else puts(output[idx]);
|
|
fflush(stdout);
|
|
}
|
|
diff --git a/minisatip.h b/minisatip.h
|
|
index 821e756..44ca0c9 100755
|
|
--- a/minisatip.h
|
|
+++ b/minisatip.h
|
|
@@ -9,7 +9,7 @@
|
|
|
|
#define VERSION_BUILD "84"
|
|
#define CC(a,b,c) #a b #c
|
|
-#define VERSION CC(0.1.,VERSION_BUILD,)
|
|
+#define VERSION CC(0.1.,VERSION_BUILD,-axe2)
|
|
|
|
void set_options (int argc, char *argv[]);
|
|
|
|
@@ -30,6 +30,11 @@ void set_options (int argc, char *argv[]);
|
|
#define ENABLE_ADAPTERS_OPT 'e'
|
|
#define UNICABLE_OPT 'u'
|
|
#define JESS_OPT 'j'
|
|
+#define SYSLOG_OPT 'g'
|
|
+#define LINK_OPT 'L'
|
|
+#define QUATTRO_OPT 'Q'
|
|
+#define AXE_UNICINP_OPT 'X'
|
|
+#define AXE_SKIP_PKT 'M'
|
|
|
|
#define PID_FILE "/var/run/minisatip.pid"
|
|
struct struct_opts
|
|
@@ -39,6 +44,7 @@ struct struct_opts
|
|
char *disc_host; //discover host
|
|
char mac[13];
|
|
unsigned int log,
|
|
+ slog,
|
|
start_rtp,
|
|
http_port;
|
|
int timeout_sec;
|
|
@@ -50,6 +56,9 @@ struct struct_opts
|
|
int dvr;
|
|
int force_scan;
|
|
int file_line;
|
|
+ int quattro;
|
|
+ int axe_unicinp;
|
|
+ int axe_skippkt;
|
|
char *last_log;
|
|
char playlist[200];
|
|
};
|
|
diff --git a/socketworks.c b/socketworks.c
|
|
index b4891f1..3167cac 100755
|
|
--- a/socketworks.c
|
|
+++ b/socketworks.c
|
|
@@ -299,6 +299,7 @@ socket_action a, socket_action c, socket_action t)
|
|
max_sock = i + 1;
|
|
s[i].buf = NULL;
|
|
s[i].lbuf = 0;
|
|
+ s[i].skiplen = type == TYPE_DVR ? opts.axe_skippkt * 188 : 0;
|
|
s[i].close_sec = 0;
|
|
s[i].sock_id = i;
|
|
pf[i].fd = sock;
|
|
@@ -433,6 +434,29 @@ select_and_execute ()
|
|
ss->rtime = c_time;
|
|
if(rlen>0)
|
|
ss->rlen += rlen;
|
|
+#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))
|
|
+ rlen = 1;
|
|
+ if (ss->skiplen > 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
|
|
index 57b25b2..9c14f64 100755
|
|
--- a/socketworks.h
|
|
+++ b/socketworks.h
|
|
@@ -18,6 +18,7 @@ typedef struct struct_sockets
|
|
unsigned char *buf;
|
|
int lbuf;
|
|
int rlen;
|
|
+ int skiplen;
|
|
int close_sec;
|
|
int sock_id; // socket id
|
|
int err;
|
|
diff --git a/stream.c b/stream.c
|
|
index db4a46d..2036841 100755
|
|
--- a/stream.c
|
|
+++ b/stream.c
|
|
@@ -320,6 +320,7 @@ int decode_transport (sockets * s, char *arg, char *default_rtp, int start_rtp)
|
|
if(sid->type == 0)
|
|
{
|
|
int i;
|
|
+ socklen_t sl;
|
|
struct sockaddr_in sa;
|
|
|
|
sid->type = STREAM_RTSP_UDP;
|
|
@@ -332,6 +333,13 @@ int decode_transport (sockets * s, char *arg, char *default_rtp, int start_rtp)
|
|
|
|
if((sid->rsock = udp_bind_connect (NULL, opts.start_rtp + (sid->sid * 2), p.dest, p.port, &sid->sa)) < 0)
|
|
LOG_AND_RETURN (-1, "decode_transport failed: UDP connection on rtp port to %s:%d failed", p.dest, p.port);
|
|
+
|
|
+ i = 512*1024;
|
|
+ if(setsockopt(sid->rsock, SOL_SOCKET, SO_SNDBUF, &i, sizeof(i)))
|
|
+ LOG("unable to set output UDP buffer size to %d", i);
|
|
+ sl = sizeof(int);
|
|
+ if(!getsockopt(sid->rsock, SOL_SOCKET, SO_SNDBUF, &i, &sl))
|
|
+ LOG("output UDP buffer size is %d bytes", i);
|
|
|
|
if ((sid->rtcp = udp_bind_connect (NULL, opts.start_rtp + (sid->sid * 2) +1, p.dest, p.port + 1, &sa)) < 1)
|
|
LOG_AND_RETURN (-1, "decode_transport failed: UDP connection on rtcp port to %s:%d failed", p.dest, p.port+1);
|
|
@@ -582,7 +590,7 @@ send_rtcp (int s_id, int ctime)
|
|
rtcp[51] = 0;
|
|
rtcp[52] = 0x80;
|
|
rtcp[53] = 0xCC;
|
|
- copy16( rtcp, 54, (la + 16) / 4);
|
|
+ copy16( rtcp, 54, ((la + 16 + 3) / 4) - 1);
|
|
copy32( rtcp, 56, sid->ssrc);
|
|
rtcp[60] = 'S';
|
|
rtcp[61] = 'E';
|
|
@@ -617,13 +625,18 @@ extern uint32_t nsecs, reads;
|
|
void
|
|
flush_streamb (streams * sid, char *buf, int rlen, int ctime)
|
|
{
|
|
- int i, rv = 0;
|
|
+ int i, remain, rv = 0;
|
|
|
|
if (sid->type == STREAM_HTTP)
|
|
rv = send (sid->rsock, buf, rlen, MSG_NOSIGNAL);
|
|
- else
|
|
- for (i = 0; i < rlen; i += DVB_FRAME * 7)
|
|
- rv += send_rtpb (sid, &buf[i], DVB_FRAME * 7);
|
|
+ else {
|
|
+ for (i = 0; i < rlen; i += DVB_FRAME * 7) {
|
|
+ remain = rlen - i;
|
|
+ rv += send_rtpb (sid, &buf[i],
|
|
+ remain < DVB_FRAME * 7 ?
|
|
+ remain : DVB_FRAME * 7);
|
|
+ }
|
|
+ }
|
|
|
|
sid->iiov = 0;
|
|
sid->wtime = ctime;
|
|
@@ -675,8 +688,9 @@ read_dmx (sockets * s)
|
|
int pid, flush_all = 0;
|
|
uint64_t stime;
|
|
|
|
- if (s->rlen % DVB_FRAME != 0)
|
|
- s->rlen = ((int) s->rlen / DVB_FRAME) * DVB_FRAME;
|
|
+ i = s->rlen % DVB_FRAME;
|
|
+ if (i)
|
|
+ s->rlen -= i;
|
|
if (s->rlen == s->lbuf)
|
|
cnt++;
|
|
else
|
|
@@ -696,7 +710,7 @@ read_dmx (sockets * s)
|
|
LOG ("Buffer overrun %d %d", s->rlen, s->lbuf);
|
|
|
|
// LOGL(2, "read_dmx called for adapter %d -> %d bytes read ",s->sid, s->rlen);
|
|
-
|
|
+
|
|
int rlen = s->rlen;
|
|
ad->rtime = s->rtime;
|
|
s->rlen = 0;
|
|
diff --git a/stream.h b/stream.h
|
|
index 5f1bd6f..5885c59 100755
|
|
--- a/stream.h
|
|
+++ b/stream.h
|
|
@@ -38,7 +38,7 @@ typedef struct struct_streams
|
|
*pids;
|
|
struct iovec iov[MAX_PACK + 2];
|
|
int iiov;
|
|
- int sp,sb;
|
|
+ size_t sp,sb;
|
|
int timeout;
|
|
|
|
} streams;
|