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 47 namespace cricket { 48 49 class MediaContentDescription; 50 class MediaSinkInterface; 51 struct CryptoParams; 52 53 enum { 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. 79 class 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. 254 class 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. 365 class 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