1a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk/* 2a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Copyright (C) 2017 The Android Open Source Project 3a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 4a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Licensed under the Apache License, Version 2.0 (the "License"); 5a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * you may not use this file except in compliance with the License. 6a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * You may obtain a copy of the License at 7a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 8a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * http://www.apache.org/licenses/LICENSE-2.0 9a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * 10a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * Unless required by applicable law or agreed to in writing, software 11a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * distributed under the License is distributed on an "AS IS" BASIS, 12a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * See the License for the specific language governing permissions and 14a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk * limitations under the License. 15a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk */ 16a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk#define LOG_TAG "BroadcastRadioDefault.utils" 17a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk//#define LOG_NDEBUG 0 18a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 1906100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk#include <broadcastradio-utils-1x/Utils.h> 20a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 21a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk#include <log/log.h> 22a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 23a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace android { 24a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace hardware { 25a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace broadcastradio { 26a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyknamespace utils { 27a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 28a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykusing V1_0::Band; 298c34c8179d4b745338e6200b337488ef9ad4b7edTomasz Wasilczykusing V1_1::IdentifierType; 30f679e8b6ece550ea84348c70b8e414d92fc4a5c6Tomasz Wasilczykusing V1_1::ProgramIdentifier; 31f679e8b6ece550ea84348c70b8e414d92fc4a5c6Tomasz Wasilczykusing V1_1::ProgramSelector; 32f679e8b6ece550ea84348c70b8e414d92fc4a5c6Tomasz Wasilczykusing V1_1::ProgramType; 33a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 34a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykstatic bool isCompatibleProgramType(const uint32_t ia, const uint32_t ib) { 35a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk auto a = static_cast<ProgramType>(ia); 36a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk auto b = static_cast<ProgramType>(ib); 37a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 38a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (a == b) return true; 39a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (a == ProgramType::AM && b == ProgramType::AM_HD) return true; 40a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (a == ProgramType::AM_HD && b == ProgramType::AM) return true; 41a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (a == ProgramType::FM && b == ProgramType::FM_HD) return true; 42a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (a == ProgramType::FM_HD && b == ProgramType::FM) return true; 43a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return false; 44a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 45a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 46a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykstatic bool bothHaveId(const ProgramSelector& a, const ProgramSelector& b, 47a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk const IdentifierType type) { 48a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return hasId(a, type) && hasId(b, type); 49a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 50a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 51a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykstatic bool anyHaveId(const ProgramSelector& a, const ProgramSelector& b, 52a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk const IdentifierType type) { 53a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return hasId(a, type) || hasId(b, type); 54a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 55a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 56a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykstatic bool haveEqualIds(const ProgramSelector& a, const ProgramSelector& b, 57a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk const IdentifierType type) { 58a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (!bothHaveId(a, b, type)) return false; 59753c1d1ef27a7f0519c954ffa462fae0cfb18976Tomasz Wasilczyk /* We should check all Ids of a given type (ie. other AF), 60753c1d1ef27a7f0519c954ffa462fae0cfb18976Tomasz Wasilczyk * but it doesn't matter for default implementation. 61753c1d1ef27a7f0519c954ffa462fae0cfb18976Tomasz Wasilczyk */ 6206100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk return getId(a, type) == getId(b, type); 63a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 64a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 65a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykbool tunesTo(const ProgramSelector& a, const ProgramSelector& b) { 66a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (!isCompatibleProgramType(a.programType, b.programType)) return false; 67a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 68a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk auto type = getType(a); 69a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 70a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk switch (type) { 71a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::AM: 72a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::AM_HD: 73a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::FM: 74a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::FM_HD: 75a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (haveEqualIds(a, b, IdentifierType::HD_STATION_ID_EXT)) return true; 76a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 77a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk // if HD Radio subchannel is specified, it must match 78a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (anyHaveId(a, b, IdentifierType::HD_SUBCHANNEL)) { 79a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk // missing subchannel (analog) is an equivalent of first subchannel (MPS) 80a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk auto aCh = getId(a, IdentifierType::HD_SUBCHANNEL, 0); 81a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk auto bCh = getId(b, IdentifierType::HD_SUBCHANNEL, 0); 82a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (aCh != bCh) return false; 83a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 84a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 85a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (haveEqualIds(a, b, IdentifierType::RDS_PI)) return true; 86a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 87a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return haveEqualIds(a, b, IdentifierType::AMFM_FREQUENCY); 88a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::DAB: 898c34c8179d4b745338e6200b337488ef9ad4b7edTomasz Wasilczyk return haveEqualIds(a, b, IdentifierType::DAB_SIDECC); 90a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::DRMO: 91a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return haveEqualIds(a, b, IdentifierType::DRMO_SERVICE_ID); 92a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::SXM: 93a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (anyHaveId(a, b, IdentifierType::SXM_SERVICE_ID)) { 94a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return haveEqualIds(a, b, IdentifierType::SXM_SERVICE_ID); 95a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 96a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return haveEqualIds(a, b, IdentifierType::SXM_CHANNEL); 97da97a6dd42c1fdacc5110c8b04e95d67321697d5Tomasz Wasilczyk default: // includes all vendor types 98a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk ALOGW("Unsupported program type: %s", toString(type).c_str()); 99a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return false; 100a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 101a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 102a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 103a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz WasilczykProgramType getType(const ProgramSelector& sel) { 104a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return static_cast<ProgramType>(sel.programType); 105a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 106a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 107a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykbool isAmFm(const ProgramType type) { 108a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk switch (type) { 109a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::AM: 110a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::FM: 111a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::AM_HD: 112a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::FM_HD: 113a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return true; 114a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk default: 115a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return false; 116a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 117a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 118a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 119701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczykbool isAm(const Band band) { 120701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk return band == Band::AM || band == Band::AM_HD; 121701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk} 122701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk 123701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczykbool isFm(const Band band) { 124701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk return band == Band::FM || band == Band::FM_HD; 125701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk} 126701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk 127002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczykstatic bool maybeGetId(const ProgramSelector& sel, const IdentifierType type, uint64_t* val) { 128a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk auto itype = static_cast<uint32_t>(type); 129002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk 1308c34c8179d4b745338e6200b337488ef9ad4b7edTomasz Wasilczyk if (sel.primaryId.type == itype) { 131002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk if (val) *val = sel.primaryId.value; 132002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk return true; 133002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk } 134002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk 135a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk // not optimal, but we don't care in default impl 136a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk for (auto&& id : sel.secondaryIds) { 137002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk if (id.type == itype) { 138002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk if (val) *val = id.value; 139002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk return true; 140002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk } 141a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 142002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk 1438c34c8179d4b745338e6200b337488ef9ad4b7edTomasz Wasilczyk return false; 144002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk} 145002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk 146002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczykbool hasId(const ProgramSelector& sel, const IdentifierType type) { 147002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk return maybeGetId(sel, type, nullptr); 148a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 149a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 150a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykuint64_t getId(const ProgramSelector& sel, const IdentifierType type) { 151002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk uint64_t val; 152002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk 153002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk if (maybeGetId(sel, type, &val)) { 154002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk return val; 155a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 156002151ce255f171a3bfdd3bbf2f2ed5d63f77541Tomasz Wasilczyk 157a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk ALOGW("Identifier %s not found", toString(type).c_str()); 158a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return 0; 159a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 160a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 161a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykuint64_t getId(const ProgramSelector& sel, const IdentifierType type, uint64_t defval) { 162a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (!hasId(sel, type)) return defval; 163a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return getId(sel, type); 164a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 165a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 166a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz WasilczykProgramSelector make_selector(Band band, uint32_t channel, uint32_t subChannel) { 167a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk ProgramSelector sel = {}; 168a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 169a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk ALOGW_IF((subChannel > 0) && (band == Band::AM || band == Band::FM), 170a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk "got subChannel for non-HD AM/FM"); 171a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 172a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk // we can't use ProgramType::AM_HD or FM_HD, because we don't know HD station ID 173a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk ProgramType type; 174701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk if (isAm(band)) { 175701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk type = ProgramType::AM; 176701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk } else if (isFm(band)) { 177701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk type = ProgramType::FM; 178701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk } else { 179701a5bdda51a8b2feddbb5e82a3ac3bbc6ce3fddTomasz Wasilczyk LOG_ALWAYS_FATAL("Unsupported band: %s", toString(band).c_str()); 180a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 181a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 182a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk sel.programType = static_cast<uint32_t>(type); 183a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk sel.primaryId.type = static_cast<uint32_t>(IdentifierType::AMFM_FREQUENCY); 184a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk sel.primaryId.value = channel; 185a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (subChannel > 0) { 1862834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk /* stating sub channel for AM/FM channel does not give any guarantees, 1872834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk * but we can't do much more without HD station ID 1882834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk * 1892834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk * The legacy APIs had 1-based subChannels, while ProgramSelector is 0-based. 1902834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk */ 191a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk sel.secondaryIds = hidl_vec<ProgramIdentifier>{ 1922834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk {static_cast<uint32_t>(IdentifierType::HD_SUBCHANNEL), subChannel - 1}, 193a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk }; 194a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 195a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 196a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return sel; 197a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 198a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 1992834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczykbool getLegacyChannel(const ProgramSelector& sel, uint32_t* channelOut, uint32_t* subChannelOut) { 2002834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk if (channelOut) *channelOut = 0; 2012834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk if (subChannelOut) *subChannelOut = 0; 202a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk if (isAmFm(getType(sel))) { 2032834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk if (channelOut) *channelOut = getId(sel, IdentifierType::AMFM_FREQUENCY); 2042834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk if (subChannelOut && hasId(sel, IdentifierType::HD_SUBCHANNEL)) { 2052834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk // The legacy APIs had 1-based subChannels, while ProgramSelector is 0-based. 2062834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk *subChannelOut = getId(sel, IdentifierType::HD_SUBCHANNEL) + 1; 2072834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk } 208a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return true; 209a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 2102834b95b12edb0b234594b21bcb4b44cc797fc90Tomasz Wasilczyk return false; 211a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 212a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 213a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczykbool isDigital(const ProgramSelector& sel) { 214a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk switch (getType(sel)) { 215a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::AM: 216a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk case ProgramType::FM: 217a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return false; 218a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk default: 219a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk // VENDOR might not be digital, but it doesn't matter for default impl. 220a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk return true; 221a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk } 222a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} 223a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk 224a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace utils 225c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk 226c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyknamespace V1_0 { 227c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk 228c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczykbool operator==(const BandConfig& l, const BandConfig& r) { 22906100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk using namespace utils; 23006100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk 231c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk if (l.type != r.type) return false; 232c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk if (l.antennaConnected != r.antennaConnected) return false; 233c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk if (l.lowerLimit != r.lowerLimit) return false; 234c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk if (l.upperLimit != r.upperLimit) return false; 235c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk if (l.spacings != r.spacings) return false; 23606100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk if (isAm(l.type)) { 237c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk return l.ext.am == r.ext.am; 23806100b39db99dd5b7860a6e981ba9f8d511793faTomasz Wasilczyk } else if (isFm(l.type)) { 239c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk return l.ext.fm == r.ext.fm; 240c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk } else { 241c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk ALOGW("Unsupported band config type: %s", toString(l.type).c_str()); 242c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk return false; 243c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk } 244c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk} 245c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk 246c1763a679659cdb1a50f7b4640b6c3f659f1d666Tomasz Wasilczyk} // namespace V1_0 247a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace broadcastradio 248a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace hardware 249a02b6ef23c6dd0405ceb1337ba05bf4e0087890cTomasz Wasilczyk} // namespace android 250