diff options
Diffstat (limited to 'src/fig')
-rw-r--r-- | src/fig/FIG0.cpp | 182 | ||||
-rw-r--r-- | src/fig/FIG0.h | 23 | ||||
-rw-r--r-- | src/fig/FIGCarousel.cpp | 4 | ||||
-rw-r--r-- | src/fig/FIGCarousel.h | 1 |
4 files changed, 206 insertions, 4 deletions
diff --git a/src/fig/FIG0.cpp b/src/fig/FIG0.cpp index 9f89109..0e8856f 100644 --- a/src/fig/FIG0.cpp +++ b/src/fig/FIG0.cpp @@ -994,5 +994,187 @@ FillStatus FIG0_18::fill(uint8_t *buf, size_t max_size) return fs; } +//=========== FIG 0/19 =========== + +FIG0_19::FIG0_19(FIGRuntimeInformation *rti) : + m_rti(rti) +{ } + +FillStatus FIG0_19::fill(uint8_t *buf, size_t max_size) +{ + using namespace std; + + update_state(); + + FillStatus fs; + ssize_t remaining = max_size; + + auto ensemble = m_rti->ensemble; + + FIGtype0* fig0 = NULL; + set<AnnouncementCluster*> allclusters; + for (const auto& cluster : m_new_announcements) { + allclusters.insert(cluster.first.get()); + } + for (const auto& cluster : m_repeated_announcements) { + allclusters.insert(cluster.get()); + } + for (const auto& cluster : m_disabled_announcements) { + allclusters.insert(cluster.first.get()); + } + + fs.complete_fig_transmitted = true; + for (const auto& cluster : allclusters) { + + if (remaining < (int)sizeof(FIGtype0_19)) { + fs.complete_fig_transmitted = false; + break; + } + + if (fig0 == NULL) { + if (remaining < 2 + (int)sizeof(FIGtype0_19)) { + break; + } + + fig0 = (FIGtype0*)buf; + fig0->FIGtypeNumber = 0; + fig0->Length = 1; + fig0->CN = 0; + fig0->OE = 0; + fig0->PD = 0; + fig0->Extension = 19; + buf += 2; + remaining -= 2; + } + + auto fig0_19 = (FIGtype0_19*)buf; + fig0_19->ClusterId = cluster->cluster_id; + if (cluster->is_active()) { + fig0_19->ASw = cluster->flags; + } + else { + fig0_19->ASw = 0; + } + fig0_19->NewFlag = 1; + fig0_19->RegionFlag = 0; + fig0_19->SubChId = 0; + bool found = false; + + for (const auto& subchannel : ensemble->subchannels) { + cerr << "*****" << subchannel->uid << " vs " << + cluster->subchanneluid << endl; + + if (subchannel->uid == cluster->subchanneluid) { + fig0_19->SubChId = subchannel->id; + found = true; + break; + } + } + if (not found) { + etiLog.level(warn) << "FIG0/19: could not find subchannel " << + cluster->subchanneluid << " for cluster " << + (int)cluster->cluster_id; + continue; + } + + buf += sizeof(FIGtype0_19); + remaining -= sizeof(FIGtype0_19); + } + + fs.num_bytes_written = max_size - remaining; + return fs; +} + +void FIG0_19::update_state() +{ + auto ensemble = m_rti->ensemble; + + // We are called every 24ms, and must timeout after 2s + const int timeout = 2000/24; + + etiLog.level(info) << " FIG0/19 new"; + for (const auto& cluster : m_new_announcements) { + etiLog.level(info) << " " << cluster.first->tostring() + << ": " << cluster.second; + } + etiLog.level(info) << " FIG0/19 repeated"; + for (const auto& cluster : m_repeated_announcements) { + etiLog.level(info) << " " << cluster->tostring(); + } + etiLog.level(info) << " FIG0/19 disabled"; + for (const auto& cluster : m_disabled_announcements) { + etiLog.level(info) << " " << cluster.first->tostring() + << ": " << cluster.second; + } + + etiLog.level(info) << " FIG0/19 in ensemble"; + for (const auto& cluster : ensemble->clusters) { + etiLog.level(info) << " " << cluster->tostring(); + if (cluster->is_active()) { + if (m_repeated_announcements.count(cluster) > 0) { + // We are currently announcing this cluster + continue; + } + + if (m_new_announcements.count(cluster) > 0) { + // We are currently announcing this cluster at a + // fast rate. Handle timeout: + m_new_announcements[cluster] -= 1; + if (m_new_announcements[cluster] <= 0) { + m_repeated_announcements.insert(cluster); + m_new_announcements.erase(cluster); + } + continue; + } + + // unlikely + if (m_disabled_announcements.count(cluster) > 0) { + m_new_announcements[cluster] = timeout; + m_disabled_announcements.erase(cluster); + continue; + } + + // It's a new announcement! + m_new_announcements[cluster] = timeout; + } + else { // Not active + if (m_disabled_announcements.count(cluster) > 0) { + m_disabled_announcements[cluster] -= 1; + if (m_disabled_announcements[cluster] <= 0) { + m_disabled_announcements.erase(cluster); + } + continue; + } + + if (m_repeated_announcements.count(cluster) > 0) { + // We are currently announcing this cluster + m_disabled_announcements[cluster] = timeout; + m_repeated_announcements.erase(cluster); + continue; + } + + // unlikely + if (m_new_announcements.count(cluster) > 0) { + // We are currently announcing this cluster at a + // fast rate. We must stop announcing it + m_disabled_announcements[cluster] = timeout; + m_new_announcements.erase(cluster); + continue; + } + } + } +} + +FIG_rate FIG0_19::repetition_rate(void) +{ + if ( m_new_announcements.size() > 0 or + m_disabled_announcements.size() ) { + return FIG_rate::A_B; + } + else { + return FIG_rate::B; + } +} + } // namespace FIC diff --git a/src/fig/FIG0.h b/src/fig/FIG0.h index 9015b00..9811eaf 100644 --- a/src/fig/FIG0.h +++ b/src/fig/FIG0.h @@ -220,15 +220,32 @@ class FIG0_19 : public IFIG public: FIG0_19(FIGRuntimeInformation* rti); virtual FillStatus fill(uint8_t *buf, size_t max_size); - virtual FIG_rate repetition_rate(void) { return FIG_rate::A; } + virtual FIG_rate repetition_rate(void); virtual const int figtype(void) const { return 0; } virtual const int figextension(void) const { return 19; } private: FIGRuntimeInformation *m_rti; - bool m_initialised; - std::vector<std::shared_ptr<DabService> >::iterator service; + + void update_state(void); + + /* When a new announcement gets active, it is moved into the list + * of new announcements, and gets transmitted at a faster rate for + * two seconds. + * Same for recently disabled announcements. + */ + + /* Map of cluster to frame count */ + std::map< + std::shared_ptr<AnnouncementCluster>,int> m_new_announcements; + + std::set< + std::shared_ptr<AnnouncementCluster> > m_repeated_announcements; + + /* Map of cluster to frame count */ + std::map< + std::shared_ptr<AnnouncementCluster>,int> m_disabled_announcements; }; } // namespace FIC diff --git a/src/fig/FIGCarousel.cpp b/src/fig/FIGCarousel.cpp index 8eedd6e..d565c23 100644 --- a/src/fig/FIGCarousel.cpp +++ b/src/fig/FIGCarousel.cpp @@ -68,7 +68,8 @@ FIGCarousel::FIGCarousel(boost::shared_ptr<dabEnsemble> ensemble) : m_fig1_1(&m_rti), m_fig1_4(&m_rti), m_fig1_5(&m_rti), - m_fig0_18(&m_rti) + m_fig0_18(&m_rti), + m_fig0_19(&m_rti) { load_and_allocate(m_fig0_0, 0); load_and_allocate(m_fig0_1, 0); @@ -85,6 +86,7 @@ FIGCarousel::FIGCarousel(boost::shared_ptr<dabEnsemble> ensemble) : load_and_allocate(m_fig1_1, 2); load_and_allocate(m_fig1_5, 2); load_and_allocate(m_fig0_18, 2); + load_and_allocate(m_fig0_19, 2); } void FIGCarousel::load_and_allocate(IFIG& fig, int fib) diff --git a/src/fig/FIGCarousel.h b/src/fig/FIGCarousel.h index 170ffdd..f7a839c 100644 --- a/src/fig/FIGCarousel.h +++ b/src/fig/FIGCarousel.h @@ -86,6 +86,7 @@ class FIGCarousel { FIG1_4 m_fig1_4; FIG1_5 m_fig1_5; FIG0_18 m_fig0_18; + FIG0_19 m_fig0_19; }; } // namespace FIC |