diff options
author | Lars Heer <l.heer@gmx.de> | 2013-09-18 05:50:03 +0200 |
---|---|---|
committer | Lars Heer <l.heer@gmx.de> | 2013-09-18 05:50:03 +0200 |
commit | ccf6e0f9c6b0481ed13e0f4794e3fbead750f385 (patch) | |
tree | ed86efb54f7ee41edfba5c89ca519b5fd10aa0d5 /mcast/client/.svn/text-base/dvblo_handler.c.svn-base | |
download | vdr-plugin-mcli-ccf6e0f9c6b0481ed13e0f4794e3fbead750f385.tar.gz vdr-plugin-mcli-ccf6e0f9c6b0481ed13e0f4794e3fbead750f385.tar.bz2 |
added vdr-plugin-mcli-0.0.1+svn20120927
Diffstat (limited to 'mcast/client/.svn/text-base/dvblo_handler.c.svn-base')
-rw-r--r-- | mcast/client/.svn/text-base/dvblo_handler.c.svn-base | 716 |
1 files changed, 716 insertions, 0 deletions
diff --git a/mcast/client/.svn/text-base/dvblo_handler.c.svn-base b/mcast/client/.svn/text-base/dvblo_handler.c.svn-base new file mode 100644 index 0000000..875749d --- /dev/null +++ b/mcast/client/.svn/text-base/dvblo_handler.c.svn-base @@ -0,0 +1,716 @@ +/* + * (c) BayCom GmbH, http://www.baycom.de, info@baycom.de + * + * See the COPYING file for copyright information and + * how to reach the author. + * + */ + +#include "headers.h" +#include "dvblo_ioctl.h" +#include "dvblo_handler.h" + +//#define SHOW_EVENTS +//#define SHOW_TPDU +//#define SHOW_PIDS + +#define TUNE_FORCED_TIMEOUT 5 + +extern pthread_mutex_t lock; +extern recv_info_t receivers; + +static dvblo_dev_t devs; +static int dev_num = 0; +static int dvblo_run = 1; +static int cidev = 0; +static int reload = 0; +static dvblo_cacaps_t cacaps; + +static int special_status_mode=0; // 1: return rotor mode and tuner slot in status + +static int dvblo_get_nc_addr (char *addrstr, char *uuid) +{ + int len = strlen (uuid); + if (len <= 5) { + return -1; + } + memset (addrstr, 0, INET6_ADDRSTRLEN); + + strncpy (addrstr, uuid, len - 5); + return 0; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_handle_ts (unsigned char *buffer, size_t len, void *p) +{ + dvblo_dev_t * d=( dvblo_dev_t *)p; + return write (d->fd, buffer, len); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_handle_ten (tra_t * ten, void *c) +{ + dvblo_dev_t *d = (dvblo_dev_t *) c; + dbg ("TEN: %ld %p %p\n", gettid (), ten, d); + + if (ten) { + dvblo_festatus_t stat; + memcpy(&stat, &ten->s, sizeof(dvblo_festatus_t)); + + d->ten = *ten; + + if (special_status_mode) { + stat.st|=(ten->rotor_status&3)<<8; + stat.st|=(1+ten->slot)<<12; + } + + return ioctl (d->fd, DVBLO_SET_FRONTEND_STATUS, (dvblo_festatus_t*)&stat); + } else { + dvblo_festatus_t s; + memset (&s, 0, sizeof (dvblo_festatus_t)); + + return ioctl (d->fd, DVBLO_SET_FRONTEND_STATUS, &s); + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void sig_handler (int signal) +{ + dbg ("Signal: %d\n", signal); + + switch (signal) { + case SIGHUP: + reload = 1; + break; + case SIGTERM: + case SIGINT: + dbg ("Trying to exit, got signal %d...\n", signal); + dvblo_run = 0; + break; + } +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int dvblo_init (void) +{ + char char_dev[100]; + int j, k = 0; + struct dvb_frontend_info fe_info; + dvblo_festatus_t fe_status; + + dvbmc_list_init (&devs.list); + + memset (&fe_info, 0, sizeof (struct dvb_frontend_info)); + fe_info.type = -1; + strcpy (fe_info.name, "Unconfigured"); + memset (&fe_status, 0, sizeof (dvblo_festatus_t)); + + for (j = 0; j < MAX_DEVICES; j++) { + + sprintf (char_dev, "/dev/dvblo%d", j); + int fd = open (char_dev, O_RDWR); + + if (fd == -1) { + warn ("Cannot Open %s\n", char_dev); + continue; + } + k++; + ioctl (fd, DVBLO_SET_FRONTEND_INFO, &fe_info); + ioctl (fd, DVBLO_SET_FRONTEND_STATUS, &fe_status); + ioctl (fd, DVBLO_SET_CA_CAPS, &cacaps); + dvblo_tpdu_t tpdu; + while (1) { + if (ioctl (fd, DVBLO_GET_TPDU, &tpdu) || !tpdu.len) { + break; + } + } + close (fd); + } + + signal (SIGTERM, &sig_handler); + signal (SIGINT, &sig_handler); + signal (SIGHUP, &sig_handler); + signal (SIGPIPE, &sig_handler); + return k; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_convert_pids (dvblo_dev_t * d) +{ + dvb_pid_t *dst = d->dstpids; + dvblo_pids_t *src = &d->pids; + int i; +#ifdef SHOW_PIDS + info ("devnum:%d pidnum:%d\n", d->device, src->num); +#endif + for (i = 0; i < src->num; i++) { +#ifdef SHOW_PIDS + printf ("devnum:%d pid:%04x\n", d->device, src->pid[i]); +#endif + dst[i].pid = src->pid[i]; + if (d->ca_enable) { + dst[i].id = ci_cpl_find_caid_by_pid (src->pid[i]); + if (dst[i].id != 0) { + dbg ("pid: %04x id: %04x\n", dst[i].pid, dst[i].id); + } + } + } + dst[i].pid = -1; + return i; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int dvblo_tune (dvblo_dev_t * d, int force) +{ + satellite_reference_t satref; + int SatPos; + int mode; + int ret = 0; + + nc_lock_list (); + + for (mode = 0; mode < 3; mode++) { + if (satellite_find_by_diseqc (&satref, (recv_sec_t*)&d->sec, &d->fe_parms, mode)) + break; + } + + if (mode == 3 || (mode == 2 && (d->type == FE_QAM || d->type == FE_OFDM))) { + SatPos = NO_SAT_POS; + } else { + int LOF = 0; + if (mode) { + LOF = satellite_get_lof_by_ref (&satref); + d->fe_parms.frequency += LOF * 1000; + } + SatPos = satellite_get_pos_by_ref (&satref); + recv_sec_t *sec=satellite_find_sec_by_ref (&satref); + memcpy(&d->sec, sec, sizeof(recv_sec_t)); + d->sec.voltage = satellite_find_pol_by_ref (&satref); +#if 1 //def SHOW_EVENTS + printf ("Found satellite position: %d fe_parms: %d LOF: %d voltage: %d mode: %d\n", SatPos, d->fe_parms.frequency, LOF, d->sec.voltage, mode); +#endif + } + nc_unlock_list (); + if (force && d->pids.num == 0) { + d->dstpids[0].pid = 0; + d->dstpids[0].id = 0; + d->dstpids[1].pid = -1; + ret = 2; + } else { + dvblo_convert_pids (d); + } + recv_tune (d->r, d->type, SatPos, (recv_sec_t*)&d->sec, &d->fe_parms, d->dstpids); + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +int dvblo_write_ci (ci_pdu_t * pdu, void *context) +{ + dvblo_dev_t *d = (dvblo_dev_t *) context; + dvblo_tpdu_t tpdu; + memcpy (tpdu.data, pdu->data, pdu->len); + tpdu.len = pdu->len; + if (!cmd.reelcammode) + tpdu.data[0] = 0; + return ioctl (d->fd, DVBLO_SET_TPDU, &tpdu); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void clean_dvblo_recv_thread (void *argp) +{ + dvblo_dev_t *d = (dvblo_dev_t *) argp; + recv_del (d->r); + close (d->fd); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void *dvblo_recv (void *argp) +{ + dvblo_dev_t *d = (dvblo_dev_t *) argp; + dvblo_tpdu_t tpdu; + struct dvb_frontend_parameters old_fe_parms; + dvblo_sec_t old_sec; + struct pollfd fds[1]; + int timeout_msecs = 50; + int ret; + time_t last_ci_reset = 0; + char char_dev[100]; + int need_tune = 0; + time_t forced = 0; + unsigned int event = 0; + + dvblo_cacaps_t cacap; + + sprintf (char_dev, "/dev/dvblo%d", d->device); + dbg ("Using character device %s for dvb loopback\n", char_dev); + + d->fd = open (char_dev, O_RDWR); + + if (d->fd < 0) { + err ("Cannot open %s - dvbloop driver loaded?\n", char_dev); + } + + pthread_cleanup_push (clean_dvblo_recv_thread, d); + + fds[0].fd = d->fd; + + if (!ioctl (d->fd, DVBLO_IOCCHECKDEV)) { + if (!ioctl (d->fd, DVBLO_IOCADDDEV)) { + info ("created dvb adapter: %d\n", d->device); + } + } + d->info.frequency_min = 1; + d->info.frequency_max = 2000000000; + + ioctl (d->fd, DVBLO_SET_FRONTEND_INFO, &d->info); + ioctl (d->fd, DVBLO_GET_FRONTEND_PARAMETERS, &d->fe_parms); + ioctl (d->fd, DVBLO_GET_PIDLIST, &d->pids); + ioctl (d->fd, DVBLO_GET_SEC_PARAMETERS, &d->sec); + + old_fe_parms = d->fe_parms; + old_sec = d->sec; +#ifdef DEBUG + print_fe_info (&d->info); +#endif + d->recv_run = 1; + + if (dvblo_tune (d, 1) == 2) { + forced = time (NULL); + } + + while (d->recv_run) { + if (d->cacaps->cap.slot_num) { + nc_lock_list (); +#ifdef SHOW_TPDU + info ("ca_caps->: %p ci_slot:%d info[0]:%02x info[1]:%02x\n", d->cacaps, d->ci_slot, d->cacaps->info[0].flags, d->cacaps->info[1].flags); +#endif + cacap = *d->cacaps; + if (!cmd.reelcammode) { + if (d->ci_slot != 0) { + cacap.info[0] = cacap.info[d->ci_slot]; + } + cacap.cap.slot_num = 1; + } + if ((time (NULL) - last_ci_reset) < cmd.ci_timeout) { + cacap.info[0].flags = 0; + } + ioctl (d->fd, DVBLO_SET_CA_CAPS, &cacap); + nc_unlock_list (); + } + + fds[0].events = POLLIN; + ret = poll (fds, 1, timeout_msecs); + if (ret > 0) { + ioctl (d->fd, DVBLO_GET_EVENT_MASK, &event); + ioctl (d->fd, DVBLO_GET_FRONTEND_PARAMETERS, &d->fe_parms); + ioctl (d->fd, DVBLO_GET_PIDLIST, &d->pids); + ioctl (d->fd, DVBLO_GET_SEC_PARAMETERS, &d->sec); + if (event & EV_MASK_FE) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: FE+Tuner/", d, d->r); + if (event & EV_FRONTEND) { + printf ("Frontend "); + } + if (event & EV_TUNER) { + printf ("Tuner "); + } + if (event & EV_FREQUENCY) { + printf ("Frequency:%d ", d->fe_parms.frequency); + } + if (event & EV_BANDWIDTH) { + printf ("Bandwidth "); + } + printf ("\n"); +#endif + if (memcmp (&d->fe_parms, &old_fe_parms, sizeof (struct dvb_frontend_parameters))) { + old_fe_parms = d->fe_parms; + dbg ("fe_parms have changed!\n"); + need_tune = 1; + if (d->ca_enable) { + ci_cpl_clear (d->ci_slot); + } + } + } + if (event & EV_MASK_SEC) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: SEC/", d, d->r); + if (event & EV_TONE) { + printf ("Tone:%d ", d->sec.tone_mode); + } + if (event & EV_VOLTAGE) { + printf ("Voltage:%d ", d->sec.voltage); + } + if (event & EV_DISEC_MSG) { + printf ("DISEC-Message:"); + int j; + for (j = 0; j < d->sec.diseqc_cmd.msg_len; j++) { + printf ("%02x ", d->sec.diseqc_cmd.msg[j]); + } + } + if (event & EV_DISEC_BURST) { + printf ("DISEC-Burst:%d ", d->sec.mini_cmd); + } + printf ("\n"); +#endif + if (d->sec.voltage == SEC_VOLTAGE_OFF) { + recv_stop (d->r); + memset (&old_fe_parms, 0, sizeof (struct dvb_frontend_parameters)); + need_tune = 0; + dbg ("Stop %p\n", d->r); + } else if (memcmp (&d->sec, &old_sec, sizeof (dvblo_sec_t))) { + dbg ("SEC parms have changed!\n"); + old_sec = d->sec; + need_tune = 1; + if (d->ca_enable) { + ci_cpl_clear (d->ci_slot); + } + } + } + if (event & EV_MASK_CA) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: CA/", d, d->r); +#endif + if (event & EV_CA_WRITE) { +#ifdef SHOW_EVENTS + printf ("WRITE "); +#endif + while (1) { + if (!ioctl (d->fd, DVBLO_GET_TPDU, &tpdu) && tpdu.len) { + if (d->c && d->ca_enable) { + ci_pdu_t pdu; + pdu.len = tpdu.len; + pdu.data = tpdu.data; + if (!cmd.reelcammode) { + pdu.data[0] = d->ci_slot; + } + ci_write_pdu (d->c, &pdu); + event |= EV_PIDFILTER; + } + } else { + break; + } + } + } + if (event & EV_CA_RESET) { +#ifdef SHOW_EVENTS + printf ("RESET "); +#endif + last_ci_reset = time (NULL); + if (d->ca_enable) { + ci_cpl_clear (d->ci_slot); + } + } +#ifdef SHOW_EVENTS + printf ("\n"); +#endif + } + if (need_tune) { + if (dvblo_tune (d, 1) == 2) { + forced = time (NULL); + } + need_tune = 0; + } else if (event & EV_MASK_PID) { +#ifdef SHOW_EVENTS + printf ("%p/%p Event Received: Demux/", d, d->r); + if (event & EV_PIDFILTER) { + printf ("PID filter: %d pids", d->pids.num); + } + printf ("\n"); +#endif + forced = 0; + } + } + if (forced) { + if ((time (NULL) - forced) < TUNE_FORCED_TIMEOUT) { + event &= ~EV_PIDFILTER; + } else { + event |= EV_PIDFILTER; + forced = 0; + } + } + if (event & EV_PIDFILTER) { + dvblo_convert_pids (d); + recv_pids (d->r, d->dstpids); + } + event = 0; + } + pthread_cleanup_pop (1); + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static dvblo_dev_t *dvblo_add (void) +{ + dvblo_dev_t *d = (dvblo_dev_t *) malloc (sizeof (dvblo_dev_t)); + + if (!d) + return NULL; + memset (d, 0, sizeof (dvblo_dev_t)); + dvbmc_list_add_head (&devs.list, &d->list); + return d; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static void dvblo_del (dvblo_dev_t * d) +{ + d->recv_run = 0; + if (pthread_exist(d->dvblo_recv_thread) && !pthread_cancel (d->dvblo_recv_thread)) { + pthread_join (d->dvblo_recv_thread, NULL); + } + dvbmc_list_remove (&d->list); + free (d); +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +void dvblo_exit (void) +{ + dvblo_dev_t *d; + dvblo_dev_t *dtmp; + + DVBMC_LIST_FOR_EACH_ENTRY_SAFE (d, dtmp, &devs.list, dvblo_dev_t, list) { + dvblo_del (d); + } +} + +static dvblo_dev_t *find_dev_by_uuid (dvblo_dev_t * devs, char *uuid) +{ + dvblo_dev_t *d; + DVBMC_LIST_FOR_EACH_ENTRY (d, &devs->list, dvblo_dev_t, list) { + if (!strcmp (d->uuid, uuid)) { + return d; + } + } + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int count_dev_by_type (dvblo_dev_t * devs, fe_type_t type) +{ + int ret = 0; + dvblo_dev_t *d; + DVBMC_LIST_FOR_EACH_ENTRY (d, &devs->list, dvblo_dev_t, list) { + if (type == d->type) { + ret++; + } + } + return ret; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +satellite_list_t *dvblo_get_sat_list (char *SatelliteListName, netceiver_info_t * nci) +{ + int i; + dbg ("looking for %s\n", SatelliteListName); + for (i = 0; i < nci->sat_list_num; i++) { + if (!strcmp (SatelliteListName, nci->sat_list[i].Name)) { + dbg ("found uuid in sat list %d\n", i); + return nci->sat_list + i; + } + } + return NULL; +} + +//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +static int diseqc_write_conf (char *disec_conf_path, char *rotor_conf_path, dvblo_dev_t * devs, int mode) +{ + int j, k; + dvblo_dev_t *d; + char buf[80]; + char tstr[16]; + FILE *f = NULL; + FILE *fr = NULL; + + f = fopen (disec_conf_path, "wt"); + if (f == NULL) { + return 0; + } + fprintf (f, "# diseqc.conf in VDR format auto generated\n\n"); + + if (strlen(rotor_conf_path)) { + special_status_mode=1; + fr = fopen (rotor_conf_path, "wt"); + } + if (fr) + fprintf (fr, "# rotor.conf auto generated\n\n"); + + DVBMC_LIST_FOR_EACH_ENTRY (d, &devs->list, dvblo_dev_t, list) { + satellite_list_t *sat_list = dvblo_get_sat_list (d->nci->tuner[d->tuner].SatelliteListName, d->nci); + if (!sat_list) { + continue; + } + for (j = 0; j < sat_list->sat_num; j++) { + satellite_info_t *sat = sat_list->sat + j; + for (k = 0; k < sat->comp_num; k++) { + satellite_component_t *comp = sat->comp + k; + int newpos = sat->SatPos ^ 1800; + sprintf (buf, "e0 10 6f %02x %02x %02x", newpos & 0xff, (newpos >> 8) & 0xff, comp->Polarisation << 1 | !(comp->sec.tone_mode & 1)); + if (mode) { + sprintf (tstr, "A%d ", d->device + 1); + } else { + tstr[0] = 0; + } + fprintf (f, "%s%s %d %c 0 [ %s ]\n", tstr, sat->Name, comp->RangeMax, comp->Polarisation == POL_H ? 'H' : 'V', buf); + } + fprintf (f, "\n"); + if (j==0 && fr && sat->type==SAT_SRC_ROTOR) { + fprintf(fr, "%s %i %i %i %i %i\n", tstr, sat->SatPosMin, sat->SatPosMax, + sat->AutoFocus, sat->Latitude, sat->Longitude); + } + } + } + info ("created %s\n", disec_conf_path); + fclose (f); + if (fr) { + info ("created %s\n", rotor_conf_path); + fclose(fr); + } + return 1; +} + +void dvblo_handler (void) +{ + int i; + int n; + int nci_num = 0; + int write_conf = strlen (cmd.disec_conf_path); + netceiver_info_list_t *nc_list = nc_get_list (); + memset (&cacaps, 0, sizeof (dvblo_cacaps_t)); + + info ("Device Type Limits: DVB-S: %d DVB-C: %d DVB-T: %d ATSC: %d DVB-S2: %d\n\n", cmd.tuner_type_limit[FE_QPSK], cmd.tuner_type_limit[FE_QAM], cmd.tuner_type_limit[FE_OFDM], cmd.tuner_type_limit[FE_ATSC], cmd.tuner_type_limit[FE_DVBS2]); + + while (dvblo_run) { + nc_lock_list (); + for (n = 0; n < nc_list->nci_num; n++) { + netceiver_info_t *nci = nc_list->nci + n; + for (i = 0; i < nci->tuner_num; i++) { + char *uuid = nci->tuner[i].uuid; + if (nci->tuner[i].preference < 0 || !strlen (uuid) || find_dev_by_uuid (&devs, uuid)) { + //already seen + continue; + } + fe_type_t type = nci->tuner[i].fe_info.type; + + if (type > FE_DVBS2) { + continue; + } + if(dev_num >= MAX_DEVICES) { + dbg("Limit dev_num reached limit of "MAX_DEVICES"\n"); + continue; + } + if (count_dev_by_type (&devs, type) == cmd.tuner_type_limit[type]) { + dbg ("Limit: %d %d>%d\n", type, count_dev_by_type (&devs, type), cmd.tuner_type_limit[type]); + continue; + } + + dvblo_dev_t *d = dvblo_add (); + if (!d) { + err ("Cannot get memory for dvb loopback context\n"); + } + + dbg ("allocate dev %d for uuid %s\n", dev_num, uuid); + + d->info = nci->tuner[i].fe_info; + + if (type == FE_DVBS2) { + d->info.type = FE_QPSK; + } + + strcpy (d->uuid, nci->tuner[i].uuid); + if (!cmd.reelcammode) { + if (cidev < CA_MAX_SLOTS && (cmd.ca_enable & (1 << dev_num))) { + d->cacaps=(dvblo_cacaps_t*)((void *) &nci->ci); + d->ca_enable = 1; + dbg ("Enabling CA support for device %d\n", dev_num); + char addrstr[INET6_ADDRSTRLEN]; + dvblo_get_nc_addr (addrstr, d->uuid); + dbg ("dvblo_get_nc_addr: %s %s\n", addrstr, d->uuid); + d->c = ci_find_dev_by_uuid (addrstr); + if (d->c) { + dbg ("Attaching ci dev %p to dvblo dev %p\n", d->c, d); + ci_register_handler (d->c, cidev, dvblo_write_ci, d); + d->ci_slot = cidev++; + } else { + dvblo_del (d); //retry next time + break; + } + } else { + d->cacaps = &cacaps; + d->ca_enable = 0; + dbg ("Disabling CA support for device %d\n", dev_num); + } + } else { + if (nci->ci.cap.slot_num && cmd.ca_enable) { + d->ca_enable = 1; + dbg ("Enabling CA support for device %d\n", dev_num); + if (!cidev) { + d->cacaps = (dvblo_cacaps_t*)((void *) &nci->ci); + char addrstr[INET6_ADDRSTRLEN]; + dvblo_get_nc_addr (addrstr, d->uuid); + dbg ("dvblo_get_nc_addr: %s %s\n", addrstr, d->uuid); + d->c = ci_find_dev_by_uuid (addrstr); + if (d->c) { + dbg ("Attaching ci dev %p to dvblo dev %p\n", d->c, d); + ci_register_handler (d->c, cidev++, dvblo_write_ci, d); + ci_register_handler (d->c, cidev++, dvblo_write_ci, d); + } else { + dvblo_del (d); //retry next time + break; + } + } else { + d->cacaps = &cacaps; + } + } else { + d->cacaps = &cacaps; + d->ca_enable = 0; + dbg ("Disabling CA support for device %d\n", dev_num); + } + } + + d->r = recv_add (); + if (!d->r) { + err ("Cannot get memory for receiver\n"); + } + + d->device = dev_num++; + d->type = type; + d->tuner = i; + d->nci = nci; + + register_ten_handler (d->r, dvblo_handle_ten, d); + register_ts_handler (d->r, dvblo_handle_ts, d); + + info ("Starting thread for tuner UUID %s [%s] at device %d with type %d\n", d->uuid, nci->tuner[i].fe_info.name, nci->tuner[i].slot, nci->tuner[i].fe_info.type); + int ret = pthread_create (&d->dvblo_recv_thread, NULL, dvblo_recv, d); + while (!ret && !d->recv_run) { + usleep (10000); + } + if (ret) { + err ("pthread_create failed with %d\n", ret); + } + } + } + if (write_conf) { + if (reload || (nci_num != nc_list->nci_num)) { + nci_num = nc_list->nci_num; + diseqc_write_conf (cmd.disec_conf_path, cmd.rotor_conf_path, &devs, cmd.vdrdiseqcmode); + reload = 0; + } + } + nc_unlock_list (); + sleep (1); + } +} |