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


#include "channel.h"
#include "critical_section_wrapper.h"
#include "trace.h"
#include "voe_errors.h"
#include "voice_engine_impl.h"

namespace webrtc {

VoEEncryption* VoEEncryption::GetInterface(VoiceEngine* voiceEngine)
{
#ifndef WEBRTC_VOICE_ENGINE_ENCRYPTION_API
    return NULL;
#else
    if (NULL == voiceEngine)
    {
        return NULL;
    }
    VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
    s->AddRef();
    return s;
#endif
}

#ifdef WEBRTC_VOICE_ENGINE_ENCRYPTION_API

VoEEncryptionImpl::VoEEncryptionImpl(voe::SharedData* shared) : _shared(shared)
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "VoEEncryptionImpl::VoEEncryptionImpl() - ctor");
}

VoEEncryptionImpl::~VoEEncryptionImpl()
{
    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "VoEEncryptionImpl::~VoEEncryptionImpl() - dtor");
}

int VoEEncryptionImpl::EnableSRTPSend(
    int channel,
    CipherTypes cipherType,
    int cipherKeyLength,
    AuthenticationTypes authType,
    int authKeyLength,
    int authTagLength,
    SecurityLevels level,
    const unsigned char key[kVoiceEngineMaxSrtpKeyLength],
    bool useForRTCP)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "EnableSRTPSend(channel=%i, cipherType=%i, cipherKeyLength=%i,"
                 " authType=%i, authKeyLength=%i, authTagLength=%i, level=%i, "
                 "key=?, useForRTCP=%d)",
                 channel, cipherType, cipherKeyLength, authType,
                 authKeyLength, authTagLength, level, useForRTCP);
#ifdef WEBRTC_SRTP
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    voe::ScopedChannel sc(_shared->channel_manager(), channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "EnableSRTPSend() failed to locate channel");
        return -1;
    }
    return channelPtr->EnableSRTPSend(cipherType,
                                      cipherKeyLength,
                                      authType,
                                      authKeyLength,
                                      authTagLength,
                                      level,
                                      key,
                                      useForRTCP);
#else
   _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
       "EnableSRTPSend() SRTP is not supported");
    return -1;
#endif
}

int VoEEncryptionImpl::DisableSRTPSend(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
               "DisableSRTPSend(channel=%i)",channel);
#ifdef WEBRTC_SRTP
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    voe::ScopedChannel sc(_shared->channel_manager(), channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "DisableSRTPSend() failed to locate channel");
        return -1;
    }
    return channelPtr->DisableSRTPSend();
#else
   _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
       "DisableSRTPSend() SRTP is not supported");
    return -1;
#endif
}

int VoEEncryptionImpl::EnableSRTPReceive(
    int channel,
    CipherTypes cipherType,
    int cipherKeyLength,
    AuthenticationTypes authType,
    int authKeyLength,
    int authTagLength,
    SecurityLevels level,
    const unsigned char key[kVoiceEngineMaxSrtpKeyLength],
		bool useForRTCP)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "EnableSRTPReceive(channel=%i, cipherType=%i, "
                 "cipherKeyLength=%i, authType=%i, authKeyLength=%i, "
                 "authTagLength=%i, level=%i, key=?, useForRTCP=%d)",
                 channel, cipherType, cipherKeyLength, authType,
                 authKeyLength, authTagLength, level, useForRTCP);
#ifdef WEBRTC_SRTP
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    voe::ScopedChannel sc(_shared->channel_manager(), channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "EnableSRTPReceive() failed to locate channel");
        return -1;
    }
    return channelPtr->EnableSRTPReceive(cipherType,
                                         cipherKeyLength,
	                                 authType,
	                                 authKeyLength,
	                                 authTagLength,
	                                 level,
	                                 key,
	                                 useForRTCP);
#else
   _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
       "EnableSRTPReceive() SRTP is not supported");
    return -1;
#endif
}

int VoEEncryptionImpl::DisableSRTPReceive(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "DisableSRTPReceive(channel=%i)", channel);
#ifdef WEBRTC_SRTP
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }

    voe::ScopedChannel sc(_shared->channel_manager(), channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "DisableSRTPReceive() failed to locate channel");
        return -1;
    }
    return channelPtr->DisableSRTPReceive();
#else
    _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceError,
        "DisableSRTPReceive() SRTP is not supported");
    return -1;
#endif
}

int VoEEncryptionImpl::RegisterExternalEncryption(int channel,
                                                  Encryption& encryption)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "RegisterExternalEncryption(channel=%d, encryption=0x%x)",
                 channel, &encryption);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ScopedChannel sc(_shared->channel_manager(), channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "RegisterExternalEncryption() failed to locate channel");
        return -1;
    }
    return channelPtr->RegisterExternalEncryption(encryption);
}

int VoEEncryptionImpl::DeRegisterExternalEncryption(int channel)
{
    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
                 "DeRegisterExternalEncryption(channel=%d)", channel);
    if (!_shared->statistics().Initialized())
    {
        _shared->SetLastError(VE_NOT_INITED, kTraceError);
        return -1;
    }
    voe::ScopedChannel sc(_shared->channel_manager(), channel);
    voe::Channel* channelPtr = sc.ChannelPtr();
    if (channelPtr == NULL)
    {
        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
            "DeRegisterExternalEncryption() failed to locate channel");
        return -1;
    }
    return channelPtr->DeRegisterExternalEncryption();
}

#endif  // #ifdef WEBRTC_VOICE_ENGINE_ENCRYPTION_API

// EOF
}  // namespace webrtc
