media/mtransport/mediapacket.cpp
author Sven Sauleau <ssauleau@igalia.com>
Tue, 05 Mar 2019 12:19:31 +0000
changeset 522212 64cc60d52a04d0c97162b18b4c3c744a11684e41
parent 518881 fd4330c37f1f8ae8ff828c3ae082f95de5895994
permissions -rw-r--r--
Bug 1526694 [wpt PR 15276] - [wasm] update js-api test runner and expectations, a=testonly Automatic update from web-platform-tests [wasm] update js-api test runner and expectations wasm-module-builder: - consistently adds the end opcode in function bodies (using addBody). - add missing setTableLength method table/get-set: - Avoid unrelated errors like: Cannot destructure property `fn` of 'undefined' or 'null'. Bug: 926311, v8:8319 Change-Id: Ia7db1ee5c3a9b1c1d6092cdce8885ddee4dd9b0e Reviewed-on: https://chromium-review.googlesource.com/c/1458099 Reviewed-by: Michael Lippautz <mlippautz@chromium.org> Commit-Queue: Sven Sauleau <ssauleau@igalia.com> Cr-Commit-Position: refs/heads/master@{#633121} -- wpt-commits: 22400f9755a49a50632a8f2067cb06bca74efff8 wpt-pr: 15276

/* -*- 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 "mediapacket.h"

#include <cstring>
#include "ipc/IPCMessageUtils.h"

namespace mozilla {

MediaPacket::MediaPacket(const MediaPacket& orig)
    : sdp_level_(orig.sdp_level_), type_(orig.type_) {
  Copy(orig.data(), orig.len(), orig.capacity_);
}

void MediaPacket::Copy(const uint8_t* data, size_t len, size_t capacity) {
  if (capacity < len) {
    capacity = len;
  }
  data_.reset(new uint8_t[capacity]);
  len_ = len;
  capacity_ = capacity;
  memcpy(data_.get(), data, len);
}

void MediaPacket::Serialize(IPC::Message* aMsg) const {
  aMsg->WriteUInt32(len_);
  aMsg->WriteUInt32(capacity_);
  if (len_) {
    aMsg->WriteBytes(data_.get(), len_);
  }
  aMsg->WriteUInt32(encrypted_len_);
  if (encrypted_len_) {
    aMsg->WriteBytes(encrypted_data_.get(), encrypted_len_);
  }
  aMsg->WriteInt32(sdp_level_.isSome() ? *sdp_level_ : -1);
  aMsg->WriteInt32(type_);
}

bool MediaPacket::Deserialize(const IPC::Message* aMsg, PickleIterator* aIter) {
  Reset();
  uint32_t len;
  if (!aMsg->ReadUInt32(aIter, &len)) {
    return false;
  }
  uint32_t capacity;
  if (!aMsg->ReadUInt32(aIter, &capacity)) {
    return false;
  }
  if (len) {
    MOZ_RELEASE_ASSERT(capacity >= len);
    UniquePtr<uint8_t[]> data(new uint8_t[capacity]);
    if (!aMsg->ReadBytesInto(aIter, data.get(), len)) {
      return false;
    }
    data_ = std::move(data);
    len_ = len;
    capacity_ = capacity;
  }

  if (!aMsg->ReadUInt32(aIter, &len)) {
    return false;
  }
  if (len) {
    UniquePtr<uint8_t[]> data(new uint8_t[len]);
    if (!aMsg->ReadBytesInto(aIter, data.get(), len)) {
      return false;
    }
    encrypted_data_ = std::move(data);
    encrypted_len_ = len;
  }

  int32_t sdp_level;
  if (!aMsg->ReadInt32(aIter, &sdp_level)) {
    return false;
  }

  if (sdp_level >= 0) {
    sdp_level_ = Some(sdp_level);
  }

  int32_t type;
  if (!aMsg->ReadInt32(aIter, &type)) {
    return false;
  }
  type_ = static_cast<Type>(type);
  return true;
}

static bool IsRtp(const uint8_t* data, size_t len) {
  if (len < 2) return false;

  // Check if this is a RTCP packet. Logic based on the types listed in
  // media/webrtc/trunk/src/modules/rtp_rtcp/source/rtp_utility.cc

  // Anything outside this range is RTP.
  if ((data[1] < 192) || (data[1] > 207)) return true;

  if (data[1] == 192)  // FIR
    return false;

  if (data[1] == 193)  // NACK, but could also be RTP. This makes us sad
    return true;       // but it's how webrtc.org behaves.

  if (data[1] == 194) return true;

  if (data[1] == 195)  // IJ.
    return false;

  if ((data[1] > 195) && (data[1] < 200))  // the > 195 is redundant
    return true;

  if ((data[1] >= 200) && (data[1] <= 207))  // SR, RR, SDES, BYE,
    return false;                            // APP, RTPFB, PSFB, XR

  MOZ_ASSERT(false);  // Not reached, belt and suspenders.
  return true;
}

void MediaPacket::Categorize() {
  SetType(MediaPacket::UNCLASSIFIED);

  if (!data_ || len_ < 4) {
    return;
  }

  if (data_[0] >= 20 && data_[0] <= 63) {
    // DTLS per RFC 7983
    SetType(MediaPacket::DTLS);
  } else if (data_[0] > 127 && data_[0] < 192) {
    // RTP/RTCP per RFC 7983
    if (IsRtp(data_.get(), len_)) {
      SetType(MediaPacket::SRTP);
    } else {
      SetType(MediaPacket::SRTCP);
    }
  }
}
}  // namespace mozilla