• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_
12 #define MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_
13 
14 #include <map>
15 #include <set>
16 #include <vector>
17 
18 #include "media/base/media_channel.h"
19 #include "media/base/rtp_utils.h"
20 #include "rtc_base/byte_order.h"
21 #include "rtc_base/copy_on_write_buffer.h"
22 #include "rtc_base/dscp.h"
23 #include "rtc_base/message_handler.h"
24 #include "rtc_base/synchronization/mutex.h"
25 #include "rtc_base/thread.h"
26 
27 namespace cricket {
28 
29 // Fake NetworkInterface that sends/receives RTP/RTCP packets.
30 class FakeNetworkInterface : public MediaChannel::NetworkInterface,
31                              public rtc::MessageHandler {
32  public:
FakeNetworkInterface()33   FakeNetworkInterface()
34       : thread_(rtc::Thread::Current()),
35         dest_(NULL),
36         conf_(false),
37         sendbuf_size_(-1),
38         recvbuf_size_(-1),
39         dscp_(rtc::DSCP_NO_CHANGE) {}
40 
SetDestination(MediaChannel * dest)41   void SetDestination(MediaChannel* dest) { dest_ = dest; }
42 
43   // Conference mode is a mode where instead of simply forwarding the packets,
44   // the transport will send multiple copies of the packet with the specified
45   // SSRCs. This allows us to simulate receiving media from multiple sources.
SetConferenceMode(bool conf,const std::vector<uint32_t> & ssrcs)46   void SetConferenceMode(bool conf, const std::vector<uint32_t>& ssrcs)
47       RTC_LOCKS_EXCLUDED(mutex_) {
48     webrtc::MutexLock lock(&mutex_);
49     conf_ = conf;
50     conf_sent_ssrcs_ = ssrcs;
51   }
52 
NumRtpBytes()53   int NumRtpBytes() RTC_LOCKS_EXCLUDED(mutex_) {
54     webrtc::MutexLock lock(&mutex_);
55     int bytes = 0;
56     for (size_t i = 0; i < rtp_packets_.size(); ++i) {
57       bytes += static_cast<int>(rtp_packets_[i].size());
58     }
59     return bytes;
60   }
61 
NumRtpBytes(uint32_t ssrc)62   int NumRtpBytes(uint32_t ssrc) RTC_LOCKS_EXCLUDED(mutex_) {
63     webrtc::MutexLock lock(&mutex_);
64     int bytes = 0;
65     GetNumRtpBytesAndPackets(ssrc, &bytes, NULL);
66     return bytes;
67   }
68 
NumRtpPackets()69   int NumRtpPackets() RTC_LOCKS_EXCLUDED(mutex_) {
70     webrtc::MutexLock lock(&mutex_);
71     return static_cast<int>(rtp_packets_.size());
72   }
73 
NumRtpPackets(uint32_t ssrc)74   int NumRtpPackets(uint32_t ssrc) RTC_LOCKS_EXCLUDED(mutex_) {
75     webrtc::MutexLock lock(&mutex_);
76     int packets = 0;
77     GetNumRtpBytesAndPackets(ssrc, NULL, &packets);
78     return packets;
79   }
80 
NumSentSsrcs()81   int NumSentSsrcs() RTC_LOCKS_EXCLUDED(mutex_) {
82     webrtc::MutexLock lock(&mutex_);
83     return static_cast<int>(sent_ssrcs_.size());
84   }
85 
86   // Note: callers are responsible for deleting the returned buffer.
GetRtpPacket(int index)87   const rtc::CopyOnWriteBuffer* GetRtpPacket(int index)
88       RTC_LOCKS_EXCLUDED(mutex_) {
89     webrtc::MutexLock lock(&mutex_);
90     if (index >= static_cast<int>(rtp_packets_.size())) {
91       return NULL;
92     }
93     return new rtc::CopyOnWriteBuffer(rtp_packets_[index]);
94   }
95 
NumRtcpPackets()96   int NumRtcpPackets() RTC_LOCKS_EXCLUDED(mutex_) {
97     webrtc::MutexLock lock(&mutex_);
98     return static_cast<int>(rtcp_packets_.size());
99   }
100 
101   // Note: callers are responsible for deleting the returned buffer.
GetRtcpPacket(int index)102   const rtc::CopyOnWriteBuffer* GetRtcpPacket(int index)
103       RTC_LOCKS_EXCLUDED(mutex_) {
104     webrtc::MutexLock lock(&mutex_);
105     if (index >= static_cast<int>(rtcp_packets_.size())) {
106       return NULL;
107     }
108     return new rtc::CopyOnWriteBuffer(rtcp_packets_[index]);
109   }
110 
sendbuf_size()111   int sendbuf_size() const { return sendbuf_size_; }
recvbuf_size()112   int recvbuf_size() const { return recvbuf_size_; }
dscp()113   rtc::DiffServCodePoint dscp() const { return dscp_; }
options()114   rtc::PacketOptions options() const { return options_; }
115 
116  protected:
SendPacket(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)117   virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet,
118                           const rtc::PacketOptions& options)
119       RTC_LOCKS_EXCLUDED(mutex_) {
120     webrtc::MutexLock lock(&mutex_);
121 
122     uint32_t cur_ssrc = 0;
123     if (!GetRtpSsrc(packet->data(), packet->size(), &cur_ssrc)) {
124       return false;
125     }
126     sent_ssrcs_[cur_ssrc]++;
127     options_ = options;
128 
129     rtp_packets_.push_back(*packet);
130     if (conf_) {
131       for (size_t i = 0; i < conf_sent_ssrcs_.size(); ++i) {
132         if (!SetRtpSsrc(packet->data(), packet->size(), conf_sent_ssrcs_[i])) {
133           return false;
134         }
135         PostMessage(ST_RTP, *packet);
136       }
137     } else {
138       PostMessage(ST_RTP, *packet);
139     }
140     return true;
141   }
142 
SendRtcp(rtc::CopyOnWriteBuffer * packet,const rtc::PacketOptions & options)143   virtual bool SendRtcp(rtc::CopyOnWriteBuffer* packet,
144                         const rtc::PacketOptions& options)
145       RTC_LOCKS_EXCLUDED(mutex_) {
146     webrtc::MutexLock lock(&mutex_);
147     rtcp_packets_.push_back(*packet);
148     options_ = options;
149     if (!conf_) {
150       // don't worry about RTCP in conf mode for now
151       PostMessage(ST_RTCP, *packet);
152     }
153     return true;
154   }
155 
SetOption(SocketType type,rtc::Socket::Option opt,int option)156   virtual int SetOption(SocketType type, rtc::Socket::Option opt, int option) {
157     if (opt == rtc::Socket::OPT_SNDBUF) {
158       sendbuf_size_ = option;
159     } else if (opt == rtc::Socket::OPT_RCVBUF) {
160       recvbuf_size_ = option;
161     } else if (opt == rtc::Socket::OPT_DSCP) {
162       dscp_ = static_cast<rtc::DiffServCodePoint>(option);
163     }
164     return 0;
165   }
166 
PostMessage(int id,const rtc::CopyOnWriteBuffer & packet)167   void PostMessage(int id, const rtc::CopyOnWriteBuffer& packet) {
168     thread_->Post(RTC_FROM_HERE, this, id, rtc::WrapMessageData(packet));
169   }
170 
OnMessage(rtc::Message * msg)171   virtual void OnMessage(rtc::Message* msg) {
172     rtc::TypedMessageData<rtc::CopyOnWriteBuffer>* msg_data =
173         static_cast<rtc::TypedMessageData<rtc::CopyOnWriteBuffer>*>(msg->pdata);
174     if (dest_) {
175       if (msg->message_id == ST_RTP) {
176         dest_->OnPacketReceived(msg_data->data(), rtc::TimeMicros());
177       } else {
178         RTC_LOG(LS_VERBOSE) << "Dropping RTCP packet, they not handled by "
179                                "MediaChannel anymore.";
180       }
181     }
182     delete msg_data;
183   }
184 
185  private:
GetNumRtpBytesAndPackets(uint32_t ssrc,int * bytes,int * packets)186   void GetNumRtpBytesAndPackets(uint32_t ssrc, int* bytes, int* packets) {
187     if (bytes) {
188       *bytes = 0;
189     }
190     if (packets) {
191       *packets = 0;
192     }
193     uint32_t cur_ssrc = 0;
194     for (size_t i = 0; i < rtp_packets_.size(); ++i) {
195       if (!GetRtpSsrc(rtp_packets_[i].data(), rtp_packets_[i].size(),
196                       &cur_ssrc)) {
197         return;
198       }
199       if (ssrc == cur_ssrc) {
200         if (bytes) {
201           *bytes += static_cast<int>(rtp_packets_[i].size());
202         }
203         if (packets) {
204           ++(*packets);
205         }
206       }
207     }
208   }
209 
210   rtc::Thread* thread_;
211   MediaChannel* dest_;
212   bool conf_;
213   // The ssrcs used in sending out packets in conference mode.
214   std::vector<uint32_t> conf_sent_ssrcs_;
215   // Map to track counts of packets that have been sent per ssrc.
216   // This includes packets that are dropped.
217   std::map<uint32_t, uint32_t> sent_ssrcs_;
218   // Map to track packet-number that needs to be dropped per ssrc.
219   std::map<uint32_t, std::set<uint32_t> > drop_map_;
220   webrtc::Mutex mutex_;
221   std::vector<rtc::CopyOnWriteBuffer> rtp_packets_;
222   std::vector<rtc::CopyOnWriteBuffer> rtcp_packets_;
223   int sendbuf_size_;
224   int recvbuf_size_;
225   rtc::DiffServCodePoint dscp_;
226   // Options of the most recently sent packet.
227   rtc::PacketOptions options_;
228 };
229 
230 }  // namespace cricket
231 
232 #endif  // MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_
233