diff options
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, 0 insertions, 716 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 deleted file mode 100644 index 875749d..0000000 --- a/mcast/client/.svn/text-base/dvblo_handler.c.svn-base +++ /dev/null @@ -1,716 +0,0 @@ -/* - * (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); - } -} |