2639 lines
74 KiB
Diff
2639 lines
74 KiB
Diff
diff --git a/.gitignore b/.gitignore
|
|
index f652e62..8e8a5b9 100644
|
|
--- a/.gitignore
|
|
+++ b/.gitignore
|
|
@@ -1,2 +1,5 @@
|
|
/minisatip
|
|
*.o
|
|
+config.log
|
|
+config.status
|
|
+Makefile
|
|
diff --git a/README.md b/README.md
|
|
index f0993bc..2c2923a 100644
|
|
--- a/README.md
|
|
+++ b/README.md
|
|
@@ -25,15 +25,7 @@ https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=7UWQ7FXSABUH8&item
|
|
Usage:
|
|
-------
|
|
|
|
-minisatip version 0.5.39, compiled with s2api version: 050A
|
|
-[19/03 11:23:51.663 main]: Built with dvbcsa
|
|
-[19/03 11:23:51.663 main]: Built with dvbapi
|
|
-[19/03 11:23:51.663 main]: Built with AES (OpenSSL)
|
|
-[19/03 11:23:51.663 main]: Built with tables processing
|
|
-[19/03 11:23:51.663 main]: Built with satip client
|
|
-[19/03 11:23:51.663 main]: Built with linux dvb client
|
|
-[19/03 11:23:51.663 main]: Built with backtrace
|
|
-[19/03 11:23:51.663 main]: Built with netceiver
|
|
+minisatip version 0.5.44, compiled with s2api version: 050A
|
|
|
|
./minisatip [-[fgltz]] [-a x:y:z] [-b X:Y] [-c X] [-d A:C-U ] [-D device_id] [-e X-Y,Z] [-i prio]
|
|
[-[uj] A1:S1-F1[-PIN]] [-m mac][-o oscam_host:dvbapi_port] [-p public_host] [-r remote_rtp_host]
|
|
@@ -116,6 +108,7 @@ Help
|
|
- specifies 1 dvbt satip server with address 192.168.1.3:554
|
|
- specifies 1 dvbc satip server with address 192.168.1.4:554
|
|
|
|
+* -O --satip-tcp Use RTSP over TCP instead of UDP for data transport
|
|
* -S --slave ADAPTER1,ADAPTER2-ADAPTER4[,..] - specify slave adapters
|
|
* Allows specifying bonded adapters (multiple adapters connected with a splitter to the same LNB)
|
|
Only one adapter needs to be master all others needs to have this parameter specified
|
|
diff --git a/adapter.c b/adapter.c
|
|
index f02c4d5..c130c1c 100644
|
|
--- a/adapter.c
|
|
+++ b/adapter.c
|
|
@@ -58,6 +58,8 @@ adapter *adapter_alloc()
|
|
{
|
|
adapter *ad = malloc1(sizeof(adapter));
|
|
|
|
+ mutex_init(&ad->mutex);
|
|
+
|
|
/* diseqc setup */
|
|
ad->diseqc_param.fast = opts.diseqc_fast;
|
|
ad->diseqc_param.committed_no = opts.diseqc_committed_no;
|
|
@@ -118,6 +120,7 @@ int adapter_timeout(sockets *s)
|
|
return 0;
|
|
}
|
|
|
|
+#ifndef AXE
|
|
if (opts.no_threads)
|
|
{
|
|
for (i = 0; i < MAX_ADAPTERS; i++)
|
|
@@ -134,6 +137,7 @@ int adapter_timeout(sockets *s)
|
|
s->sid, do_close, max_close);
|
|
if (!do_close)
|
|
s->rtime = max_close;
|
|
+#endif
|
|
|
|
return do_close;
|
|
}
|
|
@@ -171,7 +175,6 @@ int init_hw(int i)
|
|
return 2;
|
|
|
|
ad = a[i];
|
|
- mutex_init(&ad->mutex);
|
|
mutex_lock(&ad->mutex);
|
|
if (is_adapter_disabled(i))
|
|
goto NOK;
|
|
@@ -183,10 +186,8 @@ int init_hw(int i)
|
|
ad->fe_sock = -1;
|
|
ad->sock = -1;
|
|
|
|
- if (ad->enabled)
|
|
- {
|
|
+ if (!ad->open)
|
|
goto NOK;
|
|
- }
|
|
|
|
if (ad->open(ad))
|
|
{
|
|
@@ -326,10 +327,12 @@ void close_adapter(int na)
|
|
ad->sock = -1;
|
|
ad->strength = 0;
|
|
ad->snr = 0;
|
|
+#ifndef AXE
|
|
ad->old_diseqc = -1;
|
|
ad->old_hiband = -1;
|
|
ad->old_pol = -1;
|
|
- mutex_destroy(&ad->mutex);
|
|
+#endif
|
|
+ mutex_unlock(&ad->mutex);
|
|
// if(a[na]->buf)free1(a[na]->buf);a[na]->buf=NULL;
|
|
LOG("done closing adapter %d", na);
|
|
}
|
|
@@ -544,6 +547,19 @@ int set_adapter_for_stream(int sid, int aid)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+static void free_axe_input(adapter *ad)
|
|
+{
|
|
+ int aid;
|
|
+ adapter *ad2;
|
|
+
|
|
+ for (aid = 0; aid < 4; aid++) {
|
|
+ ad2 = get_adapter2(aid);
|
|
+ ad2->axe_used &= ~(1 << ad->id);
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
void close_adapter_for_stream(int sid, int aid)
|
|
{
|
|
adapter *ad;
|
|
@@ -562,9 +578,12 @@ void close_adapter_for_stream(int sid, int aid)
|
|
LOG("closed adapter %d for stream %d m:%d s:%d", aid, sid, ad->master_sid,
|
|
ad->sid_cnt);
|
|
// delete the attached PIDs as well
|
|
- if (ad->sid_cnt == 0)
|
|
+ if (ad->sid_cnt == 0) {
|
|
mark_pids_deleted(aid, -1, NULL);
|
|
- else
|
|
+#ifdef AXE
|
|
+ free_axe_input(ad);
|
|
+#endif
|
|
+ } else
|
|
mark_pids_deleted(aid, sid, NULL);
|
|
update_pids(aid);
|
|
// if (a[aid]->sid_cnt == 0)
|
|
@@ -660,6 +679,7 @@ int tune(int aid, int sid)
|
|
ad->status = -1;
|
|
ad->status_cnt = 0;
|
|
set_socket_pos(ad->sock, 0); // flush the existing buffer
|
|
+ set_socket_skip(ad->sock);
|
|
ad->rlen = 0;
|
|
if (ad->sid_cnt > 1) // the master changed the frequency
|
|
{
|
|
@@ -978,6 +998,18 @@ get_adapter1(int aid, char *file, int line)
|
|
return a[aid];
|
|
}
|
|
|
|
+adapter *
|
|
+get_adapter21(int aid, char *file, int line)
|
|
+{
|
|
+ if (aid < 0 || aid >= MAX_ADAPTERS || !a[aid] || disabled[aid])
|
|
+ {
|
|
+ LOG("%s:%d: get_adapter2 returns NULL for adapter_id %d", file, line,
|
|
+ aid);
|
|
+ return NULL;
|
|
+ }
|
|
+ return a[aid];
|
|
+}
|
|
+
|
|
char* get_stream_pids(int s_id, char *dest, int max_size);
|
|
char *
|
|
describe_adapter(int sid, int aid, char *dad, int ld)
|
|
@@ -1092,9 +1124,11 @@ void free_all_adapters()
|
|
{
|
|
if (a[i]->buf)
|
|
free1(a[i]->buf);
|
|
+ mutex_destroy(&a[i]->mutex);
|
|
free(a[i]);
|
|
a[i] = NULL;
|
|
}
|
|
+ mutex_destroy(&a_mutex);
|
|
|
|
#ifndef DISABLE_NETCVCLIENT
|
|
fprintf(stderr, "\n\nREEL: recv_exit\n");
|
|
@@ -1347,6 +1381,93 @@ 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<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] && a[a_id]->slave))
|
|
+ continue;
|
|
+ if (!a[b_id])
|
|
+ a[b_id] = adapter_alloc();
|
|
+ a[b_id]->slave = a_id + 1;
|
|
+ LOGL(0, "Setting adapter %d as master for adapter %d", a_id, b_id);
|
|
+ }
|
|
+}
|
|
+
|
|
+extern int absolute_switch;
|
|
+extern int absolute_table[32][4];
|
|
+
|
|
+void set_absolute_src(char *o)
|
|
+{
|
|
+ int i, la, src, inp, pos;
|
|
+ char buf[100], *arg[20], *inps, *poss;
|
|
+
|
|
+ strncpy(buf, o, sizeof(buf)-1);
|
|
+ buf[sizeof(buf)-1] = '\0';
|
|
+ la = split(arg, buf, sizeof(arg), ',');
|
|
+ for (i=0; i<la; i++)
|
|
+ {
|
|
+ inps = strchr(arg[i], ':');
|
|
+ if (!inps)
|
|
+ continue;
|
|
+ inps++;
|
|
+ poss = strchr(inps, ':');
|
|
+ if (!poss)
|
|
+ continue;
|
|
+ poss++;
|
|
+
|
|
+ src = map_intd(arg[i], NULL, -1);
|
|
+ inp = map_intd(inps, NULL, -1);
|
|
+ pos = map_intd(poss, NULL, -1);
|
|
+
|
|
+ if (src < 0 || src > 31)
|
|
+ continue;
|
|
+ if (inp < 0 || inp > 3)
|
|
+ continue;
|
|
+ if (pos < 0 || pos >= 15)
|
|
+ continue;
|
|
+ LOGL(0, "Setting source %d (src=%d) to input %d position %d", src, src + 1, inp, pos);
|
|
+ absolute_table[src][inp] = pos + 1;
|
|
+ absolute_switch = 1;
|
|
+ }
|
|
+}
|
|
+
|
|
+void set_unicable_input(char *o)
|
|
+{
|
|
+ int i, la, input, input2;
|
|
+ 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=input=0; i < 4; i++)
|
|
+ {
|
|
+ if (i < la) {
|
|
+ input2=map_intd(arg[i], NULL, -1);
|
|
+ if (input2 >= 0 && input2 < 4)
|
|
+ input = input2;
|
|
+ }
|
|
+ opts.axe_unicinp[i] = input;
|
|
+ LOGL(0, "Setting input %d for unicable adapter %d", input, i);
|
|
+ }
|
|
+}
|
|
+
|
|
extern char *fe_delsys[];
|
|
void set_adapters_delsys(char *o)
|
|
{
|
|
@@ -1615,6 +1736,82 @@ char *get_all_delsys(int aid, char *dest, int max_size)
|
|
return dest;
|
|
}
|
|
|
|
+static char *axe_vdevice_read(int aid, char *buf, size_t buflen)
|
|
+{
|
|
+ size_t len;
|
|
+ int i, fd;
|
|
+ for (i = 0; i < 10; i++) {
|
|
+ snprintf(buf, buflen, "/proc/STAPI/stpti/PTI%d/vDeviceInfo", aid ^ 1);
|
|
+ fd = open(buf, O_RDONLY);
|
|
+ len = read(fd, buf, buflen-1);
|
|
+ close(fd);
|
|
+ if (len > 200) {
|
|
+ buf[len] = '\0';
|
|
+ return buf;
|
|
+ }
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+adapter *axe_vdevice_sync(int aid)
|
|
+{
|
|
+ adapter *ad = get_adapter_nw(aid);
|
|
+ char buf[1024], *p;
|
|
+ int64_t t;
|
|
+ uint32_t addr, pktc, syncerrc, tperrc, ccerr;
|
|
+ int fd;
|
|
+
|
|
+ if (!ad)
|
|
+ return NULL;
|
|
+ t = getTickUs();
|
|
+ if (ad->axe_vdevice_last_sync + 1000000 >= t)
|
|
+ return ad;
|
|
+ ad->axe_vdevice_last_sync = t;
|
|
+ p = axe_vdevice_read(aid, buf, sizeof(buf));
|
|
+ if (p) p = strchr(p, '\n');
|
|
+ if (p) {
|
|
+ if (sscanf(p + 1, "#%08x: %08x %08x %08x %08x",
|
|
+ &addr, &pktc, &syncerrc, &tperrc, &ccerr) == 5) {
|
|
+ ad->axe_pktc = pktc;
|
|
+ ad->axe_ccerr = ccerr;
|
|
+ }
|
|
+ }
|
|
+ return ad;
|
|
+}
|
|
+
|
|
+int64_t get_axe_pktc(int aid)
|
|
+{
|
|
+ adapter *ad = axe_vdevice_sync(aid);
|
|
+ return ad ? ad->axe_pktc : 0;
|
|
+}
|
|
+
|
|
+int64_t get_axe_ccerr(int aid)
|
|
+{
|
|
+ adapter *ad = axe_vdevice_sync(aid);
|
|
+ return ad ? ad->axe_ccerr : 0;
|
|
+}
|
|
+
|
|
+char *get_axe_coax(int aid, char *dest, int max_size)
|
|
+{
|
|
+ int i, len;
|
|
+ adapter *ad;
|
|
+ dest[0] = 0;
|
|
+ len = 0;
|
|
+ if (aid < 0 || aid > 3)
|
|
+ return dest;
|
|
+
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ ad = get_adapter2(i);
|
|
+ if (ad && ad->axe_used & (1<<aid))
|
|
+ len += snprintf(dest + len, max_size - len, "LNB%d,", i + 1);
|
|
+ }
|
|
+
|
|
+ if (len > 0)
|
|
+ dest[len - 1] = 0;
|
|
+
|
|
+ return dest;
|
|
+}
|
|
+
|
|
_symbols adapters_sym[] =
|
|
{
|
|
{ "ad_enabled", VAR_AARRAY_INT8, a, 1, MAX_ADAPTERS, offsetof(adapter,
|
|
@@ -1657,4 +1854,7 @@ _symbols adapters_sym[] =
|
|
{ "tuner_c2", VAR_INT, &tuner_c2, 1, 0, 0 },
|
|
{ "tuner_t", VAR_INT, &tuner_t, 1, 0, 0 },
|
|
{ "tuner_c", VAR_INT, &tuner_c, 1, 0, 0 },
|
|
+ { "ad_axe_pktc", VAR_FUNCTION_INT64, (void *) &get_axe_pktc, 0, 0, 0 },
|
|
+ { "ad_axe_ccerr", VAR_FUNCTION_INT64, (void *) &get_axe_ccerr, 0, 0, 0 },
|
|
+ { "ad_axe_coax", VAR_FUNCTION_STRING, (void *) &get_axe_coax, 0, 0, 0 },
|
|
{ NULL, 0, NULL, 0, 0 } };
|
|
diff --git a/adapter.h b/adapter.h
|
|
index 72f61c8..e051bec 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
|
|
@@ -63,7 +67,7 @@ typedef struct struct_adapter
|
|
char enabled;
|
|
SMutex mutex;
|
|
char type; // available on the system
|
|
- int fe, dvr, dmx;
|
|
+ int fe, fe2, dvr, dmx;
|
|
int pa, fn;
|
|
// physical adapter, physical frontend number
|
|
fe_delivery_system_t sys[MAX_DELSYS];
|
|
@@ -86,6 +90,8 @@ typedef struct struct_adapter
|
|
uint16_t strength, snr, max_strength, max_snr;
|
|
uint32_t pid_err, dec_err; // detect pids received but not part of any stream, decrypt errors
|
|
diseqc diseqc_param;
|
|
+ int slave;
|
|
+ int axe_used;
|
|
int old_diseqc;
|
|
int old_hiband;
|
|
int old_pol;
|
|
@@ -101,6 +107,10 @@ typedef struct struct_adapter
|
|
Dvb_delsys delsys;
|
|
Device_signal get_signal;
|
|
Adapter_commit post_init, close;
|
|
+
|
|
+ int64_t axe_vdevice_last_sync;
|
|
+ int64_t axe_pktc;
|
|
+ int64_t axe_ccerr;
|
|
} adapter;
|
|
|
|
extern adapter *a[MAX_ADAPTERS];
|
|
@@ -123,6 +133,7 @@ int update_pids(int aid);
|
|
int tune(int aid, int sid);
|
|
SPid *find_pid(int aid, int p);
|
|
adapter * get_adapter1(int aid, char *file, int line);
|
|
+adapter * get_adapter21(int aid, char *file, int line);
|
|
char *describe_adapter(int sid, int aid, char *dad, int ld);
|
|
void dump_pids(int aid);
|
|
void sort_pids(int aid);
|
|
@@ -132,6 +143,9 @@ void set_diseqc_adapters(char *o);
|
|
void set_diseqc_timing(char *o);
|
|
void set_slave_adapters(char *o);
|
|
void set_adapter_dmxsource(char *o);
|
|
+void set_link_adapters(char *o);
|
|
+void set_absolute_src(char *o);
|
|
+void set_unicable_input(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);
|
|
@@ -145,6 +159,7 @@ void set_adapters_delsys(char *o);
|
|
int signal_thread(sockets *s);
|
|
|
|
#define get_adapter(a) get_adapter1(a, __FILE__, __LINE__)
|
|
+#define get_adapter2(a) get_adapter21(a, __FILE__, __LINE__)
|
|
#define get_adapter_nw(aid) ((aid >= 0 && aid < MAX_ADAPTERS && a[aid] && a[aid]->enabled)?a[aid]:NULL)
|
|
|
|
#define adapter_lock(a) adapter_lock1(__FILE__,__LINE__,a)
|
|
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 <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/configure b/configure
|
|
index 6aa1c64..1104eb5 100755
|
|
--- a/configure
|
|
+++ b/configure
|
|
@@ -662,6 +662,7 @@ infodir
|
|
docdir
|
|
oldincludedir
|
|
includedir
|
|
+runstatedir
|
|
localstatedir
|
|
sharedstatedir
|
|
sysconfdir
|
|
@@ -741,6 +742,7 @@ datadir='${datarootdir}'
|
|
sysconfdir='${prefix}/etc'
|
|
sharedstatedir='${prefix}/com'
|
|
localstatedir='${prefix}/var'
|
|
+runstatedir='${localstatedir}/run'
|
|
includedir='${prefix}/include'
|
|
oldincludedir='/usr/include'
|
|
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
|
@@ -993,6 +995,15 @@ do
|
|
| -silent | --silent | --silen | --sile | --sil)
|
|
silent=yes ;;
|
|
|
|
+ -runstatedir | --runstatedir | --runstatedi | --runstated \
|
|
+ | --runstate | --runstat | --runsta | --runst | --runs \
|
|
+ | --run | --ru | --r)
|
|
+ ac_prev=runstatedir ;;
|
|
+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
|
+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
|
+ | --run=* | --ru=* | --r=*)
|
|
+ runstatedir=$ac_optarg ;;
|
|
+
|
|
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
|
ac_prev=sbindir ;;
|
|
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
|
@@ -1130,7 +1141,7 @@ fi
|
|
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
|
datadir sysconfdir sharedstatedir localstatedir includedir \
|
|
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
|
- libdir localedir mandir
|
|
+ libdir localedir mandir runstatedir
|
|
do
|
|
eval ac_val=\$$ac_var
|
|
# Remove trailing slashes.
|
|
@@ -1283,6 +1294,7 @@ Fine tuning of the installation directories:
|
|
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
|
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
|
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
|
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
|
--libdir=DIR object code libraries [EPREFIX/lib]
|
|
--includedir=DIR C header files [PREFIX/include]
|
|
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
|
@@ -4040,19 +4052,19 @@ else
|
|
FM="$FM\n$openssl disabled"
|
|
fi
|
|
|
|
-
|
|
-for ac_header in execinfo.h
|
|
+{ $as_echo "$as_me:${as_lineno-$LINENO}: == Checking Embedded == " >&5
|
|
+$as_echo "$as_me: == Checking Embedded == " >&6;}
|
|
+for ac_func in backtrace
|
|
do :
|
|
- ac_fn_c_check_header_mongrel "$LINENO" "execinfo.h" "ac_cv_header_execinfo_h" "$ac_includes_default"
|
|
-if test "x$ac_cv_header_execinfo_h" = xyes; then :
|
|
+ ac_fn_c_check_func "$LINENO" "backtrace" "ac_cv_func_backtrace"
|
|
+if test "x$ac_cv_func_backtrace" = xyes; then :
|
|
cat >>confdefs.h <<_ACEOF
|
|
-#define HAVE_EXECINFO_H 1
|
|
+#define HAVE_BACKTRACE 1
|
|
_ACEOF
|
|
EMBEDDED=0
|
|
else
|
|
EMBEDDED=1
|
|
fi
|
|
-
|
|
done
|
|
|
|
if test "$EMBEDDED" = "1"; then
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 62cd966..2dbd51b 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -84,8 +84,8 @@ else
|
|
FM="$FM\n$openssl disabled"
|
|
fi
|
|
|
|
-
|
|
-AC_CHECK_HEADERS([execinfo.h],[EMBEDDED=0],[EMBEDDED=1])
|
|
+AC_MSG_NOTICE([ == Checking Embedded == ])
|
|
+AC_CHECK_FUNCS([backtrace],[EMBEDDED=0],[EMBEDDED=1])
|
|
if test "$EMBEDDED" = "1"; then
|
|
FM="$FM\n$emb enabled"
|
|
else
|
|
diff --git a/dvb.c b/dvb.c
|
|
index f7f8b0f..71ad4b9 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 };
|
|
@@ -329,25 +334,40 @@ 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);
|
|
+ if (ad->fe2 > 0)
|
|
+ ad->fe = ad->fe2;
|
|
+ else
|
|
+ ad->fe = ad->fe2 = open(buf, O_RDWR | O_NONBLOCK);
|
|
+ sprintf(buf, "/dev/axe/demuxts-%d", ad->pa);
|
|
+ ad->dvr = open(buf, O_RDONLY | O_NONBLOCK);
|
|
+#else
|
|
sprintf(buf, "/dev/dvb/adapter%d/frontend%d", ad->pa, ad->fn);
|
|
ad->fe = open(buf, O_RDWR | O_NONBLOCK);
|
|
sprintf(buf, "/dev/dvb/adapter%d/dvr%d", ad->pa, ad->fn);
|
|
ad->dvr = open(buf, O_RDONLY | O_NONBLOCK);
|
|
+#endif
|
|
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)
|
|
close(ad->fe);
|
|
if (ad->dvr >= 0)
|
|
close(ad->dvr);
|
|
- ad->fe = ad->dvr = -1;
|
|
+ ad->fe = ad->fe2 = ad->dvr = -1;
|
|
return 1;
|
|
}
|
|
ad->type = ADAPTER_DVB;
|
|
ad->dmx = -1;
|
|
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
|
|
@@ -369,7 +389,7 @@ int dvb_open_device(adapter *ad)
|
|
ad->dmx_source);
|
|
|
|
}
|
|
-
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
@@ -395,6 +415,46 @@ void diseqc_cmd(int fd, int times, char *str, struct dvb_diseqc_master_cmd *cmd,
|
|
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+void axe_wakeup(int fe_fd, int voltage)
|
|
+{
|
|
+ int i, mask;
|
|
+ adapter *a;
|
|
+ if (opts.axe_power < 2)
|
|
+ return;
|
|
+ for (i = 0; i < 4; i++) {
|
|
+ a = get_adapter(i);
|
|
+ if (a == NULL || is_adapter_disabled(i))
|
|
+ continue;
|
|
+ if (a->old_pol >= 0)
|
|
+ return;
|
|
+ }
|
|
+ LOG("AXE wakeup");
|
|
+ for (i = mask = 0; i < 4; i++) {
|
|
+ /* lowband enabled */
|
|
+ if (opts.quattro && opts.quattro_hiband == 1 && i < 2) {
|
|
+ mask = 3;
|
|
+ continue;
|
|
+ }
|
|
+ /* hiband enabled */
|
|
+ if (opts.quattro && opts.quattro_hiband == 2 && i >= 2) {
|
|
+ mask = 3<<2;
|
|
+ continue;
|
|
+ }
|
|
+ mask |= 1<<i;
|
|
+ }
|
|
+ for (i = 0; i < 4 && mask; i++) {
|
|
+ if (((1 << i) & mask) == 0)
|
|
+ continue;
|
|
+ a = get_adapter(i);
|
|
+ if (a == NULL || is_adapter_disabled(i))
|
|
+ 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 pos_change, int pol, int hiband, diseqc *d)
|
|
{
|
|
int committed_no = d->committed_no;
|
|
@@ -430,6 +490,9 @@ int send_diseqc(int fd, int pos, int pos_change, int pol, int hiband, diseqc *d)
|
|
LOGL(3, "send_diseqc fd %d, pos = %d (c %d u %d), pol = %d, hiband = %d",
|
|
fd, pos, posc, posu, pol, hiband);
|
|
|
|
+#ifdef AXE
|
|
+ axe_wakeup(fd, pol ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13);
|
|
+#endif
|
|
if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1)
|
|
LOG("send_diseqc: FE_SET_TONE failed for fd %d: %s", fd,
|
|
strerror(errno));
|
|
@@ -492,6 +555,9 @@ int send_unicable(int fd, int freq, int pos, int pol, int hiband, diseqc *d)
|
|
"send_unicable fd %d, freq %d, ufreq %d, pos = %d, pol = %d, hiband = %d, slot %d, diseqc => %02x %02x %02x %02x %02x",
|
|
fd, freq, d->ufreq, pos, pol, hiband, d->uslot, cmd.msg[0],
|
|
cmd.msg[1], cmd.msg[2], cmd.msg[3], cmd.msg[4]);
|
|
+#ifdef AXE
|
|
+ axe_wakeup(fd, 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));
|
|
@@ -524,7 +590,7 @@ int send_jess(int fd, int freq, int pos, int pol, int hiband, diseqc *d)
|
|
int t = freq - 100;
|
|
|
|
cmd.msg[1] = d->uslot << 3;
|
|
- cmd.msg[1] |= ((t << 8) & 0x07);
|
|
+ cmd.msg[1] |= ((t >> 8) & 0x07);
|
|
cmd.msg[2] = (t & 0xff);
|
|
cmd.msg[3] = ((pos & 0x3f) << 2) | (pol ? 2 : 0) | (hiband ? 1 : 0);
|
|
if (d->pin < 256)
|
|
@@ -539,6 +605,9 @@ int send_jess(int fd, int freq, int pos, int pol, int hiband, diseqc *d)
|
|
fd, freq, d->ufreq, pos, pol, hiband, d->uslot, cmd.msg[0],
|
|
cmd.msg[1], cmd.msg[2], cmd.msg[3], cmd.msg[4]);
|
|
|
|
+#ifdef AXE
|
|
+ axe_wakeup(fd, 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));
|
|
@@ -561,6 +630,55 @@ int send_jess(int fd, int freq, int pos, int pol, int hiband, diseqc *d)
|
|
return d->ufreq * 1000;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+static inline int extra_quattro(int input, int diseqc, int *equattro)
|
|
+{
|
|
+ if (diseqc <= 0)
|
|
+ *equattro = 0;
|
|
+ /* lowband allowed - control the hiband inputs independently for positions src=2+ */
|
|
+ else if (opts.quattro && opts.quattro_hiband == 1 && input < 2)
|
|
+ *equattro = diseqc;
|
|
+ /* hiband allowed - control the lowband inputs independently for positions src=2+ */
|
|
+ else if (opts.quattro && opts.quattro_hiband == 2 && input >= 2 && input < 4)
|
|
+ *equattro = diseqc;
|
|
+ else
|
|
+ *equattro = 0;
|
|
+ return *equattro;
|
|
+}
|
|
+
|
|
+adapter *use_adapter(int input)
|
|
+{
|
|
+ adapter *ad = input < 4 ? get_adapter2(input) : NULL;
|
|
+ char buf[32];
|
|
+ if (ad) {
|
|
+ if (ad->fe2 <= 0) {
|
|
+ sprintf (buf, "/dev/axe/frontend-%d", input);
|
|
+ ad->fe2 = open(buf, O_RDONLY | O_NONBLOCK);
|
|
+ LOG("adapter %d force open, fe2: %d", input, ad->fe2);
|
|
+ if (ad->fe2 < 0)
|
|
+ ad = NULL;
|
|
+ }
|
|
+ }
|
|
+ return ad;
|
|
+}
|
|
+
|
|
+int tune_check(adapter *ad, int pol, int hiband, int diseqc)
|
|
+{
|
|
+ LOGL(3, "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)
|
|
+ return 0;
|
|
+ if (ad->old_hiband != hiband)
|
|
+ return 0;
|
|
+ if (ad->old_diseqc != diseqc)
|
|
+ return 0;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+int absolute_switch;
|
|
+int absolute_table[32][4];
|
|
+#endif
|
|
+
|
|
int setup_switch(int frontend_fd, adapter *ad, transponder *tp)
|
|
{
|
|
int hiband = 0;
|
|
@@ -584,15 +702,145 @@ int setup_switch(int frontend_fd, adapter *ad, transponder *tp)
|
|
hiband = 1;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+ adapter *ad2, *adm;
|
|
+ int input = 0, src, aid, pos = 0, equattro = 0, master = -1;
|
|
+
|
|
+ if (tp->diseqc_param.switch_type != SWITCH_UNICABLE &&
|
|
+ tp->diseqc_param.switch_type != SWITCH_JESS) {
|
|
+ input = ad->id;
|
|
+ if (!opts.quattro || extra_quattro(input, diseqc, &equattro)) {
|
|
+ if (equattro > 0)
|
|
+ diseqc = equattro - 1;
|
|
+ if (absolute_switch && diseqc >= 0 && diseqc < 32) {
|
|
+ /* reuse input */
|
|
+ for (aid = 0; aid < 4; aid++) {
|
|
+ pos = absolute_table[diseqc][aid];
|
|
+ if (pos <= 0) continue;
|
|
+ pos--;
|
|
+ ad2 = get_adapter2(aid);
|
|
+ if (!ad2) continue;
|
|
+ if (ad2->fe2 <= 0) continue;
|
|
+ if ((ad2->axe_used & ~(1 << ad->id)) == 0) continue;
|
|
+ if (!tune_check(ad2, pol, hiband, pos)) continue;
|
|
+ break;
|
|
+ }
|
|
+ /* find free input */
|
|
+ if (aid >= 4) {
|
|
+ for (aid = 0; aid < 4; aid++) {
|
|
+ pos = absolute_table[diseqc][aid];
|
|
+ if (pos <= 0) continue;
|
|
+ pos--;
|
|
+ ad2 = get_adapter2(aid);
|
|
+ if (!ad2) continue;
|
|
+ LOGL(3, "axe: checking %d used 0x%x in %d", ad->id, ad2->axe_used, ad2->id);
|
|
+ if (ad2->axe_used & ~(1 << ad->id)) continue;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (aid >= 4) {
|
|
+ LOGL(0, "unable to find input for diseqc %d (absolute switch), adapter %d", diseqc, input);
|
|
+ return 0;
|
|
+ }
|
|
+ diseqc = pos;
|
|
+ master = aid;
|
|
+ adm = use_adapter(master);
|
|
+ if (adm == NULL) {
|
|
+ LOG("axe_fe: unknown master adapter for input %d", input);
|
|
+ return 0;
|
|
+ }
|
|
+ } else {
|
|
+ master = ad->slave ? ad->slave - 1 : ad->pa;
|
|
+ adm = use_adapter(master);
|
|
+ if (adm == NULL) {
|
|
+ LOG("axe_fe: unknown master adapter for input %d", input);
|
|
+ return 0;
|
|
+ }
|
|
+ if (adm->old_pol >= 0) {
|
|
+ for (aid = 0; aid < 4; aid++) {
|
|
+ ad2 = get_adapter2(aid);
|
|
+ if (!ad2 || ad2->fe2 <= 0 || 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 && !tune_check(adm, pol, hiband, diseqc)) {
|
|
+ LOGL(0, "unable to use slave adapter %d (master %d)", input, adm->pa);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ adm->axe_used |= (1 << ad->id);
|
|
+ if (master >= 0) {
|
|
+ input = master;
|
|
+ if (!tune_check(adm, pol, hiband, diseqc)) {
|
|
+ send_diseqc(adm->fe2, diseqc, adm->old_diseqc != diseqc,
|
|
+ pol, hiband, &tp->diseqc_param);
|
|
+ adm->old_pol = pol;
|
|
+ adm->old_hiband = hiband;
|
|
+ adm->old_diseqc = diseqc;
|
|
+ }
|
|
+ goto axe;
|
|
+ }
|
|
+ } else if (opts.quattro) {
|
|
+ if (opts.quattro_hiband == 1 && hiband) {
|
|
+ LOG("axe_fe: hiband is not allowed for quattro config (adapter %d)", input);
|
|
+ return 0;
|
|
+ }
|
|
+ if (opts.quattro_hiband == 2 && !hiband) {
|
|
+ LOG("axe_fe: lowband is not allowed for quattro config (adapter %d)", input);
|
|
+ return 0;
|
|
+ }
|
|
+ input = ((hiband ^ 1) << 1) | (pol ^ 1);
|
|
+ adm = use_adapter(input);
|
|
+ if (adm == NULL) {
|
|
+ LOG("axe_fe: unknown master adapter %d", input);
|
|
+ return 0;
|
|
+ }
|
|
+ adm->old_diseqc = diseqc = 0;
|
|
+ if(!tune_check(adm, pol, hiband, 0)) {
|
|
+ send_diseqc(adm->fe2, 0, 0, pol, hiband,
|
|
+ &tp->diseqc_param);
|
|
+ adm->old_pol = pol;
|
|
+ adm->old_hiband = hiband;
|
|
+ adm->old_diseqc = 0;
|
|
+ }
|
|
+ adm->axe_used |= (1 << ad->id);
|
|
+ goto axe;
|
|
+ }
|
|
+ } else {
|
|
+ aid = ad->id & 3;
|
|
+ input = opts.axe_unicinp[aid];
|
|
+ ad = use_adapter(input);
|
|
+ if (ad == NULL) {
|
|
+ LOGL(3, "axe setup: unable to find adapter %d", input);
|
|
+ return 0;
|
|
+ }
|
|
+ ad->axe_used |= (1 << aid);
|
|
+ }
|
|
+#endif
|
|
+
|
|
if (tp->diseqc_param.switch_type == SWITCH_UNICABLE)
|
|
{
|
|
- freq = send_unicable(frontend_fd, freq / 1000, diseqc, pol, hiband,
|
|
- &tp->diseqc_param);
|
|
+#ifdef AXE
|
|
+ if (ad)
|
|
+ freq = send_unicable(ad->fe2, freq / 1000, diseqc,
|
|
+ pol, hiband, &tp->diseqc_param);
|
|
+#else
|
|
+ freq = send_unicable(frontend_fd, freq / 1000, diseqc,
|
|
+ pol, hiband, &tp->diseqc_param);
|
|
+#endif
|
|
}
|
|
else if (tp->diseqc_param.switch_type == SWITCH_JESS)
|
|
{
|
|
- freq = send_jess(frontend_fd, freq / 1000, diseqc, pol, hiband,
|
|
- &tp->diseqc_param);
|
|
+#ifdef AXE
|
|
+ if (ad)
|
|
+ freq = send_jess(ad->fe2, freq / 1000, diseqc,
|
|
+ pol, hiband, &tp->diseqc_param);
|
|
+#else
|
|
+ freq = send_jess(frontend_fd, freq / 1000, diseqc,
|
|
+ pol, hiband, &tp->diseqc_param);
|
|
+#endif
|
|
}
|
|
else if (tp->diseqc_param.switch_type == SWITCH_SLAVE)
|
|
{
|
|
@@ -615,6 +863,23 @@ int setup_switch(int frontend_fd, adapter *ad, transponder *tp)
|
|
ad->old_hiband = hiband;
|
|
ad->old_diseqc = diseqc;
|
|
|
|
+#ifdef AXE
|
|
+axe:
|
|
+ for (aid = 0; aid < 4; aid++) {
|
|
+ ad2 = get_adapter2(aid);
|
|
+ if (ad2)
|
|
+ LOGL(3, "axe_fe: used[%d] = 0x%x, pol=%d, hiband=%d, diseqc=%d",
|
|
+ aid, ad2->axe_used, ad2->old_pol, ad2->old_hiband, ad2->old_diseqc);
|
|
+ }
|
|
+ LOGL(3, "axe_fe: reset for fd %d adapter %d input %d diseqc %d", frontend_fd, ad ? ad->pa : -1, input, diseqc);
|
|
+ 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
|
|
+
|
|
return freq;
|
|
}
|
|
|
|
@@ -647,6 +912,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,
|
|
@@ -666,8 +939,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
|
|
@@ -676,7 +951,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=%jd, ts pol=%jd",
|
|
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:
|
|
@@ -777,29 +1057,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;
|
|
}
|
|
|
|
@@ -825,10 +1122,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)
|
|
@@ -837,10 +1146,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;
|
|
|
|
@@ -929,6 +1248,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
|
|
|
|
}
|
|
|
|
@@ -1041,6 +1361,7 @@ void dvb_get_signal(adapter *ad)
|
|
ad->max_strength = (strength > 0) ? strength : 1;
|
|
if (ad->max_snr <= snr)
|
|
ad->max_snr = (snr > 0) ? snr : 1;
|
|
+#ifndef AXE
|
|
if (snr > 4096)
|
|
new_gs = 0;
|
|
if (new_gs)
|
|
@@ -1053,6 +1374,14 @@ void dvb_get_signal(adapter *ad)
|
|
strength = strength >> 8;
|
|
snr = snr >> 8;
|
|
}
|
|
+#else
|
|
+ strength = strength * 240 / 24000;
|
|
+ if (strength > 240)
|
|
+ strength = 240;
|
|
+ snr = snr * 15 / 54000;
|
|
+ if (snr > 15)
|
|
+ snr = 15;
|
|
+#endif
|
|
// keep the assignment at the end for the signal thread to get the right values as no locking is done on the adapter
|
|
ad->snr = snr;
|
|
ad->strength = strength;
|
|
@@ -1065,12 +1394,51 @@ void dvb_commit(adapter *a)
|
|
return;
|
|
}
|
|
|
|
-void dvb_close(adapter *a)
|
|
+int dvb_close(adapter *a2)
|
|
{
|
|
+#ifdef AXE
|
|
+ adapter *c;
|
|
+ int aid, busy;
|
|
+ if (a2->fe <= 0)
|
|
+ return;
|
|
+ a2->fe = -1;
|
|
+ if (a2->fe2 > 0)
|
|
+ axe_fe_reset(a2->fe2);
|
|
+ for (aid = busy = 0; aid < 4; aid++) {
|
|
+ c = a[aid];
|
|
+ c->axe_used &= ~(1 << a2->id);
|
|
+ if (c->axe_used || c->fe > 0) busy++;
|
|
+ }
|
|
+ if (busy > 0 && opts.axe_power > 1)
|
|
+ goto nostandby;
|
|
+ for (aid = 0; aid < 4; aid++) {
|
|
+ c = a[aid];
|
|
+ if (opts.axe_power < 2 && c != a2 && busy && c->sock >= 0)
|
|
+ continue;
|
|
+ if (c->axe_used != 0 || c->sid_cnt > 0) {
|
|
+ LOG("AXE standby: adapter %d busy (cnt=%d/used=%04x/fe=%d), keeping",
|
|
+ aid, c->sid_cnt, c->axe_used, c->fe);
|
|
+ continue;
|
|
+ }
|
|
+ if (c->fe2 < 0)
|
|
+ continue;
|
|
+ LOG("AXE standby: adapter %d", aid);
|
|
+ axe_fe_standby(c->fe2, -1);
|
|
+ axe_set_tuner_led(aid + 1, 0);
|
|
+ ioctl(c->fe2, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF);
|
|
+ close(c->fe2);
|
|
+ c->fe2 = -1;
|
|
+ c->old_diseqc = c->old_pol = c->old_hiband = -1;
|
|
+ }
|
|
+nostandby:
|
|
+ axe_set_tuner_led(a2->id + 1, 0);
|
|
+ return 0;
|
|
+#else
|
|
if (a->dmx >= 0)
|
|
close(a->dmx);
|
|
a->dmx = -1;
|
|
- return;
|
|
+#endif
|
|
+ return 0;
|
|
}
|
|
|
|
void find_dvb_adapter(adapter **a)
|
|
@@ -1081,9 +1449,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)
|
|
@@ -1091,7 +1471,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))
|
|
@@ -1122,6 +1503,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/dvbapi.c b/dvbapi.c
|
|
index bfa5ca1..77a448f 100644
|
|
--- a/dvbapi.c
|
|
+++ b/dvbapi.c
|
|
@@ -366,12 +366,14 @@ int dvbapi_reply(sockets * s)
|
|
{
|
|
int k_id, algo, mode;
|
|
SKey *k;
|
|
- pos += 13;
|
|
+ pos += 17;
|
|
k_id = b[4];
|
|
dvbapi_copy32r(algo, b, 5);
|
|
dvbapi_copy32r(mode, b, 9);
|
|
LOG("Key %d, Algo set to %d, Mode set to %d", k_id, algo, mode);
|
|
k = get_key(k_id);
|
|
+ if(!k)
|
|
+ break;
|
|
set_algo(k, algo, mode);
|
|
break;
|
|
}
|
|
@@ -396,6 +398,7 @@ SKey *get_active_key(SPid *p)
|
|
SKey *k;
|
|
adapter *ad;
|
|
int key = p->key;
|
|
+ int counter = 0;
|
|
int64_t ctime = getTick();
|
|
uint8_t nullcw[16] =
|
|
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
@@ -413,7 +416,7 @@ SKey *get_active_key(SPid *p)
|
|
LOGL(3,
|
|
"get_active_key: searching key for pid %d, starting key %d parity %d ok %d %d",
|
|
p->pid, key, k->parity, k->key_ok[0], k->key_ok[1]);
|
|
- while (k && k->enabled)
|
|
+ while (k && k->enabled && (counter ++ < 10))
|
|
{
|
|
if ((k->parity != -1) && k->key_ok[k->parity]
|
|
&& (ctime - k->cw_time[k->parity] > MAX_KEY_TIME)) // key expired
|
|
@@ -975,7 +978,6 @@ int keys_del(int i)
|
|
enabledKeys = ek;
|
|
if (!ek && sock > 0)
|
|
TEST_WRITE(write(sock, buf, sizeof(buf)));
|
|
- mutex_destroy(&k->mutex);
|
|
return 0;
|
|
}
|
|
|
|
@@ -1069,6 +1071,18 @@ void dvbapi_delete_keys_for_adapter(int aid)
|
|
keys_del(i);
|
|
}
|
|
|
|
+void free_all_keys(void)
|
|
+{
|
|
+ SKey *k;
|
|
+ for (i = 0; i < MAX_KEYS; i++) {
|
|
+ if (key[i]) {
|
|
+ mutex_destroy(&key[i]->mutex);
|
|
+ free(key[i]);
|
|
+ }
|
|
+ }
|
|
+ mutex_destroy(&keys_mutex);
|
|
+}
|
|
+
|
|
_symbols dvbapi_sym[] =
|
|
{
|
|
{ "key_enabled", VAR_AARRAY_INT8, keys, 1, MAX_KEYS, offsetof(SKey, enabled) },
|
|
diff --git a/dvbapi.h b/dvbapi.h
|
|
index 6c45650..69f1f37 100644
|
|
--- a/dvbapi.h
|
|
+++ b/dvbapi.h
|
|
@@ -124,5 +124,7 @@ void unregister_dvbapi();
|
|
void send_client_info(sockets *s);
|
|
int set_algo(SKey *k, int algo, int mode);
|
|
|
|
+void free_all_keys();
|
|
+
|
|
#endif
|
|
#endif
|
|
diff --git a/html/status.html b/html/status.html
|
|
index cd000e5..3b0c289 100644
|
|
--- a/html/status.html
|
|
+++ b/html/status.html
|
|
@@ -83,6 +83,9 @@ var ad_phyfd = [$ad_phyfd0$, $ad_phyfd1$, $ad_phyfd2$, $ad_phyfd3$, $ad_phyfd4$,
|
|
var ad_allsys = ["$ad_allsys0$", "$ad_allsys1$", "$ad_allsys2$", "$ad_allsys3$", "$ad_allsys4$", "$ad_allsys5$", "$ad_allsys6$", "$ad_allsys7$", "$ad_allsys8$", "$ad_allsys9$", "$ad_allsys10$", "$ad_allsys11$", "$ad_allsys12$", "$ad_allsys13$", "$ad_allsys14$", "$ad_allsys15$" ];
|
|
var ad_pids = ["$ad_pids0$", "$ad_pids1$", "$ad_pids2$", "$ad_pids3$", "$ad_pids4$", "$ad_pids5$", "$ad_pids6$", "$ad_pids7$", "$ad_pids8$", "$ad_pids9$", "$ad_pids10$", "$ad_pids11$", "$ad_pids12$", "$ad_pids13$", "$ad_pids14$", "$ad_pids15$" ];
|
|
var ad_satip = ["$ad_satip0$", "$ad_satip1$", "$ad_satip2$", "$ad_satip3$", "$ad_satip4$", "$ad_satip5$", "$ad_satip6$", "$ad_satip7$", "$ad_satip8$", "$ad_satip9$", "$ad_satip10$", "$ad_satip11$", "$ad_satip12$", "$ad_satip13$", "$ad_satip14$", "$ad_satip15$" ];
|
|
+var ad_axe_pktc = [$ad_axe_pktc0$, $ad_axe_pktc1$, $ad_axe_pktc2$, $ad_axe_pktc3$];
|
|
+var ad_axe_ccerr = [$ad_axe_ccerr0$, $ad_axe_ccerr1$, $ad_axe_ccerr2$, $ad_axe_ccerr3$];
|
|
+var ad_axe_coax = ["$ad_axe_coax0$", "$ad_axe_coax1$", "$ad_axe_coax2$", "$ad_axe_coax3$"];
|
|
var st_enabled = [$st_enabled0$, $st_enabled1$, $st_enabled2$, $st_enabled3$, $st_enabled4$, $st_enabled5$, $st_enabled6$, $st_enabled7$, $st_enabled8$, $st_enabled9$, $st_enabled10$, $st_enabled11$, $st_enabled12$, $st_enabled13$, $st_enabled14$, $st_enabled15$ ];
|
|
var st_adapter = [$st_adapter0$, $st_adapter1$, $st_adapter2$, $st_adapter3$, $st_adapter4$, $st_adapter5$, $st_adapter6$, $st_adapter7$, $st_adapter8$, $st_adapter9$, $st_adapter10$, $st_adapter11$, $st_adapter12$, $st_adapter13$, $st_adapter14$, $st_adapter15$ ];
|
|
var st_rport = [$st_rport0$, $st_rport1$, $st_rport2$, $st_rport3$, $st_rport4$, $st_rport5$, $st_rport6$, $st_rport7$, $st_rport8$, $st_rport9$, $st_rport10$, $st_rport11$, $st_rport12$, $st_rport13$, $st_rport14$, $st_rport15$ ];
|
|
@@ -112,6 +115,9 @@ myTable += "<th class=''>Status</th>";
|
|
myTable += "<th class='dt-right'>Frequency</th>";
|
|
myTable += "<th class='dt-right'>SR/BW</th>";
|
|
myTable += "<th class='dt-right'>Signal</th>";
|
|
+myTable += "<th class='dt-right'>Packets</th>";
|
|
+myTable += "<th class='dt-right'>CC Errors</th>";
|
|
+myTable += "<th class='dt-right'>Coax Cable</th>";
|
|
myTable += "<th class='dt-left'>Streams</th>";
|
|
myTable += "<th class='dt-left'>Cryptinfo</th>";
|
|
myTable += "</tr></thead><tbody>";
|
|
@@ -173,6 +179,9 @@ for (var i = 0; i < max_adapters; i++) {
|
|
signal += "<div class='level'>BER <div class='pBar' data-from='"+ ad_ber[i] + "' data-to='" + ad_ber[i] + "' data-color='red'></div> " + ad_ber[i] + "</div><br />";
|
|
}
|
|
myTable += "<td class='dt-right'>" + signal + " </td>";
|
|
+ myTable += "<td class='dt-right'>" + ad_axe_pktc[i] + " </td>";
|
|
+ myTable += "<td class='dt-right'>" + ad_axe_ccerr[i] + " </td>";
|
|
+ myTable += "<td class='dt-right'>" + ad_axe_coax[i] + " </td>";
|
|
|
|
// STREAMS
|
|
myTable += "<td class='dt-left'>";
|
|
diff --git a/minisatip.c b/minisatip.c
|
|
index 6402f64..a21f267 100644
|
|
--- a/minisatip.c
|
|
+++ b/minisatip.c
|
|
@@ -72,6 +72,7 @@ static const struct option long_options[] =
|
|
#endif
|
|
#ifndef DISABLE_SATIPCLIENT
|
|
{ "satip-servers", required_argument, NULL, 's' },
|
|
+ { "satip-tcp", no_argument, NULL, 'O' },
|
|
#endif
|
|
#ifndef DISABLE_NETCVCLIENT
|
|
{ "netceiver", required_argument, NULL, 'n' },
|
|
@@ -88,6 +89,14 @@ 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' },
|
|
+ { "free-inputs", required_argument, NULL, 'A' },
|
|
+ { "quattro", no_argument, NULL, 'Q' },
|
|
+ { "quattro-hiband", required_argument, NULL, 'Z' },
|
|
+ { "axe-uinput", required_argument, NULL, 'U' },
|
|
+ { "skip-mpegts", required_argument, NULL, 'M' },
|
|
+#endif
|
|
{ 0, 0, 0, 0 } };
|
|
|
|
#define RRTP_OPT 'r'
|
|
@@ -116,11 +125,19 @@ static const struct option long_options[] =
|
|
#define SATIPCLIENT_OPT 's'
|
|
#define NETCVCLIENT_OPT 'n'
|
|
#define PRIORITY_OPT 'i'
|
|
-#define PRIORITY_OPT 'i'
|
|
+#define SATIP_TCP_OPT 'O'
|
|
#define DOCUMENTROOT_OPT 'R'
|
|
#define XML_OPT 'X'
|
|
#define THREADS_OPT 'T'
|
|
#define DMXSOURCE_OPT '9'
|
|
+#define LINK_OPT 'L'
|
|
+#define QUATTRO_OPT 'Q'
|
|
+#define QUATTRO_HIBAND_OPT 'Z'
|
|
+#define AXE_UNICINP_OPT 'U'
|
|
+#define AXE_SKIP_PKT 'M'
|
|
+#define AXE_POWER 'P'
|
|
+#define ABSOLUTE_SRC 'A'
|
|
+
|
|
|
|
char *built_info[] =
|
|
{
|
|
@@ -129,6 +146,11 @@ char *built_info[] =
|
|
#else
|
|
"Built with dvbcsa",
|
|
#endif
|
|
+#ifdef DISABLE_DVBCA
|
|
+ "Built without CI",
|
|
+#else
|
|
+ "Built with CI",
|
|
+#endif
|
|
#ifdef DISABLE_DVBAPI
|
|
"Built without dvbapi",
|
|
#else
|
|
@@ -171,8 +193,11 @@ void print_version(int use_log)
|
|
char buf[200];
|
|
int i, len = 0;
|
|
memset(buf, 0, sizeof(buf));
|
|
- len += sprintf(buf, "%s version %s, compiled with s2api version: %04X",
|
|
- app_name, version, LOGDVBAPIVERSION);
|
|
+ len += sprintf(buf, "%s version %s, compiled with s2api version: %04X"
|
|
+#ifdef AXE
|
|
+ " (AXE)"
|
|
+#endif
|
|
+ , app_name, version, LOGDVBAPIVERSION);
|
|
if (!use_log)
|
|
puts(buf);
|
|
else
|
|
@@ -185,7 +210,7 @@ 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\
|
|
+ "\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[-[uj] A1:S1-F1[-PIN]] [-m mac]"
|
|
#ifndef DISABLE_DVBAPI
|
|
"[-o oscam_host:dvbapi_port] "
|
|
@@ -196,7 +221,8 @@ void usage()
|
|
"[-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] \n\n\
|
|
+ \t[-x http_port] [-X xml_path] [-y rtsp_port] [-L M1:S1[,M2:S2]] [-U unicable_adapter] \n\
|
|
+ \t[-M mpegts_packets] [-A SRC1:INP1:DISEQC1[,SRC2:INP2:DISEQC2]]\n\n\
|
|
Help\n\
|
|
-------\n\
|
|
\n\
|
|
@@ -286,6 +312,7 @@ 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\
|
|
+* -O --satip-tcp Use RTSP over TCP instead of UDP for data transport \n\
|
|
"
|
|
#endif
|
|
"\
|
|
@@ -322,7 +349,38 @@ Help\n\
|
|
* eg: -y 5544 \n\
|
|
- changing this to a port > 1024 removes the requirement for minisatip to run as root\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\
|
|
+* -A --free-inputs mapping_string: absolute source mapping for free input mode\n\
|
|
+\t* The format is: SRC1:INP1:DISEQC1[,SRC2:INP2:DISEQC2]\n\
|
|
+ * SRC: source number (src argument for SAT>IP minus 1 - 0-15)\n\
|
|
+ * INP: coaxial input (0-3)\n\
|
|
+ * DISEQC: diseqc position (0-15)\n\
|
|
+ * eg: 13E,19.2E on inputs 0&1 and 23.5E,28.2E on inputs 2&3:\n\
|
|
+ -A 0:0:0,0:1:0,1:0:0,1:1:1,2:2:0,2:3:0,3:2:1,3:2:2\n\
|
|
+\n\
|
|
+* -P --power num: power to all inputs (0 = only active inputs, 1 = all inputs)\n\
|
|
+\n\
|
|
+* -Q --quattro quattro LNB config (H/H,H/V,L/H,L/V)\n\
|
|
+\n\
|
|
+* -Z --quattro-hiband hiband\n\
|
|
+ * if hiband is 0, do not allow hiband\n\
|
|
+ * if hiband is 1, allow hiband\n\
|
|
+\n\
|
|
+* -U --axe-uinput adapterno[,adapterno2]: AXE unicable/jess input (0-3)\n\
|
|
+ * eg: 0,0,2,2 (two unicable connections at inputs 0 and 2)\n\
|
|
+ * (tuners 0,1: unicable input 0, tuners 2,3: unicable input 2)\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");
|
|
@@ -360,11 +418,12 @@ void set_options(int argc, char *argv[])
|
|
opts.clean_psi = 0;
|
|
opts.satip_addpids = 1;
|
|
opts.satip_setup_pids = 0;
|
|
+ opts.satip_rtsp_over_tcp = 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.no_threads = 1;
|
|
opts.th_priority = -1;
|
|
opts.diseqc_before_cmd = 15;
|
|
opts.diseqc_after_cmd = 54;
|
|
@@ -376,10 +435,11 @@ void set_options(int argc, char *argv[])
|
|
#ifdef NO_BACKTRACE
|
|
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:q:D:VR:S:TX:Y:",
|
|
+ "flr:a:td:w:p:s:n:hc:b:m:p:e:x:u:j:o:gy:i:q:D:VR:S:TX:Y:OL:QZ:U:M:P:A:",
|
|
long_options, NULL)) != -1)
|
|
{
|
|
// printf("options %d %c %s\n",opt,opt,optarg);
|
|
@@ -451,9 +511,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;
|
|
}
|
|
|
|
@@ -567,6 +630,15 @@ void set_options(int argc, char *argv[])
|
|
|
|
break;
|
|
|
|
+ case SATIP_TCP_OPT:
|
|
+#ifdef DISABLE_SATIPCLIENT
|
|
+ LOGL(0, "%s was not compiled with satip client support, please change the Makefile", app_name);
|
|
+ exit (0);
|
|
+
|
|
+#endif
|
|
+ opts.satip_rtsp_over_tcp = 1;
|
|
+ break;
|
|
+
|
|
case NETCVCLIENT_OPT:
|
|
{
|
|
#ifdef DISABLE_NETCVCLIENT
|
|
@@ -612,6 +684,39 @@ 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 ABSOLUTE_SRC:
|
|
+ set_absolute_src(optarg);
|
|
+ break;
|
|
+
|
|
+ case QUATTRO_OPT:
|
|
+ opts.quattro = 1;
|
|
+ break;
|
|
+
|
|
+ case QUATTRO_HIBAND_OPT:
|
|
+ opts.quattro_hiband = atoi(optarg) + 1;
|
|
+ break;
|
|
+
|
|
+ case AXE_UNICINP_OPT:
|
|
+ set_unicable_input(optarg);
|
|
+ break;
|
|
+
|
|
+ case AXE_POWER:
|
|
+ opts.axe_power = atoi(optarg) + 1;
|
|
+ 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
|
|
}
|
|
|
|
}
|
|
@@ -880,6 +985,9 @@ int read_http(sockets * s)
|
|
{
|
|
char *arg[50];
|
|
char buf[2000]; // the XML should not be larger than 1400 as it will create problems
|
|
+ char url[300];
|
|
+ char *space;
|
|
+ int is_head = 0;
|
|
static char *xml =
|
|
"<?xml version=\"1.0\"?>"
|
|
"<root xmlns=\"urn:schemas-upnp-org:device-1-0\" configId=\"0\">"
|
|
@@ -916,14 +1024,35 @@ int read_http(sockets * s)
|
|
s->flags = s->flags | 1;
|
|
return 0;
|
|
}
|
|
+ url[0] = 0;
|
|
+ space = strchr(s->buf, ' ');
|
|
+ if(space)
|
|
+ {
|
|
+ int i = 0;
|
|
+ space++;
|
|
+ while( space[i] && space[i] != ' ')
|
|
+ {
|
|
+ url[i] = space[i];
|
|
+ if( i++ > sizeof(url) - 3)
|
|
+ break;
|
|
+ }
|
|
+ url[i] = 0;
|
|
+ }
|
|
|
|
- if (strncasecmp((const char*) s->buf, "GET ", 4) == 0
|
|
- && strstr((const char*) s->buf, "/?"))
|
|
+ if (strstr(url, "/?") && !strncasecmp((const char*) s->buf, "GET ", 4))
|
|
{
|
|
- read_rtsp(s);
|
|
- return 0;
|
|
+ read_rtsp(s);
|
|
+ return 0;
|
|
}
|
|
|
|
+ if(!strncasecmp((const char*) s->buf, "HEAD ", 5))
|
|
+ is_head = 1;
|
|
+
|
|
+ if (is_head && strstr(url, "/?"))
|
|
+ {
|
|
+ http_response(s, 200, NULL, NULL, 0, 0);
|
|
+ return 0;
|
|
+ }
|
|
s->rlen = 0;
|
|
|
|
LOG("read HTTP from %d sid: %d: ", s->sock, s->sid);
|
|
@@ -931,7 +1060,7 @@ int read_http(sockets * s)
|
|
|
|
split(arg, (char*) s->buf, 50, ' ');
|
|
// LOG("args: %s -> %s -> %s",arg[0],arg[1],arg[2]);
|
|
- if (strncmp(arg[0], "GET", 3) != 0)
|
|
+ if (strncmp(arg[0], "GET", 3) && !is_head)
|
|
REPLY_AND_RETURN(503);
|
|
if (uuidi == 0)
|
|
ssdp_discovery(s);
|
|
@@ -943,7 +1072,7 @@ int read_http(sockets * s)
|
|
extern int tuner_s2, tuner_t, tuner_c, tuner_t2, tuner_c2;
|
|
char adapters[400];
|
|
char headers[500];
|
|
-
|
|
+
|
|
memset(adapters, 0, sizeof(adapters));
|
|
if (tuner_s2)
|
|
sprintf(adapters, "DVBS2-%d,", tuner_s2);
|
|
@@ -983,6 +1112,11 @@ int read_http(sockets * s)
|
|
http_response(s, 404, NULL, NULL, 0, 0);
|
|
return 0;
|
|
}
|
|
+ if(is_head)
|
|
+ {
|
|
+ http_response(s, 200, ctype, NULL, 0, 0);
|
|
+ return 0;
|
|
+ }
|
|
if (strstr(ctype, "image") || strstr(ctype, "css")
|
|
|| strstr(ctype, "javascript"))
|
|
{
|
|
@@ -1051,7 +1185,7 @@ int ssdp_discovery(sockets * s)
|
|
if (s->type != TYPE_UDP)
|
|
return 0;
|
|
|
|
- LOG("ssdp_discovery: bootid: %d deviceid: %d http: %s", opts.bootid,
|
|
+ LOGL(3, "ssdp_discovery: bootid: %d deviceid: %d http: %s", opts.bootid,
|
|
opts.device_id, opts.http_host);
|
|
|
|
for (i = 0; i < 3; i++)
|
|
@@ -1060,7 +1194,7 @@ int ssdp_discovery(sockets * s)
|
|
nt[i] + 2, app_name, version, uuid, i == 1 ? "" : nt[i],
|
|
opts.bootid, opts.device_id);
|
|
salen = sizeof(ssdp_sa);
|
|
- LOGL(3, "Discovery packet %d:\n%s", i + 1, buf);
|
|
+ LOGL(5, "Discovery packet %d:\n%s", i + 1, buf);
|
|
sendto(s->sock, buf, strlen(buf), MSG_NOSIGNAL,
|
|
(const struct sockaddr *) &ssdp_sa, salen);
|
|
}
|
|
@@ -1102,17 +1236,20 @@ int ssdp_reply(sockets * s)
|
|
ruuid = strcasestr((const char *) s->buf, "uuid:");
|
|
if (ruuid && strncmp(uuid, strip(ruuid + 5), strlen(uuid)) == 0)
|
|
{
|
|
- LOGL(3, "Dropping packet from the same UUID as mine (from %s:%d)",
|
|
+ LOGL(5, "Dropping packet from the same UUID as mine (from %s:%d)",
|
|
get_socket_rhost(s->id, ra, sizeof(ra)),
|
|
get_socket_rport(s->id));
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef AXE
|
|
+ axe_set_network_led(1);
|
|
+#endif
|
|
// not my uuid
|
|
- LOG("Received SSDP packet from %s:%d -> handle %d",
|
|
+ LOGL(4, "Received SSDP packet from %s:%d -> handle %d",
|
|
get_socket_rhost(s->id, ra, sizeof(ra)), get_socket_rport(s->id),
|
|
s->sock);
|
|
- LOGL(3, "%s", s->buf);
|
|
+ LOGL(5, "%s", s->buf);
|
|
|
|
if (strncasecmp((const char *) s->buf, "NOTIFY", 6) == 0)
|
|
{
|
|
@@ -1156,11 +1293,11 @@ int ssdp_reply(sockets * s)
|
|
sprintf(buf, reply, get_current_timestamp(), opts.http_host, opts.xml_path,
|
|
app_name, version, uuid, opts.bootid, did);
|
|
|
|
- LOG("ssdp_reply fd: %d -> %s:%d, bootid: %d deviceid: %d http: %s", ssdp,
|
|
+ LOGL(5, "ssdp_reply fd: %d -> %s:%d, bootid: %d deviceid: %d http: %s", ssdp,
|
|
get_socket_rhost(s->id, ra, sizeof(ra)), get_socket_rport(s->id),
|
|
opts.bootid, did, opts.http_host);
|
|
//use ssdp (unicast) even if received to multicast address
|
|
- LOGL(3, "%s", buf);
|
|
+ LOGL(5, "%s", buf);
|
|
sendto(ssdp, buf, strlen(buf), MSG_NOSIGNAL,
|
|
(const struct sockaddr *) &s->sa, salen);
|
|
return 0;
|
|
@@ -1243,7 +1380,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 8194eb2..984c6f7
|
|
--- a/minisatip.h
|
|
+++ b/minisatip.h
|
|
@@ -8,9 +8,9 @@
|
|
#include "utils.h"
|
|
|
|
|
|
-#define VERSION_BUILD "43"
|
|
+#define VERSION_BUILD "49"
|
|
#define CC(a,b,c) #a b #c
|
|
-#define VERSION CC(0.5.,VERSION_BUILD,)
|
|
+#define VERSION CC(0.5.,VERSION_BUILD,-axe102)
|
|
|
|
void set_options (int argc, char *argv[]);
|
|
|
|
@@ -53,12 +53,17 @@ struct struct_opts
|
|
int force_scan;
|
|
int clean_psi;
|
|
int file_line;
|
|
+ int quattro;
|
|
+ int quattro_hiband;
|
|
+ int axe_unicinp[4];
|
|
+ int axe_skippkt;
|
|
+ int axe_power;
|
|
char *last_log;
|
|
int dvbapi_port;
|
|
char *dvbapi_host;
|
|
int drop_encrypted;
|
|
int rtsp_port;
|
|
- uint8_t satip_addpids, satip_setup_pids;
|
|
+ uint8_t satip_addpids, satip_setup_pids, satip_rtsp_over_tcp;
|
|
uint8_t netcv_count;
|
|
char *netcv_if;
|
|
char playlist[200];
|
|
diff --git a/satipc.c b/satipc.c
|
|
index a7dfef4..404bfb8 100644
|
|
--- a/satipc.c
|
|
+++ b/satipc.c
|
|
@@ -17,6 +17,7 @@
|
|
* USA
|
|
*
|
|
*/
|
|
+#define _GNU_SOURCE
|
|
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
@@ -37,13 +38,15 @@
|
|
#include <net/if.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
-#include <string.h>
|
|
+#include "utils.h"
|
|
#include "dvbapi.h"
|
|
#include "satipc.h"
|
|
#include "ca.h"
|
|
#include "minisatip.h"
|
|
#include "dvb.h"
|
|
|
|
+#define TCP_DATA_SIZE ((ADAPTER_BUFFER/1316)*(1316+16))
|
|
+
|
|
extern char *fe_delsys[];
|
|
extern struct struct_opts opts;
|
|
|
|
@@ -65,11 +68,13 @@ typedef struct struct_satipc
|
|
int wp, qp; // written packet, queued packet
|
|
char ignore_packets; // ignore packets coming from satip server while tuning
|
|
char satip_fe, last_cmd;
|
|
+ char use_tcp;
|
|
char expect_reply, force_commit, want_commit, want_tune, sent_transport;
|
|
int64_t last_setup, last_connect;
|
|
uint8_t addpids, setup_pids;
|
|
+ unsigned char *tcp_data;
|
|
+ int tcp_size, tcp_pos, tcp_len;
|
|
char use_fe;
|
|
-
|
|
uint32_t rcvp, repno, rtp_miss, rtp_ooo; // rtp statstics
|
|
uint16_t rtp_seq;
|
|
|
|
@@ -210,6 +215,10 @@ int satipc_reply(sockets * s)
|
|
{
|
|
satipc_commit(ad);
|
|
}
|
|
+
|
|
+ if (!sip->expect_reply && sip->last_cmd == RTSP_PLAY)
|
|
+ http_request(ad, NULL, "DESCRIBE");
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -223,10 +232,7 @@ int satipc_timeout(sockets *s)
|
|
ad?sip->sip:NULL, ad ? sip->sport : 0, s->sid, s->id, s->sock,
|
|
s->timeout_ms);
|
|
|
|
- if (sip->last_cmd == RTSP_PLAY)
|
|
- http_request(ad, NULL, "DESCRIBE");
|
|
- else
|
|
- http_request(ad, NULL, "OPTIONS");
|
|
+ http_request(ad, NULL, "OPTIONS");
|
|
|
|
s->rtime = getTick();
|
|
return 0;
|
|
@@ -284,7 +290,7 @@ int satipc_rtcp_reply(sockets * s)
|
|
{
|
|
copy32r(rp, b, 20);
|
|
|
|
- if ((++sip->repno % 100) == 0) //every 20s
|
|
+ if (!sip->use_tcp && ((++sip->repno % 100) == 0)) //every 20s
|
|
LOG(
|
|
"satipc: rtp report, adapter %d: rtcp missing packets %d, rtp missing %d, rtp ooo %d, pid err %d",
|
|
ad->id, rp - sip->rcvp, sip->rtp_miss, sip->rtp_ooo,
|
|
@@ -309,34 +315,47 @@ int satipc_open_device(adapter *ad)
|
|
if (ad->fe < 0)
|
|
return 2;
|
|
|
|
- LOG("satipc: connected to SAT>IP server %s port %d, handle %d", sip->sip,
|
|
- sip->sport, ad->fe);
|
|
- sip->listen_rtp = opts.start_rtp + 1000 + ad->id * 2;
|
|
- ad->dvr = udp_bind(NULL, sip->listen_rtp);
|
|
- sip->rtcp = udp_bind(NULL, sip->listen_rtp + 1);
|
|
-
|
|
- ad->fe_sock = sockets_add(ad->fe, NULL, ad->id, TYPE_TCP,
|
|
- (socket_action) satipc_reply, (socket_action) satipc_close,
|
|
- (socket_action) satipc_timeout);
|
|
- sip->rtcp_sock = sockets_add(sip->rtcp, NULL, ad->id, TYPE_TCP,
|
|
- (socket_action) satipc_rtcp_reply, (socket_action) satipc_close,
|
|
- NULL);
|
|
- sockets_timeout(ad->fe_sock, 30000); // 30s
|
|
- set_socket_receive_buffer(ad->dvr, opts.dvr_buffer);
|
|
- if (ad->fe_sock < 0 || ad->dvr < 0 || sip->rtcp < 0 || sip->rtcp_sock < 0)
|
|
+ LOG("satipc: connected to SAT>IP server %s port %d %s handle %d", sip->sip,
|
|
+ sip->sport, sip->use_tcp ? "[RTSP OVER TCP]" : "", ad->fe);
|
|
+ if (!sip->use_tcp)
|
|
{
|
|
- sockets_del(sip->rtcp_sock);
|
|
- sockets_del(ad->fe_sock);
|
|
- close(sip->rtcp);
|
|
- close(ad->dvr);
|
|
- close(ad->fe);
|
|
+ sip->listen_rtp = opts.start_rtp + 1000 + ad->id * 2;
|
|
+ ad->dvr = udp_bind(NULL, sip->listen_rtp);
|
|
+ sip->rtcp = udp_bind(NULL, sip->listen_rtp + 1);
|
|
+
|
|
+ ad->fe_sock = sockets_add(ad->fe, NULL, ad->id, TYPE_TCP,
|
|
+ (socket_action) satipc_reply, (socket_action) satipc_close,
|
|
+ (socket_action) satipc_timeout);
|
|
+ sip->rtcp_sock = sockets_add(sip->rtcp, NULL, ad->id, TYPE_TCP,
|
|
+ (socket_action) satipc_rtcp_reply, (socket_action) satipc_close,
|
|
+ NULL);
|
|
+ sockets_timeout(ad->fe_sock, 30000); // 30s
|
|
+ set_socket_receive_buffer(ad->dvr, opts.dvr_buffer);
|
|
+ if (ad->fe_sock < 0 || ad->dvr < 0 || sip->rtcp < 0
|
|
+ || sip->rtcp_sock < 0)
|
|
+ {
|
|
+ sockets_del(sip->rtcp_sock);
|
|
+ sockets_del(ad->fe_sock);
|
|
+ close(sip->rtcp);
|
|
+ close(ad->dvr);
|
|
+ close(ad->fe);
|
|
+ }
|
|
}
|
|
+ else
|
|
+ {
|
|
+ ad->dvr = ad->fe;
|
|
+ ad->fe = -1;
|
|
+ ad->fe_sock = sockets_add(SOCK_TIMEOUT, NULL, ad->id, TYPE_UDP,
|
|
+ NULL, NULL, (socket_action) satipc_timeout);
|
|
+ sockets_timeout(ad->fe_sock, 30000); // 30s
|
|
|
|
+ }
|
|
sip->session[0] = 0;
|
|
sip->lap = 0;
|
|
sip->ldp = 0;
|
|
sip->cseq = 1;
|
|
sip->err = 0;
|
|
+ sip->tcp_pos = sip->tcp_len = 0;
|
|
sip->expect_reply = 0;
|
|
sip->last_connect = 0;
|
|
sip->sent_transport = 0;
|
|
@@ -412,13 +431,170 @@ int satipc_read(int socket, void *buf, int len, sockets *ss, int *rb)
|
|
return (*rb >= 0);
|
|
}
|
|
|
|
+int process_rtsp_tcp(sockets *ss, unsigned char *rtsp, int rtsp_len, void *buf,
|
|
+ int len)
|
|
+{
|
|
+ int nl = 0;
|
|
+ unsigned char tmp_char;
|
|
+ satipc *sip = get_satip(ss->sid);
|
|
+ adapter *ad = get_adapter(ss->sid);
|
|
+ if (!ad || !sip)
|
|
+ return 0;
|
|
+
|
|
+ if (sip->ignore_packets)
|
|
+ return 0;
|
|
+
|
|
+ if (rtsp[1] == 1)
|
|
+ {
|
|
+ tmp_char = rtsp[rtsp_len + 4];
|
|
+ rtsp[rtsp_len + 4] = 0;
|
|
+ set_adapter_signal(ad, rtsp + 4, rtsp_len);
|
|
+ rtsp[rtsp_len + 4] = tmp_char;
|
|
+ return 0;
|
|
+ }
|
|
+ else if (rtsp[1] == 0)
|
|
+ {
|
|
+ nl = rtsp_len - 12;
|
|
+ if (nl > len)
|
|
+ nl = len;
|
|
+
|
|
+ if (nl > 0)
|
|
+ memcpy(buf, rtsp + 16, nl);
|
|
+
|
|
+ }
|
|
+ else
|
|
+ LOG("Not processing packet as the type is %02X (not 0 or 1)", rtsp[1]);
|
|
+
|
|
+ return nl;
|
|
+}
|
|
+
|
|
+int satipc_tcp_read(int socket, void *buf, int len, sockets *ss, int *rb)
|
|
+{
|
|
+ unsigned char *rtsp;
|
|
+ sockets tmp_sock;
|
|
+ uint16_t seq;
|
|
+ static int iter;
|
|
+ int pos;
|
|
+ int rtsp_len;
|
|
+ int tmp_len;
|
|
+ adapter *ad;
|
|
+ satipc *sip;
|
|
+ get_ad_and_sipr(ss->sid, 0);
|
|
+ *rb = 0;
|
|
+
|
|
+ if (!sip->tcp_data)
|
|
+ {
|
|
+ sip->tcp_size = TCP_DATA_SIZE;
|
|
+ sip->tcp_data = malloc1(sip->tcp_size + 1);
|
|
+ if (!sip->tcp_data)
|
|
+ LOG_AND_RETURN(-1, "Cannot alloc memory for tcp_data with size %d",
|
|
+ sip->tcp_size);
|
|
+ memset(sip->tcp_data, 0, sip->tcp_size + 1);
|
|
+ }
|
|
+
|
|
+ if (sip->tcp_len == sip->tcp_size && sip->tcp_pos == 0)
|
|
+ {
|
|
+ LOG("Probably the buffer needs to be increased, as it is full");
|
|
+ sip->tcp_len = 0;
|
|
+ }
|
|
+ if (sip->tcp_len == sip->tcp_size)
|
|
+ {
|
|
+ int nl = sip->tcp_len - sip->tcp_pos;
|
|
+ memmove(sip->tcp_data, sip->tcp_data + sip->tcp_pos, nl);
|
|
+// LOG("Moved from the position %d, length %d", sip->tcp_pos, nl);
|
|
+ sip->tcp_pos = 0;
|
|
+ sip->tcp_len = nl;
|
|
+
|
|
+ }
|
|
+
|
|
+ tmp_len = read(socket, sip->tcp_data + sip->tcp_len,
|
|
+ sip->tcp_size - sip->tcp_len);
|
|
+
|
|
+ if (tmp_len <= 0)
|
|
+ return 0;
|
|
+
|
|
+ pos = 0;
|
|
+ sip->tcp_len += tmp_len;
|
|
+ while (sip->tcp_pos < sip->tcp_len - 6)
|
|
+ {
|
|
+ rtsp = sip->tcp_data + sip->tcp_pos;
|
|
+
|
|
+ if ((rtsp[0] == 0x24) && (rtsp[1] < 2) && (rtsp[4] == 0x80)
|
|
+ && ((rtsp[5] == 0x21) || (rtsp[5] == 0xC8)))
|
|
+ {
|
|
+ copy16r(rtsp_len, rtsp, 2);
|
|
+
|
|
+ if (rtsp_len + sip->tcp_pos > sip->tcp_len) // expecting more data in the buffer
|
|
+ break;
|
|
+
|
|
+ if (rtsp[1] == 0 && (rtsp_len - 12 + pos > len)) // destination buffer full
|
|
+ {
|
|
+ LOGL(4,
|
|
+ "Destination buffer is full @ buf %x pos %d, required %d len %d [%d]",
|
|
+ buf, pos, rtsp_len - 12, len, sip->tcp_pos);
|
|
+ break;
|
|
+ }
|
|
+ sip->tcp_pos += rtsp_len + 4;
|
|
+
|
|
+ pos += process_rtsp_tcp(ss, rtsp, rtsp_len, buf + pos, len - pos);
|
|
+ *rb = pos;
|
|
+
|
|
+ }
|
|
+ else if (!strncmp(rtsp, "RTSP", 4))
|
|
+ {
|
|
+ unsigned char *nlnl, *cl;
|
|
+ int bytes;
|
|
+ unsigned char tmp_char;
|
|
+ nlnl = strstr(rtsp, "\r\n\r\n");
|
|
+ if (nlnl && (cl = strcasestr(rtsp, "content-length:")))
|
|
+ {
|
|
+ cl += 15;
|
|
+ while (*cl == 0x20)
|
|
+ cl++;
|
|
+
|
|
+ int icl = map_intd(cl, NULL, 0);
|
|
+ nlnl += icl;
|
|
+ }
|
|
+ if (!nlnl)
|
|
+ break;
|
|
+ memset(&tmp_sock, 0, sizeof(tmp_sock));
|
|
+ bytes = nlnl - rtsp;
|
|
+ sip->tcp_pos += bytes + 4;
|
|
+ tmp_sock.buf = rtsp;
|
|
+ tmp_sock.rlen = bytes;
|
|
+ tmp_sock.sid = ss->sid;
|
|
+ tmp_sock.sock = ad->dvr;
|
|
+ tmp_sock.id = ss->id;
|
|
+ tmp_char = rtsp[bytes + 4];
|
|
+ rtsp[bytes + 4] = 0;
|
|
+ satipc_reply(&tmp_sock);
|
|
+ rtsp[bytes + 4] = tmp_char;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ LOG("ignoring byte %02X", rtsp[0]);
|
|
+ sip->tcp_pos++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (sip->tcp_pos == sip->tcp_len)
|
|
+ sip->tcp_pos = sip->tcp_len = 0;
|
|
+
|
|
+ return (*rb >= 0);
|
|
+}
|
|
+
|
|
void satip_post_init(adapter *ad)
|
|
{
|
|
satipc *sip;
|
|
get_ad_and_sip(ad->id);
|
|
- sockets_setread(ad->sock, satipc_read);
|
|
- set_socket_thread(ad->fe_sock, get_socket_thread(ad->sock)); // set all the threads to run in the new thread with the adapter
|
|
- set_socket_thread(sip->rtcp_sock, get_socket_thread(ad->sock));
|
|
+ if (sip->use_tcp)
|
|
+ sockets_setread(ad->sock, satipc_tcp_read);
|
|
+ else
|
|
+ {
|
|
+ sockets_setread(ad->sock, satipc_read);
|
|
+ set_socket_thread(sip->rtcp_sock, get_socket_thread(ad->sock));
|
|
+ }
|
|
+ set_socket_thread(ad->fe_sock, get_socket_thread(ad->sock));
|
|
}
|
|
|
|
int satipc_set_pid(adapter *ad, uint16_t pid)
|
|
@@ -536,7 +712,7 @@ int http_request(adapter *ad, char *url, char *method)
|
|
char buf[2048];
|
|
char sid[40];
|
|
char *qm;
|
|
- int lb;
|
|
+ int lb, remote_socket;
|
|
char format[] = "%s rtsp://%s:%d/%s%s%s RTSP/1.0\r\nCSeq: %d%s\r\n\r\n";
|
|
__attribute__((unused)) int rv;
|
|
satipc *sip = get_satip(ad->id);
|
|
@@ -546,6 +722,7 @@ int http_request(adapter *ad, char *url, char *method)
|
|
session[0] = 0;
|
|
sid[0] = 0;
|
|
int64_t ctime = getTick();
|
|
+ remote_socket = sip->use_tcp ? ad->dvr : ad->fe;
|
|
|
|
if (!method && sip->sent_transport == 0)
|
|
{
|
|
@@ -560,8 +737,11 @@ int http_request(adapter *ad, char *url, char *method)
|
|
sip->sent_transport = 1;
|
|
sip->stream_id = -1;
|
|
sip->session[0] = 0;
|
|
- sprintf(session, "\r\nTransport:RTP/AVP;unicast;client_port=%d-%d",
|
|
- sip->listen_rtp, sip->listen_rtp + 1);
|
|
+ if (sip->use_tcp)
|
|
+ sprintf(session, "\r\nTransport: RTP/AVP/TCP;interleaved=0-1");
|
|
+ else
|
|
+ sprintf(session, "\r\nTransport:RTP/AVP;unicast;client_port=%d-%d",
|
|
+ sip->listen_rtp, sip->listen_rtp + 1);
|
|
}
|
|
else
|
|
{
|
|
@@ -601,7 +781,7 @@ int http_request(adapter *ad, char *url, char *method)
|
|
qm, url, sip->cseq++, session);
|
|
|
|
LOG("satipc_http_request (ad %d): %s to handle %d: \n%s", ad->id,
|
|
- sip->expect_reply ? "queueing" : "sending", ad->fe, buf);
|
|
+ sip->expect_reply ? "queueing" : "sending", remote_socket, buf);
|
|
if (sip->expect_reply)
|
|
{
|
|
setItem(MAKE_ITEM(ad->id, sip->qp++), (unsigned char *) buf, lb + 1, 0);
|
|
@@ -609,7 +789,7 @@ int http_request(adapter *ad, char *url, char *method)
|
|
else
|
|
{
|
|
sip->wp = sip->qp = 0;
|
|
- rv = write(ad->fe, buf, lb);
|
|
+ rv = write(remote_socket, buf, lb);
|
|
}
|
|
sip->expect_reply = 1;
|
|
return 0;
|
|
@@ -915,6 +1095,9 @@ void find_satip_adapter(adapter **a)
|
|
sip->satip_fe = determine_fe(a, i, sip->sip, sip->sport);
|
|
sip->addpids = opts.satip_addpids;
|
|
sip->setup_pids = opts.satip_setup_pids;
|
|
+ sip->tcp_size = 0;
|
|
+ sip->tcp_data = NULL;
|
|
+ sip->use_tcp = opts.satip_rtsp_over_tcp;
|
|
|
|
j++;
|
|
LOG("Satip device %s port %d delsys %d: %s %s", sip->sip,
|
|
diff --git a/socketworks.c b/socketworks.c
|
|
index 5452fea..f4e0d60 100644
|
|
--- a/socketworks.c
|
|
+++ b/socketworks.c
|
|
@@ -435,6 +435,7 @@ int sockets_add(int sock, struct sockaddr_in *sa, int sid, int type,
|
|
ss->buf = NULL;
|
|
ss->lbuf = 0;
|
|
ss->timeout_ms = 0;
|
|
+ ss->skiplen = type == TYPE_DVR ? opts.axe_skippkt * 188 : 0;
|
|
ss->id = i;
|
|
ss->read = (read_action) sockets_read;
|
|
ss->lock = NULL;
|
|
@@ -462,15 +463,16 @@ int sockets_del(int sock)
|
|
if (sock < 0 || sock > MAX_SOCKS || !s[sock] || !s[sock]->enabled)
|
|
return 0;
|
|
|
|
+ mutex_lock(&s_mutex);
|
|
ss = s[sock];
|
|
mutex_lock(&ss->mutex);
|
|
if (!ss->enabled)
|
|
{
|
|
mutex_unlock(&ss->mutex);
|
|
+ mutex_unlock(&s_mutex);
|
|
return 0;
|
|
|
|
}
|
|
- mutex_lock(&s_mutex);
|
|
ss->enabled = 0;
|
|
so = ss->sock;
|
|
ss->sock = -1; // avoid infinite loop
|
|
@@ -492,7 +494,7 @@ int sockets_del(int sock)
|
|
ss->lock = NULL;
|
|
LOG("sockets_del: %d Last open socket is at index %d current_handle %d",
|
|
sock, i, so);
|
|
- mutex_destroy(&ss->mutex);
|
|
+ mutex_unlock(&ss->mutex);
|
|
mutex_unlock(&s_mutex);
|
|
return 0;
|
|
}
|
|
@@ -525,6 +527,7 @@ void *select_and_execute(void *arg)
|
|
les = 1;
|
|
es = 0;
|
|
lt = getTick();
|
|
+ memset(&pf, -1, sizeof(pf));
|
|
LOG("Starting select_and_execute on thread ID %x, thread_name %s", tid,
|
|
thread_name);
|
|
while (run_loop)
|
|
@@ -627,10 +630,33 @@ void *select_and_execute(void *arg)
|
|
err = errno;
|
|
if (rlen > 0)
|
|
ss->rtime = c_time;
|
|
- if (read_ok && rlen > 0)
|
|
+ if (read_ok && rlen >= 0)
|
|
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;
|
|
@@ -720,6 +746,8 @@ void *select_and_execute(void *arg)
|
|
}
|
|
}
|
|
|
|
+ clean_mutexes();
|
|
+
|
|
if (tid == main_tid)
|
|
LOG("The main loop ended, run_loop = %d", run_loop);
|
|
add_join_thread(tid);
|
|
@@ -878,6 +906,7 @@ void set_socket_buffer(int sid, unsigned char *buf, int len)
|
|
|
|
void free_all_streams();
|
|
void free_all_adapters();
|
|
+void free_all_keys();
|
|
|
|
void free_all()
|
|
{
|
|
@@ -887,12 +916,17 @@ void free_all()
|
|
{
|
|
if (s[i] && s[i]->enabled)
|
|
sockets_del(i);
|
|
- if (s[i])
|
|
+ if (s[i]) {
|
|
+ mutex_destroy(&s[i]->mutex);
|
|
free(s[i]);
|
|
+ }
|
|
s[i] = NULL;
|
|
}
|
|
free_all_streams();
|
|
free_all_adapters();
|
|
+#ifndef DISABLE_DVBAPI
|
|
+ free_all_keys();
|
|
+#endif
|
|
}
|
|
|
|
void set_socket_send_buffer(int sock, int len)
|
|
@@ -945,6 +979,14 @@ void set_socket_pos(int sock, int pos)
|
|
ss->rlen = pos;
|
|
}
|
|
|
|
+void set_socket_skip(int sock)
|
|
+{
|
|
+ sockets *ss = get_sockets(sock);
|
|
+ if (!ss)
|
|
+ return;
|
|
+ ss->skiplen = opts.axe_skippkt * 188;
|
|
+}
|
|
+
|
|
char *get_socket_rhost(int s_id, char *dest, int ld)
|
|
{
|
|
sockets *ss = get_sockets(s_id);
|
|
diff --git a/socketworks.h b/socketworks.h
|
|
old mode 100644
|
|
new mode 100755
|
|
index 0782477..723821a
|
|
--- a/socketworks.h
|
|
+++ b/socketworks.h
|
|
@@ -24,6 +24,7 @@ typedef struct struct_sockets {
|
|
int lbuf;
|
|
int rlen;
|
|
int timeout_ms;
|
|
+ int skiplen;
|
|
int id; // socket id
|
|
int err;
|
|
int flags; // 1 - buf is allocated dynamically
|
|
@@ -72,6 +73,7 @@ void set_socket_send_buffer(int sock, int len);
|
|
void set_socket_receive_buffer(int sock, int len);
|
|
sockets *get_sockets(int i);
|
|
void set_socket_pos(int sock, int pos);
|
|
+void set_socket_skip(int sock);
|
|
char *get_socket_rhost(int s_id, char *dest, int ld);
|
|
int get_socket_rport(int s_id);
|
|
void set_sock_lock(int i, SMutex *m);
|
|
diff --git a/stream.c b/stream.c
|
|
index 83c0f4f..9008510 100644
|
|
--- a/stream.c
|
|
+++ b/stream.c
|
|
@@ -290,14 +290,15 @@ int close_stream(int i)
|
|
return 0;
|
|
|
|
sid = st[i];
|
|
+ mutex_lock(&st_mutex);
|
|
mutex_lock(&sid->mutex);
|
|
if (!sid->enabled)
|
|
{
|
|
adapter_unlock(sid->adapter);
|
|
mutex_unlock(&sid->mutex);
|
|
+ mutex_unlock(&st_mutex);
|
|
return 0;
|
|
}
|
|
- mutex_lock(&st_mutex);
|
|
sid->enabled = 0;
|
|
sid->timeout = 0;
|
|
ad = sid->adapter;
|
|
@@ -312,7 +313,6 @@ int close_stream(int i)
|
|
if(sid->buf)free(sid->buf);
|
|
sid->pids = sid->apids = sid->dpids = sid->buf = NULL;
|
|
*/
|
|
- mutex_destroy(&sid->mutex);
|
|
|
|
if (sid->rtcp_sock > 0 || sid->rtcp > 0)
|
|
{
|
|
@@ -332,6 +332,7 @@ int close_stream(int i)
|
|
|
|
sockets_del_for_sid (i);
|
|
|
|
+ mutex_unlock(&sid->mutex);
|
|
mutex_unlock(&st_mutex);
|
|
LOG("closed stream %d", i);
|
|
return 0;
|
|
@@ -632,8 +633,8 @@ int send_rtp(streams * sid, const struct iovec *iov, int liov)
|
|
ntohs(sid->sa.sin_port));
|
|
}
|
|
|
|
- LOGL(7, "sent %d bytes for stream %d, handle %d seq %d => %s:%d", total_len,
|
|
- sid->sid, sid->rsock, sid->seq - 1,
|
|
+ LOGL(7, "%s: sent %d bytes for stream %d, handle %d seq %d => %s:%d",
|
|
+ __FUNCTION__, total_len, sid->sid, sid->rsock, sid->seq - 1,
|
|
get_stream_rhost(sid->sid, ra, sizeof(ra)), ntohs(sid->sa.sin_port));
|
|
|
|
return rv;
|
|
@@ -649,12 +650,14 @@ int send_rtpb(streams * sid, unsigned char *b, int len)
|
|
return send_rtp(sid, (const struct iovec *) iov, 1);
|
|
}
|
|
|
|
-unsigned char rtcp_buf[1600];
|
|
|
|
int send_rtcp(int s_id, int64_t ctime)
|
|
{
|
|
int len, rv = 0;
|
|
+ int total_len = 0;
|
|
char dad[1000];
|
|
+ char ra[50];
|
|
+ unsigned char rtcp_buf[1600];
|
|
int c_time = (int) (ctime / 1000) & 0xFFFFFFFF;
|
|
unsigned char *rtcp = rtcp_buf + 4;
|
|
streams *sid = get_sid(s_id);
|
|
@@ -714,20 +717,26 @@ int send_rtcp(int s_id, int64_t ctime)
|
|
rtcp[65] = 0;
|
|
copy16(rtcp, 66, la);
|
|
memcpy(rtcp + 68, a, la + 4);
|
|
+ total_len = len + 52;
|
|
if (sid->type == STREAM_RTSP_UDP)
|
|
- rv = send(sid->rtcp, rtcp, len + 52, MSG_NOSIGNAL);
|
|
+ rv = send(sid->rtcp, rtcp, total_len, MSG_NOSIGNAL);
|
|
else
|
|
{
|
|
rtcp_buf[0] = 0x24;
|
|
rtcp_buf[1] = 1;
|
|
- copy16(rtcp_buf, 2, len + 52);
|
|
- rv = send(sid->rsock, rtcp_buf, len + 52 + 4, MSG_NOSIGNAL);
|
|
+ copy16(rtcp_buf, 2, total_len);
|
|
+ total_len += 4;
|
|
+ rv = send(sid->rsock, rtcp_buf, total_len, MSG_NOSIGNAL);
|
|
}
|
|
// if(rv>0)
|
|
// sid->rsock_err = 0;
|
|
// else
|
|
// sid->rsock_err ++;
|
|
sid->rtcp_wtime = ctime;
|
|
+ LOGL(7, "%s: sent %d bytes for stream %d, handle %d seq %d => %s:%d",
|
|
+ __FUNCTION__, total_len, sid->sid, sid->rsock, sid->seq - 1,
|
|
+ get_stream_rhost(sid->sid, ra, sizeof(ra)), ntohs(sid->sa.sin_port));
|
|
+
|
|
// sid->sp = 0;
|
|
// sid->sb = 0;
|
|
return rv;
|
|
@@ -1125,8 +1134,10 @@ void free_all_streams()
|
|
|
|
for (i = 0; i < MAX_STREAMS; i++)
|
|
{
|
|
- if (st[i])
|
|
+ if (st[i]) {
|
|
+ mutex_destroy(&st[i]->mutex);
|
|
free1(st[i]);
|
|
+ }
|
|
st[i] = NULL;
|
|
|
|
}
|
|
diff --git a/utils.c b/utils.c
|
|
index 24eeb8f..5724684 100644
|
|
--- a/utils.c
|
|
+++ b/utils.c
|
|
@@ -37,6 +37,8 @@
|
|
#include <sys/socket.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/stat.h>
|
|
+#include <sys/syscall.h>
|
|
+#include <sys/resource.h>
|
|
#include <net/if.h>
|
|
#include <fcntl.h>
|
|
#include <ctype.h>
|
|
@@ -185,8 +187,12 @@ int setItem(int64_t key, unsigned char *data, int len, int pos) // pos = -1 -> a
|
|
if (pos == -1)
|
|
pos = s->len;
|
|
if (pos + len >= s->max_size) // make sure we do not overflow the data buffer
|
|
+ {
|
|
+ LOG(
|
|
+ "Overflow detected for item %jx, pos %d, size to be added %d, max_size %d",
|
|
+ key, pos, len, s->max_size);
|
|
len = s->max_size - pos;
|
|
-
|
|
+ }
|
|
s->len = pos + len;
|
|
memcpy(s->data + pos, data, len);
|
|
return 0;
|
|
@@ -745,6 +751,14 @@ void * get_var_address(char *var, float *multiplier, int * type, void *storage,
|
|
*multiplier = 1;
|
|
return storage;
|
|
}
|
|
+ else if (sym[i][j].type == VAR_FUNCTION_INT64)
|
|
+ {
|
|
+ off = map_intd(var + strlen(sym[i][j].name), NULL, 0);
|
|
+ get_data_int64 fun64 = (get_data_int64) sym[i][j].addr;
|
|
+ *(int64_t *) storage = fun64(off);
|
|
+ *multiplier = 1;
|
|
+ return storage;
|
|
+ }
|
|
else if (sym[i][j].type == VAR_FUNCTION_STRING)
|
|
{
|
|
off = map_intd(var + strlen(sym[i][j].name), NULL, 0);
|
|
@@ -942,6 +956,12 @@ int mutex_lock1(char *FILE, int line, SMutex* mutex)
|
|
else
|
|
LOGL(5, "%s:%d Locking mutex %p", FILE, line, mutex);
|
|
rv = pthread_mutex_lock(&mutex->mtx);
|
|
+ if (!mutex->enabled && rv == 0)
|
|
+ {
|
|
+ pthread_mutex_unlock(&mutex->mtx);
|
|
+ LOG("Mutex %x destroyed meanwhile", mutex);
|
|
+ return 1;
|
|
+ }
|
|
if (rv != 0)
|
|
{
|
|
LOG("Mutex Lock %p failed", mutex);
|
|
@@ -949,7 +969,7 @@ int mutex_lock1(char *FILE, int line, SMutex* mutex)
|
|
}
|
|
mutex->file = FILE;
|
|
mutex->line = line;
|
|
- mutex->state = 1;
|
|
+ mutex->state++;
|
|
mutex->tid = tid;
|
|
mutex->lock_time = getTick();
|
|
|
|
@@ -970,7 +990,7 @@ int mutex_unlock1(char *FILE, int line, SMutex* mutex)
|
|
if (!mutex || mutex->enabled)
|
|
{
|
|
LOGL(5, "%s:%d Unlocking mutex %p", FILE, line, mutex);
|
|
-
|
|
+ mutex->state--;
|
|
rv = pthread_mutex_unlock(&mutex->mtx);
|
|
}
|
|
else
|
|
@@ -1019,11 +1039,11 @@ int mutex_destroy(SMutex* mutex)
|
|
imtx--;
|
|
}
|
|
|
|
- if ((rv = pthread_mutex_unlock(&mutex->mtx)) != 1)
|
|
+ if ((rv = pthread_mutex_unlock(&mutex->mtx)) != 1 && rv != 0)
|
|
LOG("%s: pthread_mutex_unlock 1 failed for %p with error %d %s",
|
|
__FUNCTION__, mutex, rv, strerror(rv));
|
|
|
|
- if ((rv = pthread_mutex_unlock(&mutex->mtx)) != 1)
|
|
+ if ((rv = pthread_mutex_unlock(&mutex->mtx)) != 1 && rv != 0)
|
|
LOG("%s: pthread_mutex_unlock 2 failed for %p with error %d %s",
|
|
__FUNCTION__, mutex, rv, strerror(rv));
|
|
|
|
@@ -1078,6 +1098,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));
|
|
@@ -1085,6 +1106,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
|
|
}
|
|
|
|
struct struct_array
|
|
@@ -1109,8 +1136,8 @@ int add_new_lock(void **arr, int count, int size, SMutex *mutex)
|
|
LOG_AND_RETURN(-1,
|
|
"Could not allocate memory for %p index %d", arr, i);
|
|
memset(sa[i], 0, size);
|
|
+ mutex_init(&sa[i]->mutex);
|
|
}
|
|
- mutex_init(&sa[i]->mutex);
|
|
mutex_lock(&sa[i]->mutex);
|
|
sa[i]->enabled = 1;
|
|
mutex_unlock(mutex);
|
|
diff --git a/utils.h b/utils.h
|
|
index fd5d578..70fa61f 100644
|
|
--- a/utils.h
|
|
+++ b/utils.h
|
|
@@ -39,9 +39,11 @@
|
|
#define VAR_AARRAY_PSTRING (VAR_AARRAY + VAR_PSTRING)
|
|
#define VAR_FUNCTION 48
|
|
#define VAR_FUNCTION_INT (VAR_FUNCTION + VAR_INT)
|
|
+#define VAR_FUNCTION_INT64 (VAR_FUNCTION + VAR_INT64)
|
|
#define VAR_FUNCTION_STRING (VAR_FUNCTION + VAR_STRING)
|
|
|
|
typedef int (*get_data_int)(int p);
|
|
+typedef int64_t (*get_data_int64)(int p);
|
|
typedef char * (*get_data_string)(int p, char *dest, int max_len);
|
|
|
|
typedef struct struct_symbols
|