summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/sdp/RsdparsaSdp.cpp
blob: 0e653dc17ece65b9f27ddc544584f803c1a453e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "sdp/RsdparsaSdp.h"

#include <cstdlib>
#include "mozilla/UniquePtr.h"
#include "mozilla/Assertions.h"
#include "nsError.h"
#include <iostream>

#include "sdp/RsdparsaSdpInc.h"
#include "sdp/RsdparsaSdpMediaSection.h"

#ifdef CRLF
#  undef CRLF
#endif
#define CRLF "\r\n"

namespace mozilla {

RsdparsaSdp::RsdparsaSdp(RsdparsaSessionHandle session, const SdpOrigin& origin)
    : mSession(std::move(session)), mOrigin(origin) {
  RsdparsaSessionHandle attributeSession(sdp_new_reference(mSession.get()));
  mAttributeList.reset(
      new RsdparsaSdpAttributeList(std::move(attributeSession)));

  size_t section_count = sdp_media_section_count(mSession.get());
  for (size_t level = 0; level < section_count; level++) {
    RustMediaSection* mediaSection =
        sdp_get_media_section(mSession.get(), level);
    if (!mediaSection) {
      MOZ_ASSERT(false,
                 "sdp_get_media_section failed because level was out of"
                 " bounds, but we did a bounds check!");
      break;
    }
    RsdparsaSessionHandle newSession(sdp_new_reference(mSession.get()));
    RsdparsaSdpMediaSection* sdpMediaSection;
    sdpMediaSection = new RsdparsaSdpMediaSection(
        level, std::move(newSession), mediaSection, mAttributeList.get());
    mMediaSections.emplace_back(sdpMediaSection);
  }
}

RsdparsaSdp::RsdparsaSdp(const RsdparsaSdp& aOrig)
    : RsdparsaSdp(RsdparsaSessionHandle(create_sdp_clone(aOrig.mSession.get())),
                  aOrig.mOrigin) {}

Sdp* RsdparsaSdp::Clone() const { return new RsdparsaSdp(*this); }

const SdpOrigin& RsdparsaSdp::GetOrigin() const { return mOrigin; }

uint32_t RsdparsaSdp::GetBandwidth(const std::string& type) const {
  return get_sdp_bandwidth(mSession.get(), type.c_str());
}

const SdpMediaSection& RsdparsaSdp::GetMediaSection(size_t level) const {
  if (level > mMediaSections.size()) {
    MOZ_CRASH();
  }
  return *mMediaSections[level];
}

SdpMediaSection& RsdparsaSdp::GetMediaSection(size_t level) {
  if (level > mMediaSections.size()) {
    MOZ_CRASH();
  }
  return *mMediaSections[level];
}

SdpMediaSection& RsdparsaSdp::AddMediaSection(
    SdpMediaSection::MediaType mediaType, SdpDirectionAttribute::Direction dir,
    uint16_t port, SdpMediaSection::Protocol protocol, sdp::AddrType addrType,
    const std::string& addr) {
  StringView rustAddr{addr.c_str(), addr.size()};
  auto nr = sdp_add_media_section(mSession.get(), mediaType, dir, port,
                                  protocol, addrType, rustAddr);

  if (NS_SUCCEEDED(nr)) {
    size_t level = mMediaSections.size();
    RsdparsaSessionHandle newSessHandle(sdp_new_reference(mSession.get()));

    auto rustMediaSection = sdp_get_media_section(mSession.get(), level);
    auto mediaSection =
        new RsdparsaSdpMediaSection(level, std::move(newSessHandle),
                                    rustMediaSection, mAttributeList.get());
    mMediaSections.emplace_back(mediaSection);

    return *mediaSection;
  } else {
    // Return the last media section if the construction of this one fails
    return GetMediaSection(mMediaSections.size() - 1);
  }
}

void RsdparsaSdp::Serialize(std::ostream& os) const {
  os << "v=0" << CRLF << mOrigin << "s=-" << CRLF;

  // We don't support creating i=, u=, e=, p=
  // We don't generate c= at the session level (only in media)

  BandwidthVec* bwVec = sdp_get_session_bandwidth_vec(mSession.get());
  char* bwString = sdp_serialize_bandwidth(bwVec);
  if (bwString) {
    os << bwString;
    sdp_free_string(bwString);
  }

  os << "t=0 0" << CRLF;

  // We don't support r= or z=

  // attributes
  os << *mAttributeList;

  // media sections
  for (const auto& msection : mMediaSections) {
    os << *msection;
  }
}

}  // namespace mozilla