/* * Copyright (c) 2004-2007 Marcus Overhagen * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, * merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ #include #include #include #include #include #include #include // required on BeOS R5 #include #include "DVBCard.h" DVBCard::DVBCard(const char *path) : fInitStatus(B_OK) , fDev(-1) { printf("DVBCard opening %s\n", path); fDev = open(path, O_RDWR); if (fDev < 0) { printf("DVBCard opening %s failed\n", path); fInitStatus = B_ERROR; return; } dvb_frequency_info_t info; if (do_ioctl(fDev, DVB_GET_FREQUENCY_INFO, &info) < 0) { printf("DVB_GET_FREQUENCY_INFO failed with error %s\n", strerror(errno)); // close(fDev); // fDev = -1; // return; } fFreqMin = info.frequency_min; fFreqMax = info.frequency_max; fFreqStep = info.frequency_step; fCaptureActive = false; } DVBCard::~DVBCard() { if (fDev > 0) close(fDev); } status_t DVBCard::InitCheck() { return fInitStatus; } status_t DVBCard::GetCardType(dvb_type_t *type) { dvb_interface_info_t info; if (do_ioctl(fDev, DVB_GET_INTERFACE_INFO, &info) < 0) { printf("DVB_GET_INTERFACE_INFO failed with error %s\n", strerror(errno)); return errno; } if (info.version < 1) { printf("DVBCard::GetCardInfo wrong API version\n"); return B_ERROR; } *type = info.type; return B_OK; } status_t DVBCard::GetCardInfo(char *_name, int max_name_len, char *_info, int max_info_len) { dvb_interface_info_t info; if (do_ioctl(fDev, DVB_GET_INTERFACE_INFO, &info) < 0) { printf("DVB_GET_INTERFACE_INFO failed with error %s\n", strerror(errno)); return errno; } // strlcpy(_name, info.name, max_name_len); // strlcpy(_info, info.info, max_info_len); strcpy(_name, info.name); strcpy(_info, info.info); if (info.version < 1) { printf("DVBCard::GetCardInfo wrong API version\n"); return B_ERROR; } return B_OK; } status_t DVBCard::SetTuningParameter(const dvb_tuning_parameters_t& param) { if (fDev < 0) return B_NO_INIT; printf("DVBCard::SetTuningParameter:\n"); /* printf("frequency %lld\n", param.frequency); printf("inversion %d\n", param.inversion); printf("bandwidth %d\n", param.bandwidth); printf("modulation %d\n", param.modulation); printf("hierarchy %d\n", param.hierarchy); printf("code_rate_hp %d\n", param.code_rate_hp); printf("code_rate_lp %d\n", param.code_rate_lp); printf("transmission_mode %d\n", param.transmission_mode); printf("guard_interval %d\n", param.guard_interval); printf("symbolrate %d\n", param.symbolrate); printf("polarity %d\n", param.polarity); printf("agc_inversion %d\n", param.agc_inversion); */ params = param;// XXX temporary! // if (do_ioctl(fDev, DVB_SET_TUNING_PARAMETERS, const_cast(¶m)) < 0) { // if (do_ioctl(fDev, DVB_SET_TUNING_PARAMETERS, (void *)(¶m)) < 0) { if (ioctl(fDev, DVB_SET_TUNING_PARAMETERS, (void *)(¶m)) < 0) { printf("DVB_SET_TUNING_PARAMETERS failed with error %s\n", strerror(errno)); return errno; } dvb_status_t status; bigtime_t start = system_time(); bool has_lock = false; bool has_signal = false; bool has_carrier = false; do { if (do_ioctl(fDev, DVB_GET_STATUS, &status) < 0) { printf("DVB_GET_STATUS failed with error %s\n", strerror(errno)); return errno; } if (!has_signal && status & DVB_STATUS_SIGNAL) { has_signal = true; printf("got signal after %.6f\n", (system_time() - start) / 1e6); } if (!has_carrier && status & DVB_STATUS_CARRIER) { has_carrier = true; printf("got carrier after %.6f\n", (system_time() - start) / 1e6); } if (!has_lock && status & DVB_STATUS_LOCK) { has_lock = true; printf("got lock after %.6f\n", (system_time() - start) / 1e6); } if ((status & (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK)) == (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK)) break; snooze(25000); } while ((system_time() - start) < 5000000); if ((status & (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK)) != (DVB_STATUS_SIGNAL|DVB_STATUS_CARRIER|DVB_STATUS_LOCK)) { printf("DVB tuning failed! need these status flags: DVB_STATUS_SIGNAL, DVB_STATUS_CARRIER, DVB_STATUS_LOCK\n"); return B_ERROR; } return B_OK; } status_t DVBCard::GetTuningParameter(dvb_tuning_parameters_t *param) { // XXX get from CARD *param = params; return B_OK; } status_t DVBCard::GetSignalInfo(uint32 *ss, uint32 *ber, uint32 *snr) { if (do_ioctl(fDev, DVB_GET_SS, ss) < 0) { printf("DVB_GET_SS failed with error %s\n", strerror(errno)); return errno; } if (do_ioctl(fDev, DVB_GET_BER, ber) < 0) { printf("DVB_GET_BER failed with error %s\n", strerror(errno)); return errno; } if (do_ioctl(fDev, DVB_GET_SNR, snr) < 0) { printf("DVB_GET_SNR failed with error %s\n", strerror(errno)); return errno; } printf("ss %08lx, ber %08lx, snr %08lx\n", *ss, *ber, *snr); printf("ss %lu%%, ber %lu%%, snr %lu%%\n", *ss / (0xffffffff / 100), *ber / (0xffffffff / 100), *snr / (0xffffffff / 100)); return B_OK; } status_t DVBCard::CaptureStart() { printf("DVBCard::CaptureStart\n"); if (fCaptureActive) { printf("CaptureStart already called, doing nothing\n"); return B_OK; } if (do_ioctl(fDev, DVB_START_CAPTURE, 0) < 0) { printf("DVB_START_CAPTURE failed with error %s\n", strerror(errno)); return errno; } fCaptureActive = true; return B_OK; } status_t DVBCard::CaptureStop() { printf("DVBCard::CaptureStop\n"); if (!fCaptureActive) { printf("CaptureStop already called, doing nothing\n"); return B_OK; } if (do_ioctl(fDev, DVB_STOP_CAPTURE, 0) < 0) { printf("DVB_STOP_CAPTURE failed with error %s\n", strerror(errno)); return errno; } fCaptureActive = false; return B_OK; } status_t DVBCard::Capture(void **data, size_t *size, bigtime_t *end_time) { dvb_capture_t cap; if (ioctl(fDev, DVB_CAPTURE, &cap) < 0) return errno; *data = cap.data; *size = cap.size; *end_time = cap.end_time; return B_OK; } int DVBCard::do_ioctl(int fDev, ulong op, void *arg) { int res = 0; // silence stupid compiler warning int i; for (i = 0; i < 20; i++) { res = ioctl(fDev, op, arg); if (res >= 0) break; } if (i != 0) printf("ioctl %lx repeated %d times\n", op, i); return res; }