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