1/*
2 * libjingle
3 * Copyright 2004--2007, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 *  1. Redistributions of source code must retain the above copyright notice,
9 *     this list of conditions and the following disclaimer.
10 *  2. Redistributions in binary form must reproduce the above copyright notice,
11 *     this list of conditions and the following disclaimer in the documentation
12 *     and/or other materials provided with the distribution.
13 *  3. The name of the author may not be used to endorse or promote products
14 *     derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef TALK_SESSION_PHONE_CHANNEL_H_
29#define TALK_SESSION_PHONE_CHANNEL_H_
30
31#include <string>
32#include <vector>
33
34#include "talk/base/asyncudpsocket.h"
35#include "talk/base/criticalsection.h"
36#include "talk/base/network.h"
37#include "talk/base/sigslot.h"
38#include "talk/p2p/client/socketmonitor.h"
39#include "talk/p2p/base/session.h"
40#include "talk/session/phone/audiomonitor.h"
41#include "talk/session/phone/mediaengine.h"
42#include "talk/session/phone/mediachannel.h"
43#include "talk/session/phone/mediamonitor.h"
44#include "talk/session/phone/rtcpmuxfilter.h"
45#include "talk/session/phone/srtpfilter.h"
46
47namespace cricket {
48
49class MediaContentDescription;
50class MediaSinkInterface;
51struct CryptoParams;
52
53enum {
54  MSG_ENABLE = 1,
55  MSG_DISABLE = 2,
56  MSG_MUTE = 3,
57  MSG_UNMUTE = 4,
58  MSG_SETREMOTECONTENT = 5,
59  MSG_SETLOCALCONTENT = 6,
60  MSG_EARLYMEDIATIMEOUT = 8,
61  MSG_PRESSDTMF = 9,
62  MSG_SETRENDERER = 10,
63  MSG_ADDSTREAM = 11,
64  MSG_REMOVESTREAM = 12,
65  MSG_SETRINGBACKTONE = 13,
66  MSG_PLAYRINGBACKTONE = 14,
67  MSG_SETMAXSENDBANDWIDTH = 15,
68  MSG_SETRTCPCNAME = 18,
69  MSG_SENDINTRAFRAME = 19,
70  MSG_REQUESTINTRAFRAME = 20,
71  MSG_RTPPACKET = 22,
72  MSG_RTCPPACKET = 23,
73  MSG_CHANNEL_ERROR = 24
74};
75
76// BaseChannel contains logic common to voice and video, including
77// enable/mute, marshaling calls to a worker thread, and
78// connection and media monitors.
79class BaseChannel
80    : public talk_base::MessageHandler, public sigslot::has_slots<>,
81      public MediaChannel::NetworkInterface {
82 public:
83  BaseChannel(talk_base::Thread* thread, MediaEngine* media_engine,
84              MediaChannel* channel, BaseSession* session,
85              const std::string& content_name,
86              TransportChannel* transport_channel);
87  virtual ~BaseChannel();
88
89  talk_base::Thread* worker_thread() const { return worker_thread_; }
90  BaseSession* session() const { return session_; }
91  const std::string& content_name() { return content_name_; }
92  TransportChannel* transport_channel() const {
93    return transport_channel_;
94  }
95  TransportChannel* rtcp_transport_channel() const {
96    return rtcp_transport_channel_;
97  }
98  bool enabled() const { return enabled_; }
99  bool secure() const { return srtp_filter_.IsActive(); }
100
101  // Channel control
102  bool SetRtcpCName(const std::string& cname);
103  bool SetLocalContent(const MediaContentDescription* content,
104                       ContentAction action);
105  bool SetRemoteContent(const MediaContentDescription* content,
106                        ContentAction action);
107  bool SetMaxSendBandwidth(int max_bandwidth);
108
109  bool Enable(bool enable);
110  bool Mute(bool mute);
111
112  // Multiplexing
113  bool RemoveStream(uint32 ssrc);
114
115  // Monitoring
116  void StartConnectionMonitor(int cms);
117  void StopConnectionMonitor();
118
119  // Set and get media sinks for recording media.
120  void set_received_media_sink(MediaSinkInterface* sink) {
121    talk_base::CritScope cs(&sink_critical_section_);
122    received_media_sink_ = sink;
123  }
124  const MediaSinkInterface* received_media_sink() {
125    talk_base::CritScope cs(&sink_critical_section_);
126    return received_media_sink_;
127  }
128  void set_sent_media_sink(MediaSinkInterface* sink) {
129    talk_base::CritScope cs(&sink_critical_section_);
130    sent_media_sink_ = sink;
131  }
132  const MediaSinkInterface* sent_media_sink() {
133    talk_base::CritScope cs(&sink_critical_section_);
134    return sent_media_sink_;
135  }
136
137 protected:
138  MediaEngine* media_engine() const { return media_engine_; }
139  virtual MediaChannel* media_channel() const { return media_channel_; }
140  void set_rtcp_transport_channel(TransportChannel* transport);
141  bool writable() const { return writable_; }
142  bool has_codec() const { return has_codec_; }
143  void set_has_codec(bool has_codec) { has_codec_ = has_codec; }
144  bool muted() const { return muted_; }
145  talk_base::Thread* signaling_thread() { return session_->signaling_thread(); }
146
147  void Send(uint32 id, talk_base::MessageData *pdata = NULL);
148  void Post(uint32 id, talk_base::MessageData *pdata = NULL);
149  void PostDelayed(int cmsDelay, uint32 id = 0,
150                   talk_base::MessageData *pdata = NULL);
151  void Clear(uint32 id = talk_base::MQID_ANY,
152             talk_base::MessageList* removed = NULL);
153  void FlushRtcpMessages();
154
155  // NetworkInterface implementation, called by MediaEngine
156  virtual bool SendPacket(talk_base::Buffer* packet);
157  virtual bool SendRtcp(talk_base::Buffer* packet);
158  virtual int SetOption(SocketType type, talk_base::Socket::Option o, int val);
159
160  // From TransportChannel
161  void OnWritableState(TransportChannel* channel);
162  void OnChannelRead(TransportChannel* channel, const char *data, size_t len);
163
164  bool SendPacket(bool rtcp, talk_base::Buffer* packet);
165  void HandlePacket(bool rtcp, talk_base::Buffer* packet);
166
167  // Setting the send codec based on the remote description.
168  void OnSessionState(BaseSession* session, BaseSession::State state);
169
170  void EnableMedia_w();
171  void DisableMedia_w();
172  void MuteMedia_w();
173  void UnmuteMedia_w();
174  void ChannelWritable_w();
175  void ChannelNotWritable_w();
176
177  struct StreamMessageData : public talk_base::MessageData {
178    StreamMessageData(uint32 s1, uint32 s2) : ssrc1(s1), ssrc2(s2) {}
179    uint32 ssrc1;
180    uint32 ssrc2;
181  };
182  virtual void RemoveStream_w(uint32 ssrc) = 0;
183
184  virtual void ChangeState() = 0;
185
186  struct SetRtcpCNameData : public talk_base::MessageData {
187    explicit SetRtcpCNameData(const std::string& cname)
188        : cname(cname), result(false) {}
189    std::string cname;
190    bool result;
191  };
192  bool SetRtcpCName_w(const std::string& cname);
193
194  struct SetContentData : public talk_base::MessageData {
195    SetContentData(const MediaContentDescription* content,
196                   ContentAction action)
197        : content(content), action(action), result(false) {}
198    const MediaContentDescription* content;
199    ContentAction action;
200    bool result;
201  };
202
203  // Gets the content appropriate to the channel (audio or video).
204  virtual const MediaContentDescription* GetFirstContent(
205      const SessionDescription* sdesc) = 0;
206  virtual bool SetLocalContent_w(const MediaContentDescription* content,
207                                 ContentAction action) = 0;
208  virtual bool SetRemoteContent_w(const MediaContentDescription* content,
209                                  ContentAction action) = 0;
210
211  bool SetSrtp_w(const std::vector<CryptoParams>& params, ContentAction action,
212                 ContentSource src);
213  bool SetRtcpMux_w(bool enable, ContentAction action, ContentSource src);
214
215  struct SetBandwidthData : public talk_base::MessageData {
216    explicit SetBandwidthData(int value) : value(value), result(false) {}
217    int value;
218    bool result;
219  };
220  bool SetMaxSendBandwidth_w(int max_bandwidth);
221
222  // From MessageHandler
223  virtual void OnMessage(talk_base::Message *pmsg);
224
225  // Handled in derived classes
226  virtual void OnConnectionMonitorUpdate(SocketMonitor *monitor,
227      const std::vector<ConnectionInfo> &infos) = 0;
228
229 private:
230  talk_base::Thread *worker_thread_;
231  MediaEngine *media_engine_;
232  BaseSession *session_;
233  MediaChannel *media_channel_;
234  // Media sinks to handle the received or sent RTP/RTCP packets. These are
235  // reference to the objects owned by the media recorder.
236  MediaSinkInterface* received_media_sink_;
237  MediaSinkInterface* sent_media_sink_;
238  talk_base::CriticalSection sink_critical_section_;
239
240  std::string content_name_;
241  TransportChannel *transport_channel_;
242  TransportChannel *rtcp_transport_channel_;
243  SrtpFilter srtp_filter_;
244  RtcpMuxFilter rtcp_mux_filter_;
245  talk_base::scoped_ptr<SocketMonitor> socket_monitor_;
246  bool enabled_;
247  bool writable_;
248  bool has_codec_;
249  bool muted_;
250};
251
252// VoiceChannel is a specialization that adds support for early media, DTMF,
253// and input/output level monitoring.
254class VoiceChannel : public BaseChannel {
255 public:
256  VoiceChannel(talk_base::Thread *thread, MediaEngine *media_engine,
257               VoiceMediaChannel *channel, BaseSession *session,
258               const std::string& content_name, bool rtcp);
259  ~VoiceChannel();
260
261  // downcasts a MediaChannel
262  virtual VoiceMediaChannel* media_channel() const {
263    return static_cast<VoiceMediaChannel*>(BaseChannel::media_channel());
264  }
265
266  // Add an incoming stream with the specified SSRC.
267  bool AddStream(uint32 ssrc);
268
269  bool SetRingbackTone(const void* buf, int len);
270  void SetEarlyMedia(bool enable);
271  // This signal is emitted when we have gone a period of time without
272  // receiving early media. When received, a UI should start playing its
273  // own ringing sound
274  sigslot::signal1<VoiceChannel*> SignalEarlyMediaTimeout;
275
276  bool PlayRingbackTone(bool play, bool loop);
277  bool PressDTMF(int digit, bool playout);
278
279  // Monitoring functions
280  sigslot::signal2<VoiceChannel*, const std::vector<ConnectionInfo> &>
281      SignalConnectionMonitor;
282
283  void StartMediaMonitor(int cms);
284  void StopMediaMonitor();
285  sigslot::signal2<VoiceChannel*, const VoiceMediaInfo&> SignalMediaMonitor;
286
287  void StartAudioMonitor(int cms);
288  void StopAudioMonitor();
289  sigslot::signal2<VoiceChannel*, const AudioInfo&> SignalAudioMonitor;
290
291  int GetInputLevel_w();
292  int GetOutputLevel_w();
293  void GetActiveStreams_w(AudioInfo::StreamList* actives);
294
295  // Signal errors from VoiceMediaChannel.  Arguments are:
296  //     ssrc(uint32), and error(VoiceMediaChannel::Error).
297  sigslot::signal3<VoiceChannel*, uint32, VoiceMediaChannel::Error>
298      SignalMediaError;
299
300 private:
301  struct SetRingbackToneMessageData : public talk_base::MessageData {
302    SetRingbackToneMessageData(const void* b, int l)
303        : buf(b),
304          len(l) {
305    }
306    const void* buf;
307    int len;
308  };
309  struct PlayRingbackToneMessageData : public talk_base::MessageData {
310    PlayRingbackToneMessageData(bool p, bool l)
311        : play(p),
312          loop(l),
313          result(false) {
314    }
315    bool play;
316    bool loop;
317    bool result;
318  };
319  struct DtmfMessageData : public talk_base::MessageData {
320    DtmfMessageData(int d, bool p)
321        : digit(d),
322          playout(p),
323          result(false) {
324    }
325    int digit;
326    bool playout;
327    bool result;
328  };
329
330  // overrides from BaseChannel
331  virtual void OnChannelRead(TransportChannel* channel,
332                             const char *data, size_t len);
333  virtual void ChangeState();
334  virtual const MediaContentDescription* GetFirstContent(
335      const SessionDescription* sdesc);
336  virtual bool SetLocalContent_w(const MediaContentDescription* content,
337                                 ContentAction action);
338  virtual bool SetRemoteContent_w(const MediaContentDescription* content,
339                                  ContentAction action);
340
341  void AddStream_w(uint32 ssrc);
342  void RemoveStream_w(uint32 ssrc);
343
344  void SetRingbackTone_w(const void* buf, int len);
345  bool PlayRingbackTone_w(bool play, bool loop);
346  void HandleEarlyMediaTimeout();
347  bool PressDTMF_w(int digit, bool playout);
348
349  virtual void OnMessage(talk_base::Message *pmsg);
350  virtual void OnConnectionMonitorUpdate(
351      SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos);
352  virtual void OnMediaMonitorUpdate(
353      VoiceMediaChannel *media_channel, const VoiceMediaInfo& info);
354  void OnAudioMonitorUpdate(AudioMonitor *monitor, const AudioInfo& info);
355  void OnVoiceChannelError(uint32 ssrc, VoiceMediaChannel::Error error);
356  void SendLastMediaError();
357
358  static const int kEarlyMediaTimeout = 1000;
359  bool received_media_;
360  talk_base::scoped_ptr<VoiceMediaMonitor> media_monitor_;
361  talk_base::scoped_ptr<AudioMonitor> audio_monitor_;
362};
363
364// VideoChannel is a specialization for video.
365class VideoChannel : public BaseChannel {
366 public:
367  VideoChannel(talk_base::Thread *thread, MediaEngine *media_engine,
368               VideoMediaChannel *channel, BaseSession *session,
369               const std::string& content_name, bool rtcp,
370               VoiceChannel *voice_channel);
371  ~VideoChannel();
372
373  // downcasts a MediaChannel
374  virtual VideoMediaChannel* media_channel() const {
375    return static_cast<VideoMediaChannel*>(BaseChannel::media_channel());
376  }
377
378  // Add an incoming stream with the specified SSRC.
379  bool AddStream(uint32 ssrc, uint32 voice_ssrc);
380
381  bool SetRenderer(uint32 ssrc, VideoRenderer* renderer);
382
383
384  sigslot::signal2<VideoChannel*, const std::vector<ConnectionInfo> &>
385      SignalConnectionMonitor;
386
387  void StartMediaMonitor(int cms);
388  void StopMediaMonitor();
389  sigslot::signal2<VideoChannel*, const VideoMediaInfo&> SignalMediaMonitor;
390
391  bool SendIntraFrame();
392  bool RequestIntraFrame();
393
394  sigslot::signal3<VideoChannel*, uint32, VideoMediaChannel::Error>
395      SignalMediaError;
396
397 private:
398  // overrides from BaseChannel
399  virtual void ChangeState();
400  virtual const MediaContentDescription* GetFirstContent(
401      const SessionDescription* sdesc);
402  virtual bool SetLocalContent_w(const MediaContentDescription* content,
403                                 ContentAction action);
404  virtual bool SetRemoteContent_w(const MediaContentDescription* content,
405                                  ContentAction action);
406
407  void AddStream_w(uint32 ssrc, uint32 voice_ssrc);
408  void RemoveStream_w(uint32 ssrc);
409
410  void SendIntraFrame_w() {
411    media_channel()->SendIntraFrame();
412  }
413  void RequestIntraFrame_w() {
414    media_channel()->RequestIntraFrame();
415  }
416
417  struct RenderMessageData : public talk_base::MessageData {
418    RenderMessageData(uint32 s, VideoRenderer* r) : ssrc(s), renderer(r) {}
419    uint32 ssrc;
420    VideoRenderer* renderer;
421  };
422
423
424  void SetRenderer_w(uint32 ssrc, VideoRenderer* renderer);
425
426
427  virtual void OnMessage(talk_base::Message *pmsg);
428  virtual void OnConnectionMonitorUpdate(
429      SocketMonitor *monitor, const std::vector<ConnectionInfo> &infos);
430  virtual void OnMediaMonitorUpdate(
431      VideoMediaChannel *media_channel, const VideoMediaInfo& info);
432  void OnVideoChannelError(uint32 ssrc, VideoMediaChannel::Error error);
433
434  VoiceChannel *voice_channel_;
435  VideoRenderer *renderer_;
436  talk_base::scoped_ptr<VideoMediaMonitor> media_monitor_;
437};
438
439}  // namespace cricket
440
441#endif  // TALK_SESSION_PHONE_CHANNEL_H_
442