1 /* 2 * libjingle 3 * Copyright 2004--2005, 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_MEDIASESSIONCLIENT_H_ 29 #define TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_ 30 31 #include <string> 32 #include <vector> 33 #include <map> 34 #include <algorithm> 35 #include "talk/session/phone/call.h" 36 #include "talk/session/phone/channelmanager.h" 37 #include "talk/session/phone/cryptoparams.h" 38 #include "talk/base/sigslot.h" 39 #include "talk/base/sigslotrepeater.h" 40 #include "talk/base/messagequeue.h" 41 #include "talk/base/thread.h" 42 #include "talk/p2p/base/sessionmanager.h" 43 #include "talk/p2p/base/session.h" 44 #include "talk/p2p/base/sessionclient.h" 45 #include "talk/p2p/base/sessiondescription.h" 46 47 namespace cricket { 48 49 class Call; 50 class SessionDescription; 51 typedef std::vector<AudioCodec> AudioCodecs; 52 typedef std::vector<VideoCodec> VideoCodecs; 53 54 // SEC_ENABLED and SEC_REQUIRED should only be used if the session 55 // was negotiated over TLS, to protect the inline crypto material 56 // exchange. 57 // SEC_DISABLED: No crypto in outgoing offer and answer. Fail any 58 // offer with crypto required. 59 // SEC_ENABLED: Crypto in outgoing offer and answer. Fail any offer 60 // with unsupported required crypto. Crypto set but not 61 // required in outgoing offer. 62 // SEC_REQUIRED: Crypto in outgoing offer and answer with 63 // required='true'. Fail any offer with no or 64 // unsupported crypto (implicit crypto required='true' 65 // in the offer.) 66 enum SecureMediaPolicy {SEC_DISABLED, SEC_ENABLED, SEC_REQUIRED}; 67 68 const int kAutoBandwidth = -1; 69 70 struct CallOptions { CallOptionsCallOptions71 CallOptions() : 72 is_video(false), 73 is_muc(false), 74 video_bandwidth(kAutoBandwidth) { 75 } 76 77 bool is_video; 78 bool is_muc; 79 // bps. -1 == auto. 80 int video_bandwidth; 81 }; 82 83 class MediaSessionClient: public SessionClient, public sigslot::has_slots<> { 84 public: 85 86 MediaSessionClient(const buzz::Jid& jid, SessionManager *manager); 87 // Alternative constructor, allowing injection of media_engine 88 // and device_manager. 89 MediaSessionClient(const buzz::Jid& jid, SessionManager *manager, 90 MediaEngine* media_engine, DeviceManager* device_manager); 91 ~MediaSessionClient(); 92 jid()93 const buzz::Jid &jid() const { return jid_; } session_manager()94 SessionManager* session_manager() const { return session_manager_; } channel_manager()95 ChannelManager* channel_manager() const { return channel_manager_; } 96 GetCapabilities()97 int GetCapabilities() { return channel_manager_->GetCapabilities(); } 98 99 Call *CreateCall(); 100 void DestroyCall(Call *call); 101 102 Call *GetFocus(); 103 void SetFocus(Call *call); 104 105 void JoinCalls(Call *call_to_join, Call *call); 106 GetAudioInputDevices(std::vector<std::string> * names)107 bool GetAudioInputDevices(std::vector<std::string>* names) { 108 return channel_manager_->GetAudioInputDevices(names); 109 } GetAudioOutputDevices(std::vector<std::string> * names)110 bool GetAudioOutputDevices(std::vector<std::string>* names) { 111 return channel_manager_->GetAudioOutputDevices(names); 112 } GetVideoCaptureDevices(std::vector<std::string> * names)113 bool GetVideoCaptureDevices(std::vector<std::string>* names) { 114 return channel_manager_->GetVideoCaptureDevices(names); 115 } 116 SetAudioOptions(const std::string & in_name,const std::string & out_name,int opts)117 bool SetAudioOptions(const std::string& in_name, const std::string& out_name, 118 int opts) { 119 return channel_manager_->SetAudioOptions(in_name, out_name, opts); 120 } SetOutputVolume(int level)121 bool SetOutputVolume(int level) { 122 return channel_manager_->SetOutputVolume(level); 123 } SetVideoOptions(const std::string & cam_device)124 bool SetVideoOptions(const std::string& cam_device) { 125 return channel_manager_->SetVideoOptions(cam_device); 126 } 127 128 sigslot::signal2<Call *, Call *> SignalFocus; 129 sigslot::signal1<Call *> SignalCallCreate; 130 sigslot::signal1<Call *> SignalCallDestroy; 131 sigslot::repeater0<> SignalDevicesChange; 132 133 SessionDescription* CreateOffer(const CallOptions& options); 134 SessionDescription* CreateAnswer(const SessionDescription* offer, 135 const CallOptions& options); 136 secure()137 SecureMediaPolicy secure() const { return secure_; } set_secure(SecureMediaPolicy s)138 void set_secure(SecureMediaPolicy s) { secure_ = s; } 139 140 private: 141 void Construct(); 142 void OnSessionCreate(Session *session, bool received_initiate); 143 void OnSessionState(BaseSession *session, BaseSession::State state); 144 void OnSessionDestroy(Session *session); 145 virtual bool ParseContent(SignalingProtocol protocol, 146 const buzz::XmlElement* elem, 147 const ContentDescription** content, 148 ParseError* error); 149 virtual bool WriteContent(SignalingProtocol protocol, 150 const ContentDescription* content, 151 buzz::XmlElement** elem, 152 WriteError* error); 153 Session *CreateSession(Call *call); 154 155 buzz::Jid jid_; 156 SessionManager* session_manager_; 157 Call *focus_call_; 158 ChannelManager *channel_manager_; 159 std::map<uint32, Call *> calls_; 160 std::map<std::string, Call *> session_map_; 161 SecureMediaPolicy secure_; 162 friend class Call; 163 }; 164 165 enum MediaType { 166 MEDIA_TYPE_AUDIO, 167 MEDIA_TYPE_VIDEO 168 }; 169 170 class MediaContentDescription : public ContentDescription { 171 public: MediaContentDescription()172 MediaContentDescription() 173 : ssrc_(0), 174 ssrc_set_(false), 175 rtcp_mux_(false), 176 rtp_headers_disabled_(false), 177 crypto_required_(false), 178 bandwidth_(kAutoBandwidth) { 179 } 180 181 virtual MediaType type() const = 0; 182 ssrc()183 uint32 ssrc() const { return ssrc_; } ssrc_set()184 bool ssrc_set() const { return ssrc_set_; } set_ssrc(uint32 ssrc)185 void set_ssrc(uint32 ssrc) { 186 ssrc_ = ssrc; 187 ssrc_set_ = true; 188 } 189 rtcp_mux()190 bool rtcp_mux() const { return rtcp_mux_; } set_rtcp_mux(bool mux)191 void set_rtcp_mux(bool mux) { rtcp_mux_ = mux; } 192 rtp_headers_disabled()193 bool rtp_headers_disabled() const { 194 return rtp_headers_disabled_; 195 } set_rtp_headers_disabled(bool disable)196 void set_rtp_headers_disabled(bool disable) { 197 rtp_headers_disabled_ = disable; 198 } 199 cryptos()200 const std::vector<CryptoParams>& cryptos() const { return cryptos_; } AddCrypto(const CryptoParams & params)201 void AddCrypto(const CryptoParams& params) { 202 cryptos_.push_back(params); 203 } crypto_required()204 bool crypto_required() const { return crypto_required_; } set_crypto_required(bool crypto)205 void set_crypto_required(bool crypto) { 206 crypto_required_ = crypto; 207 } 208 bandwidth()209 int bandwidth() const { return bandwidth_; } set_bandwidth(int bandwidth)210 void set_bandwidth(int bandwidth) { bandwidth_ = bandwidth; } 211 212 protected: 213 uint32 ssrc_; 214 bool ssrc_set_; 215 bool rtcp_mux_; 216 bool rtp_headers_disabled_; 217 std::vector<CryptoParams> cryptos_; 218 bool crypto_required_; 219 int bandwidth_; 220 }; 221 222 template <class C> 223 class MediaContentDescriptionImpl : public MediaContentDescription { 224 public: 225 struct PreferenceSort { operatorPreferenceSort226 bool operator()(C a, C b) { return a.preference > b.preference; } 227 }; 228 codecs()229 const std::vector<C>& codecs() const { return codecs_; } AddCodec(const C & codec)230 void AddCodec(const C& codec) { 231 codecs_.push_back(codec); 232 } SortCodecs()233 void SortCodecs() { 234 std::sort(codecs_.begin(), codecs_.end(), PreferenceSort()); 235 } 236 237 private: 238 std::vector<C> codecs_; 239 }; 240 241 class AudioContentDescription : public MediaContentDescriptionImpl<AudioCodec> { 242 public: AudioContentDescription()243 AudioContentDescription() : 244 conference_mode_(false) {} 245 type()246 virtual MediaType type() const { return MEDIA_TYPE_AUDIO; } 247 conference_mode()248 bool conference_mode() const { return conference_mode_; } set_conference_mode(bool enable)249 void set_conference_mode(bool enable) { 250 conference_mode_ = enable; 251 } 252 lang()253 const std::string &lang() const { return lang_; } set_lang(const std::string & lang)254 void set_lang(const std::string &lang) { lang_ = lang; } 255 256 257 private: 258 bool conference_mode_; 259 std::string lang_; 260 }; 261 262 class VideoContentDescription : public MediaContentDescriptionImpl<VideoCodec> { 263 public: type()264 virtual MediaType type() const { return MEDIA_TYPE_VIDEO; } 265 }; 266 267 // Convenience functions. 268 const ContentInfo* GetFirstAudioContent(const SessionDescription* sdesc); 269 const ContentInfo* GetFirstVideoContent(const SessionDescription* sdesc); 270 271 272 } // namespace cricket 273 274 #endif // TALK_SESSION_PHONE_MEDIASESSIONCLIENT_H_ 275