DvbManager.cpp revision 1abddd9f6225298066094e20a6c29061b6af4590
11abddd9f6225298066094e20a6c29061b6af4590Nick Chalko/* 21abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Copyright (C) 2015 The Android Open Source Project 31abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 41abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Licensed under the Apache License, Version 2.0 (the "License"); 51abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * you may not use this file except in compliance with the License. 61abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * You may obtain a copy of the License at 71abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 81abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * http://www.apache.org/licenses/LICENSE-2.0 91abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * 101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * Unless required by applicable law or agreed to in writing, software 111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * distributed under the License is distributed on an "AS IS" BASIS, 121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * See the License for the specific language governing permissions and 141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko * limitations under the License. 151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko */ 161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 171abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <stdio.h> 181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <stdlib.h> 191abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <errno.h> 201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <unistd.h> 211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <limits.h> 221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <string.h> 231abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <fcntl.h> 241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <sys/poll.h> 251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <sys/ioctl.h> 261abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <linux/dvb/dmx.h> 271abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include <linux/dvb/frontend.h> 281abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#define LOG_TAG "DvbManager" 301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include "logging.h" 311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko#include "DvbManager.h" 331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 341abddd9f6225298066094e20a6c29061b6af4590Nick Chalkostatic double currentTimeMillis() { 351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko struct timeval tv; 361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko gettimeofday(&tv, (struct timezone *) NULL); 371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0; 381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 391abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 401abddd9f6225298066094e20a6c29061b6af4590Nick ChalkoDvbManager::DvbManager(JNIEnv *env, jobject) 411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko : mFeFd(-1), 421abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mDemuxFd(-1), 431abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mDvrFd(-1), 441abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mPatFilterFd(-1), 451abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mFeHasLock(false) { 461abddd9f6225298066094e20a6c29061b6af4590Nick Chalko jclass clazz = env->FindClass( 471abddd9f6225298066094e20a6c29061b6af4590Nick Chalko "com/android/usbtuner/UsbTunerInterface"); 481abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mOpenDvbFrontEndMethodID = env->GetMethodID( 491abddd9f6225298066094e20a6c29061b6af4590Nick Chalko clazz, "openDvbFrontEndFd", "()I"); 501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mOpenDvbDemuxMethodID = env->GetMethodID( 511abddd9f6225298066094e20a6c29061b6af4590Nick Chalko clazz, "openDvbDemuxFd", "()I"); 521abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mOpenDvbDvrMethodID = env->GetMethodID( 531abddd9f6225298066094e20a6c29061b6af4590Nick Chalko clazz, "openDvbDvrFd", "()I"); 541abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 551abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 561abddd9f6225298066094e20a6c29061b6af4590Nick ChalkoDvbManager::~DvbManager() { 571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko reset(); 581abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 591abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 601abddd9f6225298066094e20a6c29061b6af4590Nick Chalkobool DvbManager::isFeLocked() { 611abddd9f6225298066094e20a6c29061b6af4590Nick Chalko struct dvb_frontend_event kevent; 621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko memset(&kevent, 0, sizeof(kevent)); 631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (ioctl(mFeFd, FE_READ_STATUS, &kevent.status) == 0) { 641abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return (kevent.status & FE_HAS_LOCK); 651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 661abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return false; 671abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 681abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 691abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::tuneAtsc(JNIEnv *env, jobject thiz, 701abddd9f6225298066094e20a6c29061b6af4590Nick Chalko const int frequency, const char *modulationStr, int timeout_ms) { 711abddd9f6225298066094e20a6c29061b6af4590Nick Chalko resetExceptFe(); 721abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko struct dvb_frontend_parameters feParams; 741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko memset(&feParams, 0, sizeof(struct dvb_frontend_parameters)); 751abddd9f6225298066094e20a6c29061b6af4590Nick Chalko feParams.frequency = frequency; 761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (strcmp(modulationStr, "8VSB") == 0) { 771abddd9f6225298066094e20a6c29061b6af4590Nick Chalko feParams.u.vsb.modulation = VSB_8; 781abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } else if (strcmp(modulationStr, "QAM256") == 0) { 791abddd9f6225298066094e20a6c29061b6af4590Nick Chalko feParams.u.vsb.modulation = QAM_256; 801abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } else { 811abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGE("Unrecognized modulation mode : %s", modulationStr); 821abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 841abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 851abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (openDvbFe(env, thiz) != 0) { 861abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 871abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 891abddd9f6225298066094e20a6c29061b6af4590Nick Chalko feParams.inversion = INVERSION_AUTO; 901abddd9f6225298066094e20a6c29061b6af4590Nick Chalko /* Check frontend capability */ 911abddd9f6225298066094e20a6c29061b6af4590Nick Chalko struct dvb_frontend_info feInfo; 921abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (ioctl(mFeFd, FE_GET_INFO, &feInfo) != -1) { 931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (!(feInfo.caps & FE_CAN_INVERSION_AUTO)) { 941abddd9f6225298066094e20a6c29061b6af4590Nick Chalko // FE can't do INVERSION_AUTO, trying INVERSION_OFF instead 951abddd9f6225298066094e20a6c29061b6af4590Nick Chalko feParams.inversion = INVERSION_OFF; 961abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 971abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 981abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 991abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (ioctl(mFeFd, FE_SET_FRONTEND, &feParams) != 0) { 1001abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGD("Can't set Frontend : %s", strerror(errno)); 1011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 1021abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1031abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko int lockSuccessCount = 0; 1051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko double tuneClock = currentTimeMillis(); 1061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko while (currentTimeMillis() - tuneClock < timeout_ms) { 1071abddd9f6225298066094e20a6c29061b6af4590Nick Chalko usleep(FE_LOCK_CHECK_INTERNAL_US); 1081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko bool lockStatus = isFeLocked(); 1101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (lockStatus) { 1111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko lockSuccessCount++; 1121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } else { 1131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko lockSuccessCount = 0; 1141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGI("Lock status : %s", lockStatus ? "true" : "false"); 1161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (lockSuccessCount >= FE_CONSECUTIVE_LOCK_SUCCESS_COUNT) { 1171abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mFeHasLock = true; 1181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko openDvbDvr(env, thiz); 1191abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return 0; 1201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1231abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 1241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 1251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1261abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::stopTune() { 1271abddd9f6225298066094e20a6c29061b6af4590Nick Chalko reset(); 1281abddd9f6225298066094e20a6c29061b6af4590Nick Chalko usleep(DVB_TUNE_STOP_DELAY_MS); 1291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return 0; 1301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 1311abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1321abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::openDvbFeFromSystemApi(JNIEnv *env, jobject thiz) { 1331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko int fd = (int) env->CallIntMethod(thiz, mOpenDvbFrontEndMethodID); 1341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 1351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return fd; 1361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 1371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1381abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::openDvbDemuxFromSystemApi(JNIEnv *env, jobject thiz) { 1391abddd9f6225298066094e20a6c29061b6af4590Nick Chalko int fd = (int) env->CallIntMethod(thiz, mOpenDvbDemuxMethodID); 1401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 1411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return fd; 1421abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 1431abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1441abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::openDvbDvrFromSystemApi(JNIEnv *env, jobject thiz) { 1451abddd9f6225298066094e20a6c29061b6af4590Nick Chalko int fd = (int) env->CallIntMethod(thiz, mOpenDvbDvrMethodID); 1461abddd9f6225298066094e20a6c29061b6af4590Nick Chalko fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 1471abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return fd; 1481abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 1491abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1501abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::openDvbFe(JNIEnv *env, jobject thiz) { 1511abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (mFeFd == -1) { 1521abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if ((mFeFd = openDvbFeFromSystemApi(env, thiz)) < 0) { 1531abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGD("Can't open FE file : %s", strerror(errno)); 1541abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 1551abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1561abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1581abddd9f6225298066094e20a6c29061b6af4590Nick Chalko struct dvb_frontend_info info; 1591abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (ioctl(mFeFd, FE_GET_INFO, &info) == 0) { 1601abddd9f6225298066094e20a6c29061b6af4590Nick Chalko const char *types; 1611abddd9f6225298066094e20a6c29061b6af4590Nick Chalko switch (info.type) { 1621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko case FE_QPSK: 1631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko types = "DVB-S"; 1641abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 1651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko case FE_QAM: 1661abddd9f6225298066094e20a6c29061b6af4590Nick Chalko types = "DVB-C"; 1671abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 1681abddd9f6225298066094e20a6c29061b6af4590Nick Chalko case FE_OFDM: 1691abddd9f6225298066094e20a6c29061b6af4590Nick Chalko types = "DVB-T"; 1701abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 1711abddd9f6225298066094e20a6c29061b6af4590Nick Chalko case FE_ATSC: 1721abddd9f6225298066094e20a6c29061b6af4590Nick Chalko types = "ATSC"; 1731abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 1741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko default: 1751abddd9f6225298066094e20a6c29061b6af4590Nick Chalko types = "Unknown"; 1761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1771abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGI("Using frontend \"%s\", type %s", info.name, types); 1781abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1791abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return 0; 1801abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 1811abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1821abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::startTsPidFilter(JNIEnv *env, jobject thiz, int pid, int filterType) { 1831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko Mutex::Autolock autoLock(mFilterLock); 1841abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1851abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (mPidFilters.find(pid) != mPidFilters.end() || (mPatFilterFd != -1 && pid == PAT_PID)) { 1861abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return 0; 1871abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1881abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1891abddd9f6225298066094e20a6c29061b6af4590Nick Chalko int demuxFd; 1901abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if ((demuxFd = openDvbDemuxFromSystemApi(env, thiz)) < 0) { 1911abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGD("Can't open DEMUX file : %s", strerror(errno)); 1921abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 1931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 1941abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 1951abddd9f6225298066094e20a6c29061b6af4590Nick Chalko struct dmx_pes_filter_params filter; 1961abddd9f6225298066094e20a6c29061b6af4590Nick Chalko memset(&filter, 0, sizeof(filter)); 1971abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.pid = pid; 1981abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.input = DMX_IN_FRONTEND; 1991abddd9f6225298066094e20a6c29061b6af4590Nick Chalko switch (filterType) { 2001abddd9f6225298066094e20a6c29061b6af4590Nick Chalko case FILTER_TYPE_AUDIO: 2011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.pes_type = DMX_PES_AUDIO; 2021abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 2031abddd9f6225298066094e20a6c29061b6af4590Nick Chalko case FILTER_TYPE_VIDEO: 2041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.pes_type = DMX_PES_VIDEO; 2051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 2061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko case FILTER_TYPE_PCR: 2071abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.pes_type = DMX_PES_PCR; 2081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 2091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko default: 2101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.pes_type = DMX_PES_OTHER; 2111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko break; 2121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.output = DMX_OUT_TS_TAP; 2141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko filter.flags |= (DMX_CHECK_CRC | DMX_IMMEDIATE_START); 2151abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2161abddd9f6225298066094e20a6c29061b6af4590Nick Chalko // create a pes filter 2171abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (ioctl(demuxFd, DMX_SET_PES_FILTER, &filter)) { 2181abddd9f6225298066094e20a6c29061b6af4590Nick Chalko close(demuxFd); 2191abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 2201abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2211abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2221abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (pid != PAT_PID) { 2231abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mPidFilters.insert(std::pair<int, int>(pid, demuxFd)); 2241abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } else { 2251abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mPatFilterFd = demuxFd; 2261abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2271abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2281abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return 0; 2291abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2301abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2311abddd9f6225298066094e20a6c29061b6af4590Nick Chalkovoid DvbManager::closeAllDvbPidFilter() { 2321abddd9f6225298066094e20a6c29061b6af4590Nick Chalko // Close all dvb pid filters except PAT filter to maintain the opening status of the device. 2331abddd9f6225298066094e20a6c29061b6af4590Nick Chalko Mutex::Autolock autoLock(mFilterLock); 2341abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2351abddd9f6225298066094e20a6c29061b6af4590Nick Chalko for (std::map<int, int>::iterator it(mPidFilters.begin()); 2361abddd9f6225298066094e20a6c29061b6af4590Nick Chalko it != mPidFilters.end(); it++) { 2371abddd9f6225298066094e20a6c29061b6af4590Nick Chalko close(it->second); 2381abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2391abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mPidFilters.clear(); 2401abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2411abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2421abddd9f6225298066094e20a6c29061b6af4590Nick Chalkovoid DvbManager::closePatFilter() { 2431abddd9f6225298066094e20a6c29061b6af4590Nick Chalko Mutex::Autolock autoLock(mFilterLock); 2441abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2451abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (mPatFilterFd != -1) { 2461abddd9f6225298066094e20a6c29061b6af4590Nick Chalko close(mPatFilterFd); 2471abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mPatFilterFd = -1; 2481abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2491abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2501abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2511abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::openDvbDvr(JNIEnv *env, jobject thiz) { 2521abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if ((mDvrFd = openDvbDvrFromSystemApi(env, thiz)) < 0) { 2531abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGD("Can't open DVR file : %s", strerror(errno)); 2541abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 2551abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2561abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return 0; 2571abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2581abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2591abddd9f6225298066094e20a6c29061b6af4590Nick Chalkovoid DvbManager::closeDvbFe() { 2601abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (mFeFd != -1) { 2611abddd9f6225298066094e20a6c29061b6af4590Nick Chalko close(mFeFd); 2621abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mFeFd = -1; 2631abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2641abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2651abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2661abddd9f6225298066094e20a6c29061b6af4590Nick Chalkovoid DvbManager::closeDvbDvr() { 2671abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (mDvrFd != -1) { 2681abddd9f6225298066094e20a6c29061b6af4590Nick Chalko close(mDvrFd); 2691abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mDvrFd = -1; 2701abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2711abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2721abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2731abddd9f6225298066094e20a6c29061b6af4590Nick Chalkovoid DvbManager::reset() { 2741abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mFeHasLock = false; 2751abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closeDvbDvr(); 2761abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closeAllDvbPidFilter(); 2771abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closePatFilter(); 2781abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closeDvbFe(); 2791abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2801abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2811abddd9f6225298066094e20a6c29061b6af4590Nick Chalkovoid DvbManager::resetExceptFe() { 2821abddd9f6225298066094e20a6c29061b6af4590Nick Chalko mFeHasLock = false; 2831abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closeDvbDvr(); 2841abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closeAllDvbPidFilter(); 2851abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closePatFilter(); 2861abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 2871abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2881abddd9f6225298066094e20a6c29061b6af4590Nick Chalkoint DvbManager::readTsStream(JNIEnv *env, jobject thiz, 2891abddd9f6225298066094e20a6c29061b6af4590Nick Chalko uint8_t *tsBuffer, int tsBufferSize, int timeout_ms) { 2901abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (!mFeHasLock) { 2911abddd9f6225298066094e20a6c29061b6af4590Nick Chalko usleep(DVB_ERROR_RETRY_INTERVAL_MS); 2921abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 2931abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2941abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2951abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (mDvrFd == -1) { 2961abddd9f6225298066094e20a6c29061b6af4590Nick Chalko openDvbDvr(env, thiz); 2971abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 2981abddd9f6225298066094e20a6c29061b6af4590Nick Chalko 2991abddd9f6225298066094e20a6c29061b6af4590Nick Chalko struct pollfd pollFd; 3001abddd9f6225298066094e20a6c29061b6af4590Nick Chalko pollFd.fd = mDvrFd; 3011abddd9f6225298066094e20a6c29061b6af4590Nick Chalko pollFd.events = POLLIN|POLLPRI|POLLERR; 3021abddd9f6225298066094e20a6c29061b6af4590Nick Chalko pollFd.revents = 0; 3031abddd9f6225298066094e20a6c29061b6af4590Nick Chalko int poll_result = poll(&pollFd, NUM_POLLFDS, timeout_ms); 3041abddd9f6225298066094e20a6c29061b6af4590Nick Chalko if (poll_result == 0) { 3051abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return 0; 3061abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } else if (poll_result == -1 || pollFd.revents & POLLERR) { 3071abddd9f6225298066094e20a6c29061b6af4590Nick Chalko ALOGD("Can't read DVR : %s", strerror(errno)); 3081abddd9f6225298066094e20a6c29061b6af4590Nick Chalko // TODO: Find how to recover this situation correctly. 3091abddd9f6225298066094e20a6c29061b6af4590Nick Chalko closeDvbDvr(); 3101abddd9f6225298066094e20a6c29061b6af4590Nick Chalko usleep(DVB_ERROR_RETRY_INTERVAL_MS); 3111abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return -1; 3121abddd9f6225298066094e20a6c29061b6af4590Nick Chalko } 3131abddd9f6225298066094e20a6c29061b6af4590Nick Chalko return read(mDvrFd, tsBuffer, tsBufferSize); 3141abddd9f6225298066094e20a6c29061b6af4590Nick Chalko} 315