/*
 * Check that the header set works
 */
void HeaderSetTest::testHeaderSet() {
  HeaderSet headers;
  RootHeader root_header;
  E131Header e131_header("e131", 1, 2, 6001);
  E133Header e133_header("foo", 1, 2050);
  DMPHeader dmp_header(false, false, NON_RANGE, ONE_BYTES);

  // test the root header component
  CID cid = CID::Generate();
  root_header.SetCid(cid);
  headers.SetRootHeader(root_header);
  OLA_ASSERT(root_header == headers.GetRootHeader());

  // test the E1.31 header component
  headers.SetE131Header(e131_header);
  OLA_ASSERT(e131_header == headers.GetE131Header());

  // test the E1.33 header component
  headers.SetE133Header(e133_header);
  OLA_ASSERT(e133_header == headers.GetE133Header());

  // test the DMP headers component
  headers.SetDMPHeader(dmp_header);
  OLA_ASSERT(dmp_header == headers.GetDMPHeader());

  // test assign
  HeaderSet headers2 = headers;
  OLA_ASSERT(root_header == headers2.GetRootHeader());
  OLA_ASSERT(e131_header == headers2.GetE131Header());
  OLA_ASSERT(e133_header == headers2.GetE133Header());
  OLA_ASSERT(dmp_header == headers2.GetDMPHeader());
  OLA_ASSERT(headers2 == headers);

  // test copy
  HeaderSet headers3(headers);
  OLA_ASSERT(root_header == headers3.GetRootHeader());
  OLA_ASSERT(e131_header == headers3.GetE131Header());
  OLA_ASSERT(e133_header == headers3.GetE133Header());
  OLA_ASSERT(dmp_header == headers3.GetDMPHeader());
  OLA_ASSERT(headers3 == headers);
}
Beispiel #2
0
/*
 * Check if this source is operating at the highest priority for this universe.
 * This takes care of tracking all sources for a universe at the active
 * priority.
 * @param universe_data the universe_handler struct for this universe,
 * @param HeaderSet the set of headers in this packet
 * @param buffer, if set to a non-NULL pointer, the caller should copy the data
 * in the buffer.
 * @returns true if we should remerge the data, false otherwise.
 */
bool DMPE131Inflator::TrackSourceIfRequired(
    universe_handler *universe_data,
    const HeaderSet &headers,
    DmxBuffer **buffer) {

  *buffer = NULL;  // default the buffer to NULL
  ola::TimeStamp now;
  m_clock.CurrentTime(&now);
  const E131Header &e131_header = headers.GetE131Header();
  uint8_t priority = e131_header.Priority();
  vector<dmx_source> &sources = universe_data->sources;
  vector<dmx_source>::iterator iter = sources.begin();

  while (iter != sources.end()) {
    if (iter->cid != headers.GetRootHeader().GetCid()) {
      TimeStamp expiry_time = iter->last_heard_from + EXPIRY_INTERVAL;
      if (now > expiry_time) {
        OLA_INFO << "source " << iter->cid.ToString() << " has expired";
        iter = sources.erase(iter);
        continue;
      }
    }
    iter++;
  }

  if (sources.empty())
    universe_data->active_priority = 0;

  for (iter = sources.begin(); iter != sources.end(); ++iter) {
    if (iter->cid == headers.GetRootHeader().GetCid())
      break;
  }

  if (iter == sources.end()) {
    // This is an untracked source
    if (e131_header.StreamTerminated() ||
        priority < universe_data->active_priority)
      return false;

    if (priority > universe_data->active_priority) {
      OLA_INFO << "Raising priority for universe " <<
        e131_header.Universe() << " from " <<
        static_cast<int>(universe_data->active_priority) << " to " <<
        static_cast<int>(priority);
      sources.clear();
      universe_data->active_priority = priority;
    }

    if (sources.size() == MAX_MERGE_SOURCES) {
      // TODO(simon): flag this in the export map
      OLA_WARN << "Max merge sources reached for universe " <<
        e131_header.Universe() << ", " <<
        headers.GetRootHeader().GetCid().ToString() << " won't be tracked";
        return false;
    } else {
      OLA_INFO << "Added new E1.31 source: " <<
        headers.GetRootHeader().GetCid().ToString();
      dmx_source new_source;
      new_source.cid = headers.GetRootHeader().GetCid();
      new_source.sequence = e131_header.Sequence();
      new_source.last_heard_from = now;
      iter = sources.insert(sources.end(), new_source);
      *buffer = &iter->buffer;
      return true;
    }

  } else {
    // We already know about this one, check the seq #
    int8_t seq_diff = static_cast<int8_t>(e131_header.Sequence() -
                                          iter->sequence);
    if (seq_diff <= 0 && seq_diff > SEQUENCE_DIFF_THRESHOLD) {
      OLA_INFO << "Old packet received, ignoring, this # " <<
        static_cast<int>(e131_header.Sequence()) << ", last " <<
        static_cast<int>(iter->sequence);
      return false;
    }
    iter->sequence = e131_header.Sequence();

    if (e131_header.StreamTerminated()) {
      OLA_INFO << "CID " << headers.GetRootHeader().GetCid().ToString() <<
        " sent a termination for universe " << e131_header.Universe();
      sources.erase(iter);
      if (sources.empty())
        universe_data->active_priority = 0;
      // We need to trigger a merge here else the buffer will be stale, we keep
      // the buffer as NULL though so we don't use the data.
      return true;
    }

    iter->last_heard_from = now;
    if (priority < universe_data->active_priority) {
      if (sources.size() == 1) {
        universe_data->active_priority = priority;
      } else {
        sources.erase(iter);
        return true;
      }
    } else if (priority > universe_data->active_priority) {
      // new active priority
      universe_data->active_priority = priority;
      if (sources.size() != 1) {
        // clear all sources other than this one
        dmx_source this_source = *iter;
        sources.clear();
        iter = sources.insert(sources.end(), this_source);
      }
    }
    *buffer = &iter->buffer;
    return true;
  }
}