/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "webrtc/voice_engine/voe_network_impl.h"

#include "webrtc/base/checks.h"
#include "webrtc/base/format_macros.h"
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
#include "webrtc/system_wrappers/interface/logging.h"
#include "webrtc/system_wrappers/interface/trace.h"
#include "webrtc/voice_engine/channel.h"
#include "webrtc/voice_engine/include/voe_errors.h"
#include "webrtc/voice_engine/voice_engine_impl.h"

namespace webrtc {

VoENetwork* VoENetwork::GetInterface(VoiceEngine* voiceEngine) {
  if (!voiceEngine) {
    return nullptr;
  }
  VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
  s->AddRef();
  return s;
}

VoENetworkImpl::VoENetworkImpl(voe::SharedData* shared) : _shared(shared) {
}

VoENetworkImpl::~VoENetworkImpl() = default;

int VoENetworkImpl::RegisterExternalTransport(int channel,
                                              Transport& transport) {
  RTC_DCHECK(_shared->statistics().Initialized());
  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
  voe::Channel* channelPtr = ch.channel();
  if (!channelPtr) {
    LOG_F(LS_ERROR) << "Failed to locate channel: " << channel;
    return -1;
  }
  return channelPtr->RegisterExternalTransport(transport);
}

int VoENetworkImpl::DeRegisterExternalTransport(int channel) {
  RTC_CHECK(_shared->statistics().Initialized());
  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
  voe::Channel* channelPtr = ch.channel();
  if (!channelPtr) {
    LOG_F(LS_ERROR) << "Failed to locate channel: " << channel;
    return -1;
  }
  return channelPtr->DeRegisterExternalTransport();
}

int VoENetworkImpl::ReceivedRTPPacket(int channel,
                                      const void* data,
                                      size_t length) {
  return ReceivedRTPPacket(channel, data, length, webrtc::PacketTime());
}

int VoENetworkImpl::ReceivedRTPPacket(int channel,
                                      const void* data,
                                      size_t length,
                                      const PacketTime& packet_time) {
  RTC_CHECK(_shared->statistics().Initialized());
  RTC_CHECK(data);
  // L16 at 32 kHz, stereo, 10 ms frames (+12 byte RTP header) -> 1292 bytes
  if ((length < 12) || (length > 1292)) {
    LOG_F(LS_ERROR) << "Invalid packet length: " << length;
    return -1;
  }
  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
  voe::Channel* channelPtr = ch.channel();
  if (!channelPtr) {
    LOG_F(LS_ERROR) << "Failed to locate channel: " << channel;
    return -1;
  }
  if (!channelPtr->ExternalTransport()) {
    LOG_F(LS_ERROR) << "No external transport for channel: " << channel;
    return -1;
  }
  return channelPtr->ReceivedRTPPacket((const int8_t*)data, length,
                                       packet_time);
}

int VoENetworkImpl::ReceivedRTCPPacket(int channel,
                                       const void* data,
                                       size_t length) {
  RTC_CHECK(_shared->statistics().Initialized());
  RTC_CHECK(data);
  if (length < 4) {
    LOG_F(LS_ERROR) << "Invalid packet length: " << length;
    return -1;
  }
  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
  voe::Channel* channelPtr = ch.channel();
  if (!channelPtr) {
    LOG_F(LS_ERROR) << "Failed to locate channel: " << channel;
    return -1;
  }
  if (!channelPtr->ExternalTransport()) {
    LOG_F(LS_ERROR) << "No external transport for channel: " << channel;
    return -1;
  }
  return channelPtr->ReceivedRTCPPacket((const int8_t*)data, length);
}

}  // namespace webrtc
