1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org#include "webrtc/voice_engine/voe_network_impl.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
14ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
15ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org#include "webrtc/system_wrappers/interface/trace.h"
16ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org#include "webrtc/voice_engine/channel.h"
17ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org#include "webrtc/voice_engine/include/voe_errors.h"
18ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org#include "webrtc/voice_engine/voice_engine_impl.h"
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoENetwork* VoENetwork::GetInterface(VoiceEngine* voiceEngine)
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (NULL == voiceEngine)
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return NULL;
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
29b9e5a3d589349ee55e41cb54eca4ec822018f5c5tommi@webrtc.org    VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    s->AddRef();
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return s;
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoENetworkImpl::VoENetworkImpl(voe::SharedData* shared) : _shared(shared)
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "VoENetworkImpl() - ctor");
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVoENetworkImpl::~VoENetworkImpl()
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "~VoENetworkImpl() - dtor");
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoENetworkImpl::RegisterExternalTransport(int channel,
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                              Transport& transport)
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "SetExternalTransport(channel=%d, transport=0x%x)",
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 channel, &transport);
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_shared->statistics().Initialized())
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_NOT_INITED, kTraceError);
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
57b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
58b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::Channel* channelPtr = ch.channel();
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (channelPtr == NULL)
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "SetExternalTransport() failed to locate channel");
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return channelPtr->RegisterExternalTransport(transport);
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoENetworkImpl::DeRegisterExternalTransport(int channel)
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "DeRegisterExternalTransport(channel=%d)", channel);
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_shared->statistics().Initialized())
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
748da2f653997d348799b6d28f00a3ff0dc2a03476henrika@webrtc.org        WEBRTC_TRACE(kTraceError, kTraceVoice,
758da2f653997d348799b6d28f00a3ff0dc2a03476henrika@webrtc.org                     VoEId(_shared->instance_id(), -1),
768da2f653997d348799b6d28f00a3ff0dc2a03476henrika@webrtc.org                     "DeRegisterExternalTransport() - invalid state");
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
78b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
79b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::Channel* channelPtr = ch.channel();
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (channelPtr == NULL)
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "DeRegisterExternalTransport() failed to locate channel");
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return channelPtr->DeRegisterExternalTransport();
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoENetworkImpl::ReceivedRTPPacket(int channel,
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      const void* data,
91fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org                                      unsigned int length) {
92fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org  return ReceivedRTPPacket(channel, data, length, webrtc::PacketTime());
93fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org}
94fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org
95fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.orgint VoENetworkImpl::ReceivedRTPPacket(int channel,
96fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org                                      const void* data,
97fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org                                      unsigned int length,
98fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org                                      const PacketTime& packet_time)
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_shared->instance_id(), -1),
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "ReceivedRTPPacket(channel=%d, length=%u)", channel, length);
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_shared->statistics().Initialized())
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_NOT_INITED, kTraceError);
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
107ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org    // L16 at 32 kHz, stereo, 10 ms frames (+12 byte RTP header) -> 1292 bytes
108ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org    if ((length < 12) || (length > 1292))
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
110ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org        _shared->SetLastError(VE_INVALID_PACKET);
111ad9cee8255a31367c0f6a04a610acf918babd499andrew@webrtc.org        LOG(LS_ERROR) << "Invalid packet length: " << length;
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (NULL == data)
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "ReceivedRTPPacket() invalid data vector");
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
120b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
121b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::Channel* channelPtr = ch.channel();
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (channelPtr == NULL)
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "ReceivedRTPPacket() failed to locate channel");
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!channelPtr->ExternalTransport())
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_INVALID_OPERATION, kTraceError,
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "ReceivedRTPPacket() external transport is not enabled");
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
135fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org    return channelPtr->ReceivedRTPPacket((const int8_t*) data, length,
136fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org                                         packet_time);
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VoENetworkImpl::ReceivedRTCPPacket(int channel, const void* data,
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       unsigned int length)
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_shared->instance_id(), -1),
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                 "ReceivedRTCPPacket(channel=%d, length=%u)", channel, length);
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_shared->statistics().Initialized())
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_NOT_INITED, kTraceError);
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (length < 4)
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_INVALID_PACKET, kTraceError,
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "ReceivedRTCPPacket() invalid packet length");
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (NULL == data)
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "ReceivedRTCPPacket() invalid data vector");
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
161b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
162b3ada1540827c60a63058570a94a57dfd260ad11pbos@webrtc.org    voe::Channel* channelPtr = ch.channel();
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (channelPtr == NULL)
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "ReceivedRTCPPacket() failed to locate channel");
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!channelPtr->ExternalTransport())
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _shared->SetLastError(VE_INVALID_OPERATION, kTraceError,
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            "ReceivedRTCPPacket() external transport is not enabled");
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
17554f03bc96c30337a3a97af7262cfb5148063b162pbos@webrtc.org    return channelPtr->ReceivedRTCPPacket((const int8_t*) data, length);
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1773b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace webrtc
178