diff options
Diffstat (limited to 'src/fig/FIG0.cpp')
-rw-r--r-- | src/fig/FIG0.cpp | 182 |
1 files changed, 182 insertions, 0 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 |