diff --git a/adapter.c b/adapter.c index 033490a..36b3dfd 100644 --- a/adapter.c +++ b/adapter.c @@ -49,6 +49,31 @@ extern struct struct_opts opts; int tuner_s2, tuner_t, tuner_c, tuner_t2, tuner_c2; void find_dvb_adapter(adapter **a); +adapter *adapter_alloc() +{ + adapter *ad = malloc1(sizeof(adapter)); + + /* diseqc setup */ + ad->diseqc_param.fast = opts.diseqc_fast; + ad->diseqc_param.committed_no = opts.diseqc_committed_no; + ad->diseqc_param.uncommitted_no = opts.diseqc_uncommitted_no; + + /* diseqc default timing */ + ad->diseqc_param.before_cmd = opts.diseqc_before_cmd; + ad->diseqc_param.after_cmd = opts.diseqc_after_cmd; + ad->diseqc_param.after_repeated_cmd = opts.diseqc_after_repeated_cmd; + ad->diseqc_param.after_switch = opts.diseqc_after_switch; + ad->diseqc_param.after_burst = opts.diseqc_after_burst; + ad->diseqc_param.after_tone = opts.diseqc_after_tone; + + /* diseqc state control */ + ad->old_diseqc = -1; + ad->old_hiband = -1; + ad->old_pol = -1; + + return ad; +} + void find_adapters() { static int init_find_adapter; @@ -294,6 +319,9 @@ void close_adapter(int na) ad->dvr = 0; ad->strength = 0; ad->snr = 0; + ad->old_diseqc = -1; + ad->old_hiband = -1; + ad->old_pol = -1; mutex_unlock(&ad->mutex); mutex_destroy(&ad->mutex); // if(a[na]->buf)free1(a[na]->buf);a[na]->buf=NULL; @@ -381,19 +409,39 @@ void dump_pids(int aid) } } -#define return_adapter(i) { \ - if(!init_hw(i)) \ - return i; \ +int adapter_match(adapter *ad, int freq, int pol, int msys, int src, int diseqc) +{ + if (!ad->tp.freq == freq) + return 0; + if (msys == SYS_DVBS2 || msys == SYS_DVBS) + { + if (ad->tp.pol == pol && ad->tp.diseqc == diseqc) + return 1; + return 0; + } + return 1; } -int get_free_adapter(int freq, int pol, int msys, int src) +int get_free_adapter(int freq, int pol, int msys, int src, int diseqc) { int i; adapter *ad; // init_all_hw(); - i = (src > 0) ? src - 1 : 0; - ad = get_adapter(i); + if (src > 0) { + i = src - 1; + ad = a[i]; + if (!delsys_match(ad, msys)) + ad = NULL; + if (ad && !ad->enabled) + { + if (init_hw(i)) + goto noadapter; + ad = get_adapter(i); + } + } else { + ad = get_adapter(i = 0); + } if (ad) LOG("get free adapter %d - a[%d] => e:%d m:%d sid_cnt:%d f:%d pol=%d", src - 1, i, ad->enabled, ad->master_sid, ad->sid_cnt, @@ -404,13 +452,14 @@ int get_free_adapter(int freq, int pol, int msys, int src) if (src > 0) { - if (ad) + if (ad && delsys_match(ad, msys)) { - if (ad->sid_cnt == 0 && delsys_match(ad, msys)) + if (ad->sid_cnt == 0) return i; - if (ad->tp.freq == freq && delsys_match(ad, msys)) + if (adapter_match(ad, freq, pol, msys, src, diseqc)) return i; } + goto noadapter; } for (i = 0; i < MAX_ADAPTERS; i++) { @@ -419,21 +468,17 @@ int get_free_adapter(int freq, int pol, int msys, int src) && delsys_match(ad, msys)) return i; if (!ad && delsys_match(a[i], msys)) // device is not initialized - return_adapter(i); + { + if(!init_hw(i)) + return i; + } } for (i = 0; i < MAX_ADAPTERS; i++) - if ((ad = get_adapter_nw(i)) && a[i]->tp.freq == freq - && delsys_match(ad, msys)) - { - if ((msys == SYS_DVBS2 || msys == SYS_DVBS)) - { - if (ad->tp.pol == pol) - return i; - } - else + if ((ad = get_adapter_nw(i)) && delsys_match(ad, msys)) + if (adapter_match(ad, freq, pol, msys, src, diseqc)) return i; - } +noadapter: LOG("no adapter found for f:%d pol:%d msys:%d", freq, pol, msys); dump_adapters(); return -1; @@ -557,19 +602,13 @@ int tune(int aid, int sid) ad->last_sort = getTick(); if (sid == ad->master_sid && ad->do_tune) { - ad->tp.switch_type = ad->switch_type; - ad->tp.uslot = ad->uslot; - ad->tp.ufreq = ad->ufreq; - ad->tp.pin = ad->pin; - ad->tp.only13v = ad->only13v; - - ad->tp.committed_no = ad->committed_no; - ad->tp.uncommitted_no = ad->uncommitted_no; + ad->tp.diseqc_param = ad->diseqc_param; rv = ad->tune(ad->id, &ad->tp); 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 { @@ -1067,7 +1106,7 @@ void set_unicable_adapters(char *o, int type) continue; if (!a[a_id]) - a[a_id] = malloc(sizeof(adapter)); + a[a_id] = adapter_alloc(); ad = a[a_id]; sep1 = strchr(arg[i], ':'); @@ -1084,11 +1123,11 @@ void set_unicable_adapters(char *o, int type) sep3 = strchr(sep2 + 1, '-'); pin = map_intd(sep3, NULL, 0); - ad->uslot = slot; - ad->ufreq = freq; - ad->switch_type = type; - ad->pin = pin; - ad->only13v = o13v; + ad->diseqc_param.uslot = slot; + ad->diseqc_param.ufreq = freq; + ad->diseqc_param.switch_type = type; + ad->diseqc_param.pin = pin; + ad->diseqc_param.only13v = o13v; LOGL(0, "Setting %s adapter %d slot %d freq %d", type == SWITCH_UNICABLE ? "unicable" : "jess", a_id, slot, freq); } @@ -1096,35 +1135,115 @@ void set_unicable_adapters(char *o, int type) void set_diseqc_adapters(char *o) { - int i, la, a_id, committed_no, uncommitted_no; + int i, la, a_id, fast, committed_no, uncommitted_no; char buf[100], *arg[20], *sep1, *sep2; adapter *ad; strncpy(buf, o, sizeof(buf)); 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; + if (arg[i] && arg[i][0] == '*') { + ad = NULL; + a_id = -1; + } else { + a_id = map_intd(arg[i], NULL, -1); + if (a_id < 0 || a_id >= MAX_ADAPTERS) + continue; - if (!a[a_id]) - a[a_id] = malloc(sizeof(adapter)); - ad = a[a_id]; + if (!a[a_id]) + a[a_id] = adapter_alloc(); + ad = a[a_id]; + } sep1 = strchr(arg[i], ':'); sep2 = strchr(arg[i], '-'); if (!sep1 || !sep2) continue; + if ((fast = (sep1[1] == '*')) != 0) + sep1++; committed_no = map_intd(sep1 + 1, NULL, -1); uncommitted_no = map_intd(sep2 + 1, NULL, -1); if (committed_no < 0 || uncommitted_no < 0) continue; - ad->committed_no = committed_no; - ad->uncommitted_no = uncommitted_no; - LOGL(0, "Setting diseqc adapter %d committed_no %d uncommitted_no %d", - a_id, committed_no, uncommitted_no); + if (ad) { + ad->diseqc_param.fast = fast; + ad->diseqc_param.committed_no = committed_no; + ad->diseqc_param.uncommitted_no = uncommitted_no; + } else { + opts.diseqc_fast = fast; + opts.diseqc_committed_no = committed_no; + opts.diseqc_uncommitted_no = uncommitted_no; + } + LOGL(0, "Setting diseqc adapter %d fast %d committed_no %d uncommitted_no %d", + a_id, fast, committed_no, uncommitted_no); + } +} + +void set_diseqc_timing(char *o) +{ + int i, la, a_id; + int before_cmd, after_cmd, after_repeated_cmd; + int after_switch, after_burst, after_tone; + char buf[2000], *arg[20]; + char *sep1, *sep2, *sep3, *sep4, *sep5, *sep6, *sep7; + adapter *ad; + strncpy(buf, o, sizeof(buf)); + la = split(arg, buf, sizeof(arg), ','); + for (i = 0; i < la; i++) + { + if (arg[i] && arg[i][0] == '*') { + ad = NULL; + a_id = -1; + } else { + a_id = map_intd(arg[i], NULL, -1); + if (a_id < 0 || a_id >= MAX_ADAPTERS) + continue; + + if (!a[a_id]) + a[a_id] = adapter_alloc(); + ad = a[a_id]; + } + + sep1 = strchr(arg[i], ':'); + sep2 = strchr(arg[i], '-'); + sep3 = sep2 ? strchr(sep2 + 1, '-') : NULL; + sep4 = sep3 ? strchr(sep3 + 1, '-') : NULL; + sep5 = sep4 ? strchr(sep4 + 1, '-') : NULL; + sep6 = sep5 ? strchr(sep5 + 1, '-') : NULL; + + if (!sep1 || !sep2 || !sep3 || !sep4 || !sep5 || !sep6) + continue; + before_cmd = map_intd(sep1 + 1, NULL, -1); + after_cmd = map_intd(sep2 + 1, NULL, -1); + after_repeated_cmd = map_intd(sep3 + 1, NULL, -1); + after_switch = map_intd(sep4 + 1, NULL, -1); + after_burst = map_intd(sep5 + 1, NULL, -1); + after_tone = map_intd(sep6 + 1, NULL, -1); + if (before_cmd < 0 || after_cmd < 0 || after_repeated_cmd < 0 || + after_switch < 0 || after_burst < 0 || after_tone < 0) + continue; + + if (ad) { + ad->diseqc_param.before_cmd = before_cmd; + ad->diseqc_param.after_cmd = after_cmd; + ad->diseqc_param.after_repeated_cmd = after_repeated_cmd; + ad->diseqc_param.after_switch = after_switch; + ad->diseqc_param.after_burst = after_burst; + ad->diseqc_param.after_tone = after_tone; + } else { + opts.diseqc_before_cmd = before_cmd; + opts.diseqc_after_cmd = after_cmd; + opts.diseqc_after_repeated_cmd = after_repeated_cmd; + opts.diseqc_after_switch = after_switch; + opts.diseqc_after_burst = after_burst; + opts.diseqc_after_tone = after_tone; + } + LOGL(0, "Setting diseqc timing for adapter %d before cmd %d after cmd %d " + "after repeated cmd %d after switch %d after burst %d after tone %d", + a_id, before_cmd, after_cmd, after_repeated_cmd, + after_switch, after_burst, after_tone); } } @@ -1152,16 +1271,43 @@ void set_slave_adapters(char *o) for (j = a_id; j <= a_id2; j++) { if (!a[j]) - a[j] = malloc1(sizeof(adapter)); + a[j] = adapter_alloc(); ad = a[j]; - ad->switch_type = SWITCH_SLAVE; + ad->diseqc_param.switch_type = SWITCH_SLAVE; LOGL(0, "Setting slave adapter %d", j); } } } + +void set_link_adapters(char *o) +{ + int i, la, a_id, b_id; + char buf[100], *arg[20], *sep1; + + strncpy(buf, o, sizeof(buf)-1); + buf[sizeof(buf)-1] = '\0'; + la = split(arg, buf, sizeof(arg), ','); + for (i=0; i= MAX_ADAPTERS) + continue; + sep1 = strchr(arg[i], ':'); + if (!sep1) + continue; + b_id=map_intd(sep1 + 1, NULL, -1); + if (b_id < 0 || b_id >= MAX_ADAPTERS) + continue;; + if (a_id == b_id || a[a_id]->slave) + continue; + a[a_id]->slave = a_id + 1; + LOG("Setting adapter %d as master for adapter %d", a_id, b_id); + } +} + extern char *fe_delsys[]; void set_adapters_delsys(char *o) { @@ -1186,7 +1332,7 @@ void set_adapters_delsys(char *o) ds = map_intd(sep + 1, fe_delsys, 0); if (!a[a_id]) - a[a_id] = malloc1(sizeof(adapter)); + a[a_id] = adapter_alloc(); ad = a[a_id]; ad->sys[0] = ds; @@ -1371,42 +1517,24 @@ char *get_all_delsys(int aid, char *dest, int max_size) return dest; } -adapter *a_tmp; - _symbols adapters_sym[] = { -{ "ad_enabled", VAR_AARRAY_INT8, a, 1, MAX_ADAPTERS, - (long int) &a_tmp[0].enabled - (long int) &a_tmp[0] }, -{ "ad_type", VAR_AARRAY_INT8, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].type - - (long int) &a_tmp[0] }, -{ "ad_freq", VAR_AARRAY_INT, a, 1. / 1000, -MAX_ADAPTERS, (long int) &a_tmp[0].tp.freq - (long int) &a_tmp[0] }, -{ "ad_strength", VAR_AARRAY_UINT16, a, 1, -MAX_ADAPTERS, (long int) &a_tmp[0].strength - (long int) &a_tmp[0] }, -{ "ad_snr", VAR_AARRAY_UINT16, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].snr - - (long int) &a_tmp[0] }, -{ "ad_ber", VAR_AARRAY_UINT16, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].ber - - (long int) &a_tmp[0] }, -{ "ad_pol", VAR_AARRAY_INT8, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].tp.pol - - (long int) &a_tmp[0] }, -{ "ad_sr", VAR_AARRAY_INT, a, 1. / 1000, MAX_ADAPTERS, - (long int) &a_tmp[0].tp.sr - (long int) &a_tmp[0] }, -{ "ad_bw", VAR_AARRAY_INT, a, 1. / 1000, MAX_ADAPTERS, - (long int) &a_tmp[0].tp.bw - (long int) &a_tmp[0] }, -{ "ad_diseqc", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, - (long int) &a_tmp[0].tp.diseqc - (long int) &a_tmp[0] }, -{ "ad_fe", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].fe - - (long int) &a_tmp[0] }, -{ "ad_master", VAR_AARRAY_UINT8, a, 1, -MAX_ADAPTERS, (long int) &a_tmp[0].master_sid - (long int) &a_tmp[0] }, -{ "ad_sidcount", VAR_AARRAY_UINT8, a, 1, -MAX_ADAPTERS, (long int) &a_tmp[0].sid_cnt - (long int) &a_tmp[0] }, -{ "ad_phyad", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].pa - - (long int) &a_tmp[0] }, -{ "ad_phyfd", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].fn - - (long int) &a_tmp[0] }, -{ "ad_sys", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, (long int) &a_tmp[0].tp.sys - - (long int) &a_tmp[0] }, +{ "ad_enabled", VAR_AARRAY_INT8, a, 1, MAX_ADAPTERS, offsetof(adapter, enabled) }, +{ "ad_type", VAR_AARRAY_INT8, a, 1, MAX_ADAPTERS, offsetof(adapter, type) }, +{ "ad_freq", VAR_AARRAY_INT, a, 1. / 1000, MAX_ADAPTERS, offsetof(adapter, tp.freq) }, +{ "ad_strength", VAR_AARRAY_UINT16, a, 1, MAX_ADAPTERS, offsetof(adapter, strength) }, +{ "ad_snr", VAR_AARRAY_UINT16, a, 1, MAX_ADAPTERS, offsetof(adapter, snr) }, +{ "ad_ber", VAR_AARRAY_UINT16, a, 1, MAX_ADAPTERS, offsetof(adapter, ber) }, +{ "ad_pol", VAR_AARRAY_INT8, a, 1, MAX_ADAPTERS, offsetof(adapter, tp.pol) }, +{ "ad_sr", VAR_AARRAY_INT, a, 1. / 1000, MAX_ADAPTERS, offsetof(adapter, tp.sr) }, +{ "ad_bw", VAR_AARRAY_INT, a, 1. / 1000, MAX_ADAPTERS, offsetof(adapter, tp.bw) }, +{ "ad_diseqc", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, tp.diseqc) }, +{ "ad_fe", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, fe) }, +{ "ad_master", VAR_AARRAY_UINT8, a, 1, MAX_ADAPTERS, offsetof(adapter, master_sid) }, +{ "ad_sidcount", VAR_AARRAY_UINT8, a, 1, MAX_ADAPTERS, offsetof(adapter, sid_cnt) }, +{ "ad_phyad", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, pa) }, +{ "ad_phyfd", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, fn) }, +{ "ad_sys", VAR_AARRAY_INT, a, 1, MAX_ADAPTERS, offsetof(adapter, tp.sys) }, { "ad_allsys", VAR_FUNCTION_STRING, (void *) &get_all_delsys, 0, 0, 0 }, { "ad_pids", VAR_FUNCTION_STRING, (void *) &get_adapter_pids, 0, 0, 0 }, { "tuner_s2", VAR_INT, &tuner_s2, 1, 0, 0 }, diff --git a/adapter.h b/adapter.h index e693479..b37c238 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 @@ -83,12 +87,11 @@ typedef struct struct_adapter uint32_t ber; 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 - int switch_type; - int uslot; // unicable/jess slot - int ufreq; // unicable/jess frequency - int pin; - int only13v; // unicable - use 13V voltage only - int committed_no, uncommitted_no; // diseqc info + int slave; + diseqc diseqc_param; + int old_diseqc; + int old_hiband; + int old_pol; int id; int pat_processed, transponder_id, pat_ver; char name[5]; @@ -109,8 +112,9 @@ extern int a_count; int init_hw(int dev); int init_all_hw(); int getAdaptersCount(); +adapter *adapter_alloc(); void close_adapter(int na); -int get_free_adapter(int freq, int pol, int msys, int src); +int get_free_adapter(int freq, int pol, int msys, int src, int diseqc); int set_adapter_for_stream(int i, int a); void close_adapter_for_stream(int sid, int aid); int set_adapter_parameters(int aid, int sid, transponder * tp); @@ -128,7 +132,9 @@ void sort_pids(int aid); void enable_adapters(char *o); void set_unicable_adapters(char *o, int type); void set_diseqc_adapters(char *o); +void set_diseqc_timing(char *o); void set_slave_adapters(char *o); +void set_link_adapters(char *o); void reset_pids_type(int aid, int clear_pat); void reset_ecm_type_for_key(int aid, int key); int delsys_match(adapter *ad, int del_sys); diff --git a/axe.h b/axe.h new file mode 100644 index 0000000..d8b06bc --- /dev/null +++ b/axe.h @@ -0,0 +1,149 @@ +#ifndef __AXE_H +#define __AXE_H + +#include +#include + +typedef struct fe_frontend_status fe_frontend_status_t; + +struct fe_frontend_status { + __u32 val0; + __u32 val1; + __u32 val2; + __u32 modulation; + __u32 val4; + __u32 frequency; + __u32 val6; + __u32 val7; + __u32 symbol_rate; + __u32 val9; + __u32 fec; + __u32 rolloff; + __u32 val12; + __u32 val13; +} __attribute__ ((packed)); + +#define FE_FRONTEND_STANDBY _IOW('o', 91, __u32) +#define FE_FRONTEND_RESET _IO('o', 93) +#define FE_FRONTEND_STATUS _IOR('o', 96, fe_frontend_status_t) +#define FE_FRONTEND_INPUT _IOW('o', 97, __u8) + +static inline int axe_fe_standby(int fd, __u32 stdby) +{ + return ioctl(fd, FE_FRONTEND_STANDBY, &stdby); +} + +static inline int axe_fe_reset(int fd) +{ + return ioctl(fd, FE_FRONTEND_RESET, 0x54); +} + +static inline int axe_fe_input(int fd, __u8 in) +{ + return ioctl(fd, FE_FRONTEND_INPUT, &in); +} + +typedef struct dmx_stream_params_s { + __u32 srcIp; + __u16 srcPort; + __u16 dstPort; + __u32 dstIp; + __u32 ts; /* timestamp */ + __u32 ssrc; /* synchronization source */ + __u16 seq; +} dmx_stream_params_t; + +typedef struct rtp_state { + __u32 ssrc; + __u32 ts; + __u32 spc; + __u32 soc; + __u16 seq; +} rtp_state_t; + +#define DMXTS_ADD_PID _IOW('o', 1, __u16) +#define DMXTS_REMOVE_PID _IOW('o', 2, __u16) + +#define DMXTS_TRANSFER_START _IO('o', 5) +#define DMXTS_TRANSFER_START_RTP _IOW('o', 6, dmx_stream_params_t) +#define DMXTS_TRANSFER_STOP _IO('o', 7) +#define DMXTS_RTP_SETUP_SSRC _IOW('o', 8, __u32) +#define DMXTS_TRANSFER_PAUSE _IO('o', 9) +#define DMXTS_TRANSFER_RESUME _IO('o', 10) + +#define DMXTS_GET_RTP_STREAM_STATE _IOR('o', 11, rtp_state_t) + +static inline int axe_dmxts_add_pid(int fd, __u16 pid) +{ + return ioctl(fd, DMXTS_ADD_PID, &pid); +} + +static inline int axe_dmxts_remove_pid(int fd, __u16 pid) +{ + return ioctl(fd, DMXTS_REMOVE_PID, &pid); +} + +static inline int axe_dmxts_start(int fd) +{ + return ioctl(fd, DMXTS_TRANSFER_START); +} + +#ifdef AXE_MAIN + +int axe_fp_fd = -1; + +static inline axe_fp_fd_open(void) +{ + if (axe_fp_fd < 0) + axe_fp_fd = open("/dev/axe/fp-0", O_WRONLY); +} + +static inline axe_fp_fd_write(const char *s) +{ + const char *b; + size_t len; + ssize_t r; + + axe_fp_fd_open(); + len = strlen(b = s); + while (len > 0) { + r = write(axe_fp_fd, b, len); + if (r > 0) { + len -= r; + b += r; + } + } +} + +void axe_set_tuner_led(int tuner, int on) +{ + static int state = 0; + char buf[16]; + if (((state >> tuner) & 1) != !!on) { + sprintf(buf, "T%d_LED %d\n", tuner, on ? 1 : 0); + axe_fp_fd_write(buf); + if (on) + state |= 1 << tuner; + else + state &= ~(1 << tuner); + } +} + +void axe_set_network_led(int on) +{ + static int state = -1; + if (state != on) { + axe_fp_fd_write(on ? "NET_LED 1\n" : "NET_LED 0\n"); + state = on; + } +} + +#else + +void axe_set_tuner_led(int tuner, int on); +void axe_set_network_led(int on); +void axe_status(char *buf, size_t buflen); + +#endif + +#endif diff --git a/dvb.c b/dvb.c index 259b93d..8040849 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 }; @@ -235,7 +240,6 @@ void init_dvb_parameters(transponder * tp) tp->mtype = -1; tp->plts = PILOT_AUTO; tp->fec = FEC_AUTO; - tp->old_diseqc = tp->old_pol = tp->old_hiband = -1; } void copy_dvb_parameters(transponder * s, transponder * d) @@ -330,13 +334,25 @@ int dvb_open_device(adapter *ad) char buf[100]; LOG("trying to open [%d] adapter %d and frontend %d", ad->id, ad->pa, ad->fn); +#ifdef AXE + sprintf(buf, "/dev/axe/frontend-%d", ad->pa); +#else sprintf(buf, "/dev/dvb/adapter%d/frontend%d", ad->pa, ad->fn); +#endif ad->fe = open(buf, O_RDWR | O_NONBLOCK); +#ifdef AXE + sprintf(buf, "/dev/axe/demuxts-%d", ad->pa); +#else sprintf(buf, "/dev/dvb/adapter%d/dvr%d", ad->pa, ad->fn); +#endif ad->dvr = open(buf, O_RDONLY | O_NONBLOCK); if (ad->fe < 0 || ad->dvr < 0) { +#ifdef AXE + sprintf(buf, "/dev/axe/frontend-%d", ad->pa); +#else sprintf(buf, "/dev/dvb/adapter%d/frontend%d", ad->pa, ad->fn); +#endif LOGL(0, "Could not open %s in RW mode (fe: %d, dvr: %d)", buf, ad->fe, ad->dvr); if (ad->fe >= 0) @@ -349,31 +365,41 @@ int dvb_open_device(adapter *ad) ad->type = ADAPTER_DVB; LOG("opened DVB adapter %d fe:%d dvr:%d", ad->id, ad->fe, ad->dvr); +#ifndef AXE if (ioctl(ad->dvr, DMX_SET_BUFFER_SIZE, opts.dvr_buffer) < 0) LOG("couldn't set DVR buffer size error %d: %s", errno, strerror(errno)) else LOG("Done setting DVR buffer to %d bytes", opts.dvr_buffer); +#endif return 0; } -void diseqc_cmd(int fd, int times, char *str, struct dvb_diseqc_master_cmd *cmd) +void msleep(long ms) +{ + if (ms > 0) + usleep(ms * 1000); +} + +void diseqc_cmd(int fd, int times, char *str, struct dvb_diseqc_master_cmd *cmd, + diseqc *d) { int i; + msleep(d->before_cmd); for (i = 0; i < times; i++) { - usleep(15000); if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, cmd) == -1) LOG( "send_diseqc: FE_DISEQC_SEND_MASTER_CMD %s failed for fd %d: %s", str, fd, strerror(errno)); - usleep(54000); + msleep(i > 0 ? d->after_repeated_cmd : d->after_cmd); } } -int send_diseqc(int fd, int pos, int pol, int hiband, int committed_no, - int uncommitted_no) +int send_diseqc(int fd, int pos, int pos_change, int pol, int hiband, diseqc *d) { + int committed_no = d->committed_no; + int uncommitted_no = d->uncommitted_no; int uncommitted_first = 0; int posu, posc; /* DiSEqC 1.0 */ @@ -412,77 +438,83 @@ int send_diseqc(int fd, int pos, int pol, int hiband, int committed_no, LOG("send_diseqc: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno)); - if (uncommitted_first) - diseqc_cmd(fd, uncommitted_no, "uncommitted", &uncmd); + if (!d->fast || pos_change) { - diseqc_cmd(fd, committed_no, "committed", &cmd); + if (uncommitted_first) + diseqc_cmd(fd, uncommitted_no, "uncommitted", &uncmd, d); - if (!uncommitted_first) - diseqc_cmd(fd, uncommitted_no, "uncommitted", &uncmd); + diseqc_cmd(fd, committed_no, "committed", &cmd, d); - usleep(15000); - if (ioctl(fd, FE_DISEQC_SEND_BURST, (pos & 1) ? SEC_MINI_B : SEC_MINI_A) - == -1) - LOG("send_diseqc: FE_DISEQC_SEND_BURST failed for fd %d: %s", fd, - strerror(errno)); - usleep(15000); + if (!uncommitted_first) + diseqc_cmd(fd, uncommitted_no, "uncommitted", &uncmd, d); + + msleep(d->after_switch); + + if (ioctl(fd, FE_DISEQC_SEND_BURST, (pos & 1) ? SEC_MINI_B : SEC_MINI_A) == -1) + LOG("send_diseqc: FE_DISEQC_SEND_BURST failed for fd %d: %s", fd, + strerror(errno)); + + } + + msleep(d->after_burst); if (ioctl(fd, FE_SET_TONE, hiband ? SEC_TONE_ON : SEC_TONE_OFF) == -1) LOG("send_diseqc: FE_SET_TONE failed for fd %d: %s", fd, strerror(errno)); + msleep(d->after_tone); + return 0; } -int send_unicable(int fd, int freq, int pos, int pol, int hiband, int slot, - int ufreq, int pin, int o13v) +int send_unicable(int fd, int freq, int pos, int pol, int hiband, diseqc *d) { struct dvb_diseqc_master_cmd cmd = { { 0xe0, 0x11, 0x5a, 0x00, 0x00 }, 5 }; int t; - t = (freq + ufreq + 2) / 4 - 350; + t = (freq + d->ufreq + 2) / 4 - 350; - cmd.msg[3] = ((t & 0x0300) >> 8) | (slot << 5) | (pos ? 0x10 : 0) + cmd.msg[3] = ((t & 0x0300) >> 8) | (d->uslot << 5) | (pos ? 0x10 : 0) | (hiband ? 4 : 0) | (pol ? 8 : 0); cmd.msg[4] = t & 0xff; - if (pin) + if (d->pin) { cmd.msg_len = 6; cmd.msg[2] = 0x5C; - cmd.msg[5] = pin; + cmd.msg[5] = d->pin; } 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], + fd, freq, d->ufreq, pos, pol, hiband, d->uslot, cmd.msg[0], cmd.msg[1], cmd.msg[2], cmd.msg[3], cmd.msg[4]); 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)); - usleep(15000); + msleep(d->before_cmd); 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 (!o13v && ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1) + if (!d->only13v && ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1) LOG("send_unicable: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno)); - usleep(15000); + msleep(d->after_burst); if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) LOG("send_unicable: FE_DISEQC_SEND_MASTER_CMD failed for fd %d: %s", fd, strerror(errno)); - usleep(15000); + msleep(d->after_repeated_cmd); if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13) == -1) LOG("send_unicable: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno)); + msleep(d->after_tone); - return ufreq * 1000; + return d->ufreq * 1000; } -int send_jess(int fd, int freq, int pos, int pol, int hiband, int slot, - int ufreq, int pin, int o13v) +int send_jess(int fd, int freq, int pos, int pol, int hiband, diseqc *d) { struct dvb_diseqc_master_cmd cmd = { @@ -490,44 +522,45 @@ int send_jess(int fd, int freq, int pos, int pol, int hiband, int slot, // int t = (freq / 1000) - 100; int t = freq - 100; - cmd.msg[1] = slot << 3; + cmd.msg[1] = d->uslot << 3; cmd.msg[1] |= ((t << 8) & 0x07); cmd.msg[2] = (t & 0xff); cmd.msg[3] = ((pos & 0x3f) << 2) | (pol ? 2 : 0) | (hiband ? 1 : 0); - if (pin < 256) + if (d->pin < 256) { cmd.msg_len = 5; cmd.msg[0] = 0x71; - cmd.msg[4] = pin; + cmd.msg[4] = d->pin; } 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], + fd, freq, d->ufreq, pos, pol, hiband, d->uslot, cmd.msg[0], cmd.msg[1], cmd.msg[2], cmd.msg[3], cmd.msg[4]); 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)); - usleep(15000); + msleep(d->before_cmd); 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 (!o13v && ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1) + if (!d->only13v && ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18) == -1) LOG("send_jess: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno)); - usleep(15000); + msleep(d->after_burst); if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd) == -1) LOG("send_jess: FE_DISEQC_SEND_MASTER_CMD failed for fd %d: %s", fd, strerror(errno)); - usleep(15000); + msleep(d->after_repeated_cmd); if (ioctl(fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13) == -1) LOG("send_jess: FE_SET_VOLTAGE failed for fd %d: %s", fd, strerror(errno)); + msleep(d->after_tone); - return ufreq * 1000; + return d->ufreq * 1000; } -int setup_switch(int frontend_fd, transponder *tp) +int setup_switch(int frontend_fd, adapter *ad, transponder *tp) { int hiband = 0; int diseqc = (tp->diseqc > 0) ? tp->diseqc - 1 : 0; @@ -550,35 +583,129 @@ int setup_switch(int frontend_fd, transponder *tp) hiband = 1; } - if (tp->switch_type == SWITCH_UNICABLE) +#ifdef AXE + adapter *ad2, *adm; + int input = 0, aid; + + if (tp->diseqc_param.switch_type != SWITCH_UNICABLE && + tp->diseqc_param.switch_type != SWITCH_JESS) { + input = ad->id; + 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->old_pol >= 0) { + for (aid = 0; aid < 4; aid++) { + ad2 = get_adapter(aid); + if (!ad2 || ad == ad2) continue; + if (ad2->slave && ad2->slave - 1 != adm->pa) continue; + if (!ad2->slave && ad2 != adm) continue; + if (ad2->sid_cnt > 0) break; + } + if (adm != ad && aid < 4 && + (adm->old_pol != pol || + adm->old_hiband != hiband || + adm->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->old_pol != pol || + adm->old_hiband != hiband || + adm->old_diseqc != diseqc) { + send_diseqc(adm->fe, diseqc, adm->old_diseqc != diseqc, + pol, hiband, &tp->diseqc_param); + adm->old_pol = pol; + adm->old_hiband = hiband; + adm->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->old_pol != pol || adm->old_hiband != hiband) { + send_diseqc(adm->fe, 0, 0, pol, hiband, &tp->diseqc_param); + adm->old_pol = pol; + adm->old_hiband = hiband; + adm->old_diseqc = diseqc = 0; + } + } + } else { + input = opts.axe_unicinp; + ad = get_adapter(input); + if (ad == NULL) { + LOGL(3, "axe setup: unable to find adapter %d", input); + return 0; + } + } +#endif + + if (tp->diseqc_param.switch_type == SWITCH_UNICABLE) { - freq = send_unicable(frontend_fd, freq / 1000, diseqc, pol, hiband, - tp->uslot, tp->ufreq, tp->pin, tp->only13v); +#ifdef AXE + if (ad) + freq = send_unicable(ad->fe, 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->switch_type == SWITCH_JESS) + else if (tp->diseqc_param.switch_type == SWITCH_JESS) { - freq = send_jess(frontend_fd, freq / 1000, diseqc, pol, hiband, - tp->uslot, tp->ufreq, tp->pin, tp->only13v); +#ifdef AXE + if (ad) + freq = send_jess(ad->fe, 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->switch_type == SWITCH_SLAVE) + else if (tp->diseqc_param.switch_type == SWITCH_SLAVE) { LOGL(2, "FD %d is a slave adapter", frontend_fd); } else { - if (tp->old_pol != pol || tp->old_hiband != hiband - || tp->old_diseqc != diseqc) - send_diseqc(frontend_fd, diseqc, pol, hiband, tp->committed_no, - tp->uncommitted_no); + if (ad->old_pol != pol || ad->old_hiband != hiband + || ad->old_diseqc != diseqc) + send_diseqc(frontend_fd, diseqc, ad->old_diseqc != diseqc, + pol, hiband, &tp->diseqc_param); else - LOGL(3, - "Skip sending diseqc commands since the switch position doesn't need to be changed: pol %d, hiband %d, switch position %d", + 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); } - tp->old_pol = pol; - tp->old_hiband = hiband; - tp->old_diseqc = 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 + + ad->old_pol = pol; + ad->old_hiband = hiband; + ad->old_diseqc = diseqc; return freq; } @@ -611,6 +738,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, @@ -624,14 +759,16 @@ int dvb_tune(int aid, transponder * tp) case SYS_DVBS2: bpol = getTick(); - freq = setup_switch(fd_frontend, tp); + freq = setup_switch(fd_frontend, ad, tp); if (freq < MIN_FRQ_DVBS || freq > MAX_FRQ_DVBS) LOG_AND_RETURN(-404, "Frequency %d is not within range ", freq) ADD_PROP(DTV_SYMBOL_RATE, tp->sr) ADD_PROP(DTV_INNER_FEC, tp->fec) +#ifndef AXE ADD_PROP(DTV_PILOT, tp->plts) ADD_PROP(DTV_ROLLOFF, tp->ro) +#endif #if DVBAPIVERSION >= 0x0502 ADD_PROP(DTV_STREAM_ID, tp->plp) #endif @@ -640,7 +777,12 @@ int dvb_tune(int aid, transponder * tp) "tuning to %d(%d) pol: %s (%d) sr:%d fec:%s delsys:%s mod:%s rolloff:%s pilot:%s, ts clear=%d, ts pol=%d", tp->freq, freq, get_pol(tp->pol), tp->pol, tp->sr, fe_fec[tp->fec], fe_delsys[tp->sys], fe_modulation[tp->mtype], - fe_rolloff[tp->ro], fe_pilot[tp->plts], bclear, bpol) +#ifdef AXE + "auto", "auto", +#else + fe_rolloff[tp->ro], fe_pilot[tp->plts], +#endif + bclear, bpol) break; case SYS_DVBT: @@ -741,29 +883,46 @@ int dvb_tune(int aid, transponder * tp) if (ioctl(fd_frontend, FE_SET_PROPERTY, &p) == -1) { LOG("dvb_tune: set property failed %d %s", errno, strerror(errno)); +#ifdef AXE + axe_set_tuner_led(aid + 1, 0); +#endif return -404; } +#ifdef AXE + axe_dmxts_start(ad->dvr); +#endif + return 0; } int dvb_set_pid(adapter *a, uint16_t i_pid) { +#ifdef AXE + if (i_pid > 8192 || a == NULL) + LOG_AND_RETURN(-1, "pid %d > 8192 for ADAPTER %d", i_pid, a->id); + if (axe_dmxts_add_pid(a->dvr, i_pid) < 0) + { + LOG("failed setting filter on PID %d for ADAPTER %d (%s)", i_pid, a->id, strerror (errno)); + return -1; + } + LOG("setting filter on PID %d for ADAPTER %d", i_pid, a->id); + return ((a->id + 1) << 16) | i_pid; +#else char buf[100]; int fd; int hw, ad; + sprintf(buf, "/dev/dvb/adapter%d/demux%d", hw, ad); + hw = a->pa; ad = a->fn; if (i_pid > 8192) - LOG_AND_RETURN(-1, "pid %d > 8192 for /dev/dvb/adapter%d/demux%d", - i_pid, hw, ad); + LOG_AND_RETURN(-1, "pid %d > 8192 for %s", i_pid, buf); - sprintf(buf, "/dev/dvb/adapter%d/demux%d", hw, ad); if ((fd = open(buf, O_RDWR | O_NONBLOCK)) < 0) { - LOG("Could not open demux device /dev/dvb/adapter%d/demux%d: %s ", hw, - ad, strerror (errno)); + LOG("Could not open demux device %s: %s ", buf, strerror (errno)); return -1; } @@ -789,10 +948,22 @@ int dvb_set_pid(adapter *a, uint16_t i_pid) LOG("setting filter on PID %d for fd %d", i_pid, fd); return fd; +#endif } int dvb_del_filters(int fd, int pid) { +#ifdef AXE + adapter *a = get_adapter((fd >> 16) - 1); + if (a == NULL) + return 0; /* closed */ + if ((fd & 0xffff) != pid) + LOG_AND_RETURN(0, "AXE PID remove on an invalid handle %d, pid %d", fd, pid); + if (axe_dmxts_remove_pid(a->dvr, pid) < 0) + LOG("AXE PID remove failed on PID %d ADAPTER %d: %s", pid, a->pa, strerror (errno)) + else + LOG("clearing filters on PID %d ADAPTER %d", pid, a->pa); +#else if (fd < 0) LOG_AND_RETURN(0, "DMX_STOP on an invalid handle %d, pid %d", fd, pid); if (ioctl(fd, DMX_STOP, NULL) < 0) @@ -801,10 +972,20 @@ int dvb_del_filters(int fd, int pid) LOG("clearing filter on PID %d FD %d", pid, fd); close(fd); return 0; +#endif } fe_delivery_system_t dvb_delsys(int aid, int fd, fe_delivery_system_t *sys) { +#ifdef AXE + int i; + LOG ("Delivery System DVB-S/DVB-S2 (AXE)"); + for(i = 0 ; i < 10 ; i ++) + sys[i] = 0; + sys[0] = SYS_DVBS; + sys[1] = SYS_DVBS2; + return SYS_DVBS2; +#else int i, res, rv = 0; struct dvb_frontend_info fe_info; @@ -893,6 +1074,7 @@ fe_delivery_system_t dvb_delsys(int aid, int fd, fe_delivery_system_t *sys) fe_delsys[sys[i]], sys[i]); return (fe_delivery_system_t) rv; +#endif } @@ -1005,6 +1187,7 @@ void dvb_get_signal(adapter *ad) ad->max_strength = (ad->strength > 0) ? ad->strength : 1; if (ad->max_snr <= ad->snr) ad->max_snr = (ad->snr > 0) ? ad->snr : 1; +#ifndef AXE if (ad->snr > 4096) new_gs = 0; if (new_gs) @@ -1017,6 +1200,14 @@ void dvb_get_signal(adapter *ad) ad->strength = ad->strength >> 8; ad->snr = ad->snr >> 8; } +#else + ad->strength = ad->strength * 240 / 24000; + if (ad->strength > 240) + ad->strength = 240; + ad->snr = ad->snr * 15 / 54000; + if (ad->snr > 15) + ad->snr = 15; +#endif } void dvb_commit(adapter *a) @@ -1024,6 +1215,33 @@ void dvb_commit(adapter *a) return; } +int dvb_close(adapter *a2) +{ +#ifdef AXE + adapter *c; + int aid, fe = a2->fe; + if (fe <= 0) + return; + axe_fe_reset(fe); + for (aid = 0; aid < 4; aid++) + if (aid != a2->id && a[aid]->sid_cnt > 0) break; + if (aid >= 4) { + LOG("AXE standby"); + for (aid = 0; aid < 4; aid++) { + c = a[aid]; + axe_fe_standby(c->fe, -1); + axe_set_tuner_led(aid + 1, 0); + ioctl(c->fe, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF); + c->old_diseqc = c->old_pol = c->old_hiband = -1; + } + } else { + LOG("AXE standby: adapter %d busy (%d), keeping", aid, a[aid]->sid_cnt); + } + axe_set_tuner_led(a2->id + 1, 0); +#endif + return 0; +} + void find_dvb_adapter(adapter **a) { int na = 0; @@ -1032,9 +1250,21 @@ void find_dvb_adapter(adapter **a) int i = 0, j = 0; adapter *ad; +#ifdef AXE + axe_set_network_led(0); +#endif for (i = 0; i < MAX_ADAPTERS; i++) for (j = 0; j < MAX_ADAPTERS; j++) { +#ifdef AXE + if (i < 4 && j == 0) { + axe_set_tuner_led(i + 1, 0); + sprintf(buf, "/dev/axe/frontend-%d", i); + fd = open(buf, O_RDONLY | O_NONBLOCK); + } else { + continue; + } +#else sprintf(buf, "/dev/dvb/adapter%d/frontend%d", i, j); fd = open(buf, O_RDONLY | O_NONBLOCK); if (fd < 0) @@ -1042,7 +1272,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)) @@ -1051,7 +1282,7 @@ void find_dvb_adapter(adapter **a) // continue; // } if (!a[na]) - a[na] = malloc1(sizeof(adapter)); + a[na] = adapter_alloc(); ad = a[na]; ad->pa = i; @@ -1064,7 +1295,7 @@ void find_dvb_adapter(adapter **a) ad->tune = (Tune) dvb_tune; ad->delsys = (Dvb_delsys) dvb_delsys; ad->post_init = NULL; - ad->close = NULL; + ad->close = (Adapter_commit) dvb_close; ad->get_signal = (Device_signal) dvb_get_signal; ad->type = ADAPTER_DVB; close(fd); @@ -1073,6 +1304,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/dvb.h b/dvb.h index 0ab67a7..0f54e8e 100644 --- a/dvb.h +++ b/dvb.h @@ -165,6 +165,28 @@ typedef enum fe_modulation { #define MIN_FRQ_DVBS 950000 #define MAX_FRQ_DVBS 2150000 +typedef struct diseqc +{ +#define SWITCH_UNICABLE 1 +#define SWITCH_JESS 2 +#define SWITCH_SLAVE 3 + int switch_type; + /* parameters */ + int uslot; // unicable/jess slot + int ufreq; // unicable/jess frequency + int pin; + int only13v; // unicable - use 13V voltage only + int fast; // don't send diseqc without position change + int committed_no, uncommitted_no; // diseqc info + /* timing */ + int before_cmd; + int after_cmd; + int after_repeated_cmd; + int after_switch; + int after_burst; + int after_tone; +} diseqc; + typedef struct struct_transponder { fe_delivery_system_t sys; @@ -189,18 +211,8 @@ typedef struct struct_transponder int pol; int diseqc; -#define SWITCH_UNICABLE 1 -#define SWITCH_JESS 2 -#define SWITCH_SLAVE 3 - - int switch_type; // tuner type - int uslot; // unicable/jess slot - int ufreq; // unicable/jess frequency - int pin; - int only13v; // use only 13V voltage - int committed_no, uncommitted_no; //diseqc informations - int old_pol, old_hiband, old_diseqc; // used to cache the diseqc position - + diseqc diseqc_param; + // DVB-C2 int c2tft; int ds; diff --git a/dvbapi.c b/dvbapi.c index e832773..0bccd2e 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -991,25 +991,16 @@ void dvbapi_delete_keys_for_adapter(int aid) keys_del(i); } -SKey *k_tmp; _symbols dvbapi_sym[] = { -{ "key_enabled", VAR_AARRAY_INT8, keys, 1, MAX_KEYS, - (long int) &k_tmp[0].enabled - (long int) &k_tmp[0] }, -{ "key_hops", VAR_AARRAY_INT8, keys, 1, MAX_KEYS, (long int) &k_tmp[0].hops - - (long int) &k_tmp[0] }, -{ "key_ecmtime", VAR_AARRAY_INT, keys, 1, MAX_KEYS, (long int) &k_tmp[0].ecmtime - - (long int) &k_tmp[0] }, -{ "key_pmt", VAR_AARRAY_INT, keys, 1, MAX_KEYS, (long int) &k_tmp[0].pmt_pid - - (long int) &k_tmp[0] }, -{ "key_cardsystem", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, - (long int) &k_tmp[0].cardsystem - (long int) &k_tmp[0] }, -{ "key_reader", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, - (long int) &k_tmp[0].reader - (long int) &k_tmp[0] }, -{ "key_from", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, (long int) &k_tmp[0].from - - (long int) &k_tmp[0] }, -{ "key_protocol", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, - (long int) &k_tmp[0].protocol - (long int) &k_tmp[0] }, +{ "key_enabled", VAR_AARRAY_INT8, keys, 1, MAX_KEYS, offsetof(SKey, enabled) }, +{ "key_hops", VAR_AARRAY_INT8, keys, 1, MAX_KEYS, offsetof(SKey, hops) }, +{ "key_ecmtime", VAR_AARRAY_INT, keys, 1, MAX_KEYS, offsetof(SKey, ecmtime) }, +{ "key_pmt", VAR_AARRAY_INT, keys, 1, MAX_KEYS, offsetof(SKey, pmt_pid) }, +{ "key_cardsystem", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, offsetof(SKey, cardsystem) }, +{ "key_reader", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, offsetof(SKey, reader) }, +{ "key_from", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, offsetof(SKey, from) }, +{ "key_protocol", VAR_AARRAY_PSTRING, keys, 1, MAX_KEYS, offsetof(SKey, protocol) }, { NULL, 0, NULL, 0, 0 } }; diff --git a/html/status.html b/html/status.html index c4c91c0..5ec0d29 100644 --- a/html/status.html +++ b/html/status.html @@ -2,6 +2,33 @@ + Minisatip/$version$ on $http_host$ @@ -49,37 +76,37 @@ var max_adapters = 16; var max_streams = 64; var pol = ["", "(V)", "(H)", "(R)", "(L)"] var sys= [ "", "dvbc", "dvbcb", "dvbt", "dss", "dvbs", "dvbs2", "dvbh", "isdbt", "isdbs", "isdbc", "atsc", "atscmh", "dmbth", "cmmb", "dab", "dvbt2", "turbo", "dvbcc", "dvbc2" ] -var myTable= ""; - myTable+= ""; - myTable+=""; - myTable+=""; - myTable+=""; - myTable+=""; - myTable+=""; +var myTable= "
TunerStatusFrequencySR/BWSignalStreamsStreams Pids
"; + myTable+=""; + myTable+=""; + myTable+=""; + myTable+=""; + myTable+=""; + myTable+=""; for (var i=0; i"; + myTable+=""; var csys = ""; if(ad_sys[i] == 0) csys = ad_allsys[i]; else csys = sys[ad_sys[i]]; if(ad_enabled[i] == 1) - myTable+=""; }else{ myTable+="(" + ad_satip[i] + ")"; } - myTable+=""; + myTable+=""; if(ad_sys[i] == 0 || ad_sys[i] == 1 || ad_sys[i] == 2 || ad_sys[i] == 5 || ad_sys[i] == 6 || ad_sys[i] == 18 || ad_sys[i] == 19 ) - myTable+=""; + myTable+=""; else - myTable+=""; + myTable+=""; var signal = ""; if(ad_enabled[i] == 0) @@ -97,9 +124,9 @@ var myTable= "
TunerStatusFrequencySR/BWSignalStreamsStreams Pids
" + i + "" + csys; + myTable+="" + csys; else - myTable+="" + ad_allsys[i]; + myTable+="" + ad_allsys[i]; if(ad_type[i] == 1){ myTable+="(" + ad_phyad[i] + "," + ad_phyfd[i] +") " + ad_freq[i] + ""+pol[ad_pol[i]]+"" + ad_freq[i] + ""+pol[ad_pol[i]]+"" + ad_sr[i] + "" + ad_sr[i] + "" + ad_bw[i]/1000 + "MHZ" + ad_bw[i]/1000 + "MHZ
"; + myTable+=""; - myTable +="
Tuner< if(ad_ber[i] > 0) signal += " BER "+ad_ber[i]; } - myTable+="" + signal + " " + signal + " "; + myTable +=""; for(var j=0;j"; } - myTable +=""; + myTable +=""; for(var j=0;jIP servers in the network)\n \ * eg: -D 4 \n\ @@ -179,13 +210,23 @@ Help\n\ * -m xx: simulate xx as local mac address, generates UUID based on mac\n\ * eg: -m 001122334455 \n\ \n\ +" +#ifndef DISABLE_NETCVCLIENT +"\ * -n --netceiver if:count: use network interface (default vlan4) and look for netceivers\n\ * eg: -n vlan4:2 \n\ \n\ +" +#endif +#ifndef DISABLE_DVBCSA +"\ * -o --dvbapi host:port - specify the hostname and port for the dvbapi server (oscam) \n\ * eg: -o 192.168.9.9:9000 \n\ 192.168.9.9 is the host where oscam is running and 9000 is the port configured in dvbapi section in oscam.conf\n\ \n\ +" +#endif +"\ * -p url: specify playlist url using X_SATIPM3U header \n\ * eg: -p http://192.168.2.3:8080/playlist\n\ - this will add X_SATIPM3U tag into the satip description xml\n\ @@ -195,6 +236,9 @@ Help\n\ \n\ * -R --document-root directory: document root for the minisatip web page and images\n\ \n\ +" +#ifndef DISABLE_SATIPCLIENT +"\ * -s --satip-servers DELSYS:host:port - specify the remote satip host and port with delivery system DELSYS, it is possible to use multiple -s \n\ * DELSYS - can be one of: dvbs, dvbs2, dvbt, dvbt2, dvbc, dvbc2, isdbt, atsc, dvbcb ( - DVBC_ANNEX_B ) [default: dvbs2]\n\ host - the server of the satip server\n\ @@ -204,6 +248,9 @@ Help\n\ - specifies 1 dvbt satip server with address 192.168.1.3:554\n\ - specifies 1 dvbc satip server with address 192.168.1.4:554\n\ \n\ +" +#endif +"\ * -S --slave ADAPTER1,ADAPTER2-ADAPTER4[,..] - specify slave adapters \n\ * Allows specifying bonded adapters (multiple adapters connected with a splitter to the same LNB)\n\ Only one adapter needs to be master all others needs to have this parameter specified\n\ @@ -237,7 +284,26 @@ Help\n\ * eg: -y 5544 \n\ - changing this to a port > 1024 removes the requirement for minisatip to run as root\n\ \n\ -", +* -L --link-adapters mapping_string: link adapters (identical src,lo/hi,h/v)\n\ +\t* The format is: M1:S1[,[M2:S2]] - master:slave\n\ + * eg: 0:1,0:2,0:3 \n\ +\n\ +" +#ifdef AXE +"\ +* -L --link-adapters mapping_string: link adapters (identical src,lo/hi,h/v)\n\ +\t* The format is: M1:S1[,M2:S2] - master:slave\n\ + * eg: 0:1,0:2,0:3 \n\ +\n\ +* -Q --quattro quattro LNB config (H/H,H/V,L/H,L/V)\n\ +\n\ +* -U --axe-uinput adapterno: AXE unicable/jess input (0-3)\n\ +\n\ +* -M --skip-mpegts packets: skip initial MPEG-TS packets for AXE demuxer (default 35)\n\ +\n\ +" +#endif +, app_name, ADAPTER_BUFFER, DVR_BUFFER, opts.no_threads ? "DISABLED" : "ENABLED"); @@ -277,17 +343,24 @@ void set_options(int argc, char *argv[]) opts.satip_setup_pids = 0; opts.output_buffer = 512 * 1024; opts.satip_servers[0] = 0; - opts.document_root = "html"; + opts.document_root = "/usr/share/minisatip/html"; opts.xml_path = DESC_XML; opts.no_threads = 0; opts.th_priority = -1; + opts.diseqc_before_cmd = 15; + opts.diseqc_after_cmd = 54; + opts.diseqc_after_repeated_cmd = 15; + opts.diseqc_after_switch = 15; + opts.diseqc_after_burst = 15; + opts.diseqc_after_tone = 0; #ifdef __mips__ opts.no_threads = 1; #endif + opts.axe_skippkt = 35; memset(opts.playlist, 0, sizeof(opts.playlist)); while ((opt = getopt_long(argc, argv, - "flr:a:td:w:p:s:n:hc:b:m:p:e:x:u:j:o:gy:i:D:VR:S:TX:Y:", + "flr:a:td:w:p:s:n:hc:b:m:p:e:x:u:j:o:gy:i:q:D:VR:S:TX:Y:L:QU:M:", long_options, NULL)) != -1) { // printf("options %d %c %s\n",opt,opt,optarg); @@ -359,9 +432,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; } @@ -410,6 +486,12 @@ void set_options(int argc, char *argv[]) break; } + case DISEQC_TIMING_OPT: + { + set_diseqc_timing(optarg); + break; + } + case SLAVE_OPT: { set_slave_adapters(optarg); @@ -508,6 +590,33 @@ void set_options(int argc, char *argv[]) LOGL(0, "Not a valid path for the xml file") ; break; +#ifdef AXE + case LINK_OPT: + set_link_adapters(optarg); + break; + + case QUATTRO_OPT: + opts.quattro = 1; + break; + + case AXE_UNICINP_OPT: + opts.axe_unicinp = atoi(optarg); + if (opts.axe_unicinp < 0 || opts.axe_unicinp > 3) { + LOG("unicable input %d out of range, using 0", opts.axe_unicinp); + opts.axe_unicinp = 0; + } + break; + + case AXE_SKIP_PKT: + { + opts.axe_skippkt = atoi(optarg); + if (opts.axe_skippkt < 0) + opts.axe_skippkt = 0; + if (opts.axe_skippkt > 200) + opts.axe_skippkt = 200; + break; + } +#endif } } @@ -676,7 +785,6 @@ int read_rtsp(sockets * s) if (transport) { int s_timeout; - if (sid->timeout == 1) sid->timeout = opts.timeout_sec; @@ -1003,6 +1111,9 @@ int ssdp_reply(sockets * s) return 0; } +#ifdef AXE + axe_set_network_led(1); +#endif // not my uuid LOG("Received SSDP packet from %s:%d -> handle %d", get_socket_rhost(s->id, ra, sizeof(ra)), get_socket_rport(s->id), @@ -1138,7 +1249,11 @@ int main(int argc, char *argv[]) if (!opts.no_threads) set_socket_thread(sock_signal, start_new_thread("signal")); +#ifdef AXE + sockets_timeout(sock_signal, 400); +#else sockets_timeout(sock_signal, 1000); +#endif if (0 > (sock_bw = sockets_add(SOCK_TIMEOUT, NULL, -1, TYPE_UDP, NULL, NULL, (socket_action) calculate_bw))) diff --git a/minisatip.h b/minisatip.h old mode 100644 new mode 100755 index 403af34..3cd6977 --- a/minisatip.h +++ b/minisatip.h @@ -10,13 +10,15 @@ #define VERSION_BUILD "26" #define CC(a,b,c) #a b #c -#define VERSION CC(0.5.,VERSION_BUILD,) +#define VERSION CC(0.5.,VERSION_BUILD,-axe101) void set_options (int argc, char *argv[]); extern char pid_file[]; extern char app_name[], version[]; +#define offsetof(st, m) __builtin_offsetof(st, m) + #define copy32(a,i,v) { a[i] = ((v)>>24) & 0xFF;\ a[i+1] = ((v)>>16) & 0xFF;\ a[i+2] = ((v)>>8) & 0xFF;\ @@ -48,6 +50,9 @@ struct struct_opts int force_scan; int clean_psi; int file_line; + int quattro; + int axe_unicinp; + int axe_skippkt; char *last_log; int dvbapi_port; char *dvbapi_host; @@ -62,6 +67,15 @@ struct struct_opts char *xml_path; char no_threads; int th_priority; + int diseqc_fast; + int diseqc_committed_no; + int diseqc_uncommitted_no; + int diseqc_before_cmd; + int diseqc_after_cmd; + int diseqc_after_repeated_cmd; + int diseqc_after_switch; + int diseqc_after_burst; + int diseqc_after_tone; }; diff --git a/netceiver.c b/netceiver.c index e42023e..51ef642 100644 --- a/netceiver.c +++ b/netceiver.c @@ -457,7 +457,7 @@ void find_netcv_adapter(adapter **a) if (na >= MAX_ADAPTERS) break; if (!a[na]) - a[na] = malloc1(sizeof(adapter)); + a[na] = adapter_alloc(); if (!sn[na]) sn[na] = malloc1(sizeof(SNetceiver)); diff --git a/satipc.c b/satipc.c index 4fd5972..af3e8aa 100644 --- a/satipc.c +++ b/satipc.c @@ -831,13 +831,16 @@ void find_satip_adapter(adapter **a) return; la = split(arg, opts.satip_servers, 50, ','); j = 0; + for (i = 0; i < MAX_ADAPTERS; i++) { + + } for (i = a_count; i < MAX_ADAPTERS; i++) if (j < la) { if (is_adapter_disabled(i)) continue; if (!a[i]) - a[i] = malloc1(sizeof(adapter)); + a[i] = adapter_alloc(); if(!satip[i]) satip[i] = malloc1(sizeof(satipc)); sip = satip[i]; @@ -913,8 +916,7 @@ void find_satip_adapter(adapter **a) } -satipc *sip_tmp; _symbols satipc_sym[] ={ -{ "ad_satip", VAR_AARRAY_PSTRING, a, 1, MAX_ADAPTERS, (long int) &sip_tmp[0].sip - - (long int) &sip_tmp[0] } +{ "ad_satip", VAR_AARRAY_PSTRING, satip, 1, MAX_ADAPTERS, offsetof(satipc, sip) }, +{ NULL, 0, NULL, 0, 0 } }; diff --git a/socketworks.c b/socketworks.c index 4c91a40..192182f 100644 --- a/socketworks.c +++ b/socketworks.c @@ -431,6 +431,7 @@ int sockets_add(int sock, struct sockaddr_in *sa, int sid, int type, max_sock = i + 1; ss->buf = NULL; ss->lbuf = 0; + ss->skiplen = type == TYPE_DVR ? opts.axe_skippkt * 188 : 0; ss->close_sec = 0; ss->id = i; ss->read = (read_action) sockets_read; @@ -624,6 +625,29 @@ void *select_and_execute(void *arg) ss->rlen += rlen; else ss->rlen = 0; +#ifdef AXE + if (ss->type == TYPE_DVR) { + while (rlen > 0 && ss->lbuf - ss->rlen >= 1316) { + rlen = read (ss->sock, &ss->buf[ss->rlen], ss->lbuf - ss->rlen); + if (rlen > 0) + ss->rlen += rlen; + } + if (rlen == 0 || (rlen < 0 || errno == -EAGAIN)) + read_ok = 1; + if (ss->skiplen > 0 && ss->rlen > 0) { + LOG("AXE skip: before rlen %d skiplen %d", ss->rlen, ss->skiplen); + if (ss->skiplen >= ss->rlen) { + ss->skiplen -= ss->rlen; + ss->rlen = 0; + } else { + memmove(ss->buf, &ss->buf[ss->skiplen], ss->rlen - ss->skiplen); + ss->rlen = ss->rlen - ss->skiplen; + ss->skiplen = 0; + } + LOG("AXE skip: after rlen %d skiplen %d", ss->rlen, ss->skiplen); + } + } +#endif //force 0 at the end of the string if (ss->lbuf >= ss->rlen) ss->buf[ss->rlen] = 0; @@ -935,6 +959,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 c852e2a..aa4157c --- a/socketworks.h +++ b/socketworks.h @@ -23,6 +23,7 @@ typedef struct struct_sockets { unsigned char *buf; int lbuf; int rlen; + int skiplen; int close_sec; int id; // socket id int err; @@ -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 03fee8a..8a45437 100644 --- a/stream.c +++ b/stream.c @@ -277,7 +277,7 @@ int start_play(streams * sid, sockets * s) "Tune requested with no real parameters, ignoring ..."); } a_id = get_free_adapter(sid->tp.freq, sid->tp.pol, sid->tp.sys, - sid->tp.fe); + sid->tp.fe, sid->tp.diseqc); LOG("Got adapter %d on socket %d", a_id, s->id); if (a_id < 0) return -404; @@ -1293,17 +1293,12 @@ char* get_stream_pids(int s_id, char *dest, int max_size) return dest; } -streams *s_tmp; _symbols stream_sym[] = { -{ "st_enabled", VAR_AARRAY_INT8, st, 1, MAX_STREAMS, - (long int) &s_tmp[0].enabled - (long int) &s_tmp[0] }, -{ "st_play", VAR_AARRAY_INT, st, 1, MAX_STREAMS, (long int) &s_tmp[0].do_play - - (long int) &s_tmp[0] }, -{ "st_adapter", VAR_AARRAY_INT, st, 1, MAX_STREAMS, (long int) &s_tmp[0].adapter - - (long int) &s_tmp[0] }, -{ "st_useragent", VAR_AARRAY_STRING, st, 1, MAX_STREAMS, - (long int) &s_tmp[0].useragent - (long int) &s_tmp[0] }, +{ "st_enabled", VAR_AARRAY_INT8, st, 1, MAX_STREAMS, offsetof(streams, enabled) }, +{ "st_play", VAR_AARRAY_INT, st, 1, MAX_STREAMS, offsetof(streams, do_play) }, +{ "st_adapter", VAR_AARRAY_INT, st, 1, MAX_STREAMS, offsetof(streams, adapter) }, +{ "st_useragent", VAR_AARRAY_STRING, st, 1, MAX_STREAMS, offsetof(streams, useragent) }, { "st_rhost", VAR_FUNCTION_STRING, (void *) &get_stream_rhost, 0, 0, 0 }, { "st_rport", VAR_FUNCTION_INT, (void *) &get_stream_rport, 0, 0, 0 }, { "st_pids", VAR_FUNCTION_STRING, (void *) &get_stream_pids, 0, 0, 0 }, diff --git a/utils.c b/utils.c index eaa0317..8cb7c49 100644 --- a/utils.c +++ b/utils.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include #include @@ -1141,6 +1143,7 @@ pthread_t start_new_thread(char *name) void set_thread_prio(pthread_t tid, int prio) { +#if 0 int rv; struct sched_param param; memset( ¶m, 0, sizeof(struct sched_param) ); @@ -1148,6 +1151,12 @@ void set_thread_prio(pthread_t tid, int prio) if ( (rv = pthread_setschedparam( pthread_self(), SCHED_RR, ¶m )) ) LOG("pthread_setschedparam failed with error %d", rv); return; +#else + pid_t xtid; + xtid = syscall(SYS_gettid); + if (setpriority(PRIO_PROCESS, xtid, prio)) + LOG("setpriority(%d) failed with error %d", prio, errno); +#endif }