1a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent/*
2a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * Copyright (C) 2016 The Android Open Source Project
3a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent *
4a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * you may not use this file except in compliance with the License.
6a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * You may obtain a copy of the License at
7a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent *
8a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent *
10a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * Unless required by applicable law or agreed to in writing, software
11a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * See the License for the specific language governing permissions and
14a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent * limitations under the License.
15a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent */
16a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent#define LOG_TAG "BroadcastRadio"
17a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent//#define LOG_NDEBUG 0
18a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
193ff5260601184d52a8c9a028d6a3af150d2a6757Mark Salyzyn#include <log/log.h>
203ff5260601184d52a8c9a028d6a3af150d2a6757Mark Salyzyn
21a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent#include <hardware/radio.h>
22a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
23a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent#include "BroadcastRadio.h"
24a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent#include "Tuner.h"
25a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent#include "Utils.h"
26a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
27a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentnamespace android {
28a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentnamespace hardware {
29a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentnamespace broadcastradio {
30a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentnamespace V1_0 {
31a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentnamespace implementation {
32a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
33a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric LaurentBroadcastRadio::BroadcastRadio(Class classId)
34a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    : mStatus(Result::NOT_INITIALIZED), mClassId(classId), mHwDevice(NULL)
35a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent{
36a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}
37a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
38a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric LaurentBroadcastRadio::~BroadcastRadio()
39a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent{
40a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (mHwDevice != NULL) {
41a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        radio_hw_device_close(mHwDevice);
42a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
43a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}
44a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
45a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentvoid BroadcastRadio::onFirstRef()
46a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent{
47a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    const hw_module_t *mod;
48a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    int rc;
49a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    ALOGI("%s mClassId %d", __FUNCTION__, mClassId);
50a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
51a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    mHwDevice = NULL;
52a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    const char *classString = Utils::getClassString(mClassId);
53a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (classString == NULL) {
54a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        ALOGE("invalid class ID %d", mClassId);
55a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        mStatus = Result::INVALID_ARGUMENTS;
56a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        return;
57a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
58a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
59a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    ALOGI("%s RADIO_HARDWARE_MODULE_ID %s %s",
60a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent          __FUNCTION__, RADIO_HARDWARE_MODULE_ID, classString);
61a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
62a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    rc = hw_get_module_by_class(RADIO_HARDWARE_MODULE_ID, classString, &mod);
63a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (rc != 0) {
64a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        ALOGE("couldn't load radio module %s.%s (%s)",
65a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent              RADIO_HARDWARE_MODULE_ID, classString, strerror(-rc));
662f461016603b63e37e65c462ce1ba463bbfdcc4dTomasz Wasilczyk        mStatus = Result::INVALID_ARGUMENTS;
67a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        return;
68a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
69a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    rc = radio_hw_device_open(mod, &mHwDevice);
70a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (rc != 0) {
71a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        ALOGE("couldn't open radio hw device in %s.%s (%s)",
72a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent              RADIO_HARDWARE_MODULE_ID, "primary", strerror(-rc));
73a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        mHwDevice = NULL;
74a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        return;
75a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
76a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (mHwDevice->common.version != RADIO_DEVICE_API_VERSION_CURRENT) {
77a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        ALOGE("wrong radio hw device version %04x", mHwDevice->common.version);
78a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        radio_hw_device_close(mHwDevice);
79a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        mHwDevice = NULL;
80a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    } else {
81a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        mStatus = Result::OK;
82a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
83a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}
84a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
85a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentint BroadcastRadio::closeHalTuner(const struct radio_tuner *halTuner)
86a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent{
87a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    ALOGV("%s", __FUNCTION__);
88a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (mHwDevice == NULL) {
89a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        return -ENODEV;
90a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
91a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (halTuner == 0) {
92a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        return -EINVAL;
93a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
94a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    return mHwDevice->close_tuner(mHwDevice, halTuner);
95a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}
96a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
97a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
98a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent// Methods from ::android::hardware::broadcastradio::V1_0::IBroadcastRadio follow.
99a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric LaurentReturn<void> BroadcastRadio::getProperties(getProperties_cb _hidl_cb)
100a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent{
101a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    int rc;
102a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    radio_hal_properties_t halProperties;
103a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    Properties properties;
104a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
105a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (mHwDevice == NULL) {
106a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        rc = -ENODEV;
107a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        goto exit;
108a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
109a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    rc = mHwDevice->get_properties(mHwDevice, &halProperties);
110a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (rc == 0) {
111a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        Utils::convertPropertiesFromHal(&properties, &halProperties);
112a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
113a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
114a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurentexit:
115a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    _hidl_cb(Utils::convertHalResult(rc), properties);
116a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    return Void();
117a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}
118a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
119a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric LaurentReturn<void> BroadcastRadio::openTuner(const BandConfig& config, bool audio,
120a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent                                       const sp<ITunerCallback>& callback, openTuner_cb _hidl_cb)
121a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent{
122a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    sp<Tuner> tunerImpl = new Tuner(callback, this);
123a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
124a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    radio_hal_band_config_t halConfig;
125a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    const struct radio_tuner *halTuner;
126a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    Utils::convertBandConfigToHal(&halConfig, &config);
127a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    int rc = mHwDevice->open_tuner(mHwDevice, &halConfig, audio,
128a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent                                   Tuner::callback, tunerImpl.get(),
129a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent                                   &halTuner);
130a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    if (rc == 0) {
131a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent        tunerImpl->setHalTuner(halTuner);
132a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    }
133a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
134a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    _hidl_cb(Utils::convertHalResult(rc), tunerImpl);
135a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent    return Void();
136a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}
137a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
138a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent
139a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent} // namespace implementation
140a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}  // namespace V1_0
141a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}  // namespace broadcastradio
142a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}  // namespace hardware
143a174588f8d2bb17cd0eb90ff3ed2700c000c8d65Eric Laurent}  // namespace android
144