Example #1
0
void
SdpHelper::SetDefaultAddresses(const std::string& defaultCandidateAddr,
                               uint16_t defaultCandidatePort,
                               const std::string& defaultRtcpCandidateAddr,
                               uint16_t defaultRtcpCandidatePort,
                               Sdp* sdp,
                               uint16_t level,
                               BundledMids bundledMids)
{
  SdpMediaSection& msection = sdp->GetMediaSection(level);

  if (msection.GetAttributeList().HasAttribute(SdpAttribute::kMidAttribute)) {
    std::string mid(msection.GetAttributeList().GetMid());
    if (bundledMids.count(mid)) {
      const SdpMediaSection* masterBundleMsection(bundledMids[mid]);
      if (msection.GetLevel() != masterBundleMsection->GetLevel()) {
        // Slave bundle m-section. Skip.
        return;
      }

      // Master bundle m-section. Set defaultCandidateAddr and
      // defaultCandidatePort on all bundled m-sections.
      for (auto i = bundledMids.begin(); i != bundledMids.end(); ++i) {
        if (i->second != masterBundleMsection) {
          continue;
        }
        SdpMediaSection* bundledMsection = FindMsectionByMid(*sdp, i->first);
        if (!bundledMsection) {
          MOZ_ASSERT(false);
          continue;
        }
        SetDefaultAddresses(defaultCandidateAddr,
                            defaultCandidatePort,
                            defaultRtcpCandidateAddr,
                            defaultRtcpCandidatePort,
                            bundledMsection);
      }
    }
  }

  SetDefaultAddresses(defaultCandidateAddr,
                      defaultCandidatePort,
                      defaultRtcpCandidateAddr,
                      defaultRtcpCandidatePort,
                      &msection);

  // TODO(bug 1095793): Will this have an mid someday?

  SdpAttributeList& attrs = msection.GetAttributeList();
  attrs.SetAttribute(
      new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute));
  // Remove trickle-ice option
  attrs.RemoveAttribute(SdpAttribute::kIceOptionsAttribute);
}
Example #2
0
nsresult
SdpHelper::GetBundledMids(const Sdp& sdp, BundledMids* bundledMids)
{
  std::vector<SdpGroupAttributeList::Group> bundleGroups;
  GetBundleGroups(sdp, &bundleGroups);

  for (SdpGroupAttributeList::Group& group : bundleGroups) {
    if (group.tags.empty()) {
      SDP_SET_ERROR("Empty BUNDLE group");
      return NS_ERROR_INVALID_ARG;
    }

    const SdpMediaSection* masterBundleMsection(
        FindMsectionByMid(sdp, group.tags[0]));

    if (!masterBundleMsection) {
      SDP_SET_ERROR("mid specified for bundle transport in group attribute"
          " does not exist in the SDP. (mid=" << group.tags[0] << ")");
      return NS_ERROR_INVALID_ARG;
    }

    if (MsectionIsDisabled(*masterBundleMsection)) {
      SDP_SET_ERROR("mid specified for bundle transport in group attribute"
          " points at a disabled m-section. (mid=" << group.tags[0] << ")");
      return NS_ERROR_INVALID_ARG;
    }

    for (const std::string& mid : group.tags) {
      if (bundledMids->count(mid)) {
        SDP_SET_ERROR("mid \'" << mid << "\' appears more than once in a "
                       "BUNDLE group");
        return NS_ERROR_INVALID_ARG;
      }

      (*bundledMids)[mid] = masterBundleMsection;
    }
  }

  return NS_OK;
}
Example #3
0
nsresult
SdpHelper::AddCandidateToSdp(Sdp* sdp,
                             const std::string& candidateUntrimmed,
                             const std::string& mid,
                             uint16_t level)
{

  if (level >= sdp->GetMediaSectionCount()) {
    SDP_SET_ERROR("Index " << level << " out of range");
    return NS_ERROR_INVALID_ARG;
  }

  // Trim off '[a=]candidate:'
  size_t begin = candidateUntrimmed.find(':');
  if (begin == std::string::npos) {
    SDP_SET_ERROR("Invalid candidate, no ':' (" << candidateUntrimmed << ")");
    return NS_ERROR_INVALID_ARG;
  }
  ++begin;

  std::string candidate = candidateUntrimmed.substr(begin);

  // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-11#section-3.4.2.1
  // Implementations receiving an ICE Candidate object MUST use the MID if
  // present, or the m= line index, if not (as it could have come from a
  // non-JSEP endpoint). (bug 1095793)
  SdpMediaSection* msection = 0;
  if (!mid.empty()) {
    // FindMsectionByMid could return nullptr
    msection = FindMsectionByMid(*sdp, mid);

    // Check to make sure mid matches what we'd get by
    // looking up the m= line using the level. (mjf)
    std::string checkMid;
    nsresult rv = GetMidFromLevel(*sdp, level, &checkMid);
    if (NS_FAILED(rv)) {
      return rv;
    }
    if (mid != checkMid) {
      SDP_SET_ERROR("Mismatch between mid and level - \"" << mid
                     << "\" is not the mid for level " << level
                     << "; \"" << checkMid << "\" is");
      return NS_ERROR_INVALID_ARG;
    }
  }
  if (!msection) {
    msection = &(sdp->GetMediaSection(level));
  }

  SdpAttributeList& attrList = msection->GetAttributeList();

  UniquePtr<SdpMultiStringAttribute> candidates;
  if (!attrList.HasAttribute(SdpAttribute::kCandidateAttribute)) {
    // Create new
    candidates.reset(
        new SdpMultiStringAttribute(SdpAttribute::kCandidateAttribute));
  } else {
    // Copy existing
    candidates.reset(new SdpMultiStringAttribute(
        *static_cast<const SdpMultiStringAttribute*>(
            attrList.GetAttribute(SdpAttribute::kCandidateAttribute))));
  }
  candidates->PushEntry(candidate);
  attrList.SetAttribute(candidates.release());

  return NS_OK;
}