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_EXAMPLES_CALL_CALLCLIENT_H_
29#define TALK_EXAMPLES_CALL_CALLCLIENT_H_
30
31#include <map>
32#include <string>
33#include <vector>
34
35#include "talk/examples/call/console.h"
36#include "talk/media/base/mediachannel.h"
37#include "talk/p2p/base/session.h"
38#include "talk/session/media/mediamessages.h"
39#include "talk/session/media/mediasessionclient.h"
40#include "talk/xmpp/hangoutpubsubclient.h"
41#include "talk/xmpp/presencestatus.h"
42#include "talk/xmpp/xmppclient.h"
43#include "webrtc/base/scoped_ptr.h"
44#include "webrtc/base/sslidentity.h"
45
46namespace buzz {
47class PresencePushTask;
48class PresenceOutTask;
49class MucInviteRecvTask;
50class MucInviteSendTask;
51class FriendInviteSendTask;
52class DiscoInfoQueryTask;
53class Muc;
54class PresenceStatus;
55class IqTask;
56class MucRoomConfigTask;
57class MucRoomLookupTask;
58class MucPresenceStatus;
59class XmlElement;
60class HangoutPubSubClient;
61struct AvailableMediaEntry;
62struct MucRoomInfo;
63}  // namespace buzz
64
65namespace rtc {
66class Thread;
67class NetworkManager;
68}  // namespace rtc
69
70namespace cricket {
71class PortAllocator;
72class MediaEngineInterface;
73class MediaSessionClient;
74class Call;
75class SessionManagerTask;
76struct CallOptions;
77struct MediaStreams;
78struct StreamParams;
79}  // namespace cricket
80
81struct RosterItem {
82  buzz::Jid jid;
83  buzz::PresenceStatus::Show show;
84  std::string status;
85};
86
87struct StaticRenderedView {
88  StaticRenderedView(const cricket::StaticVideoView& view,
89                     cricket::VideoRenderer* renderer) :
90      view(view),
91      renderer(renderer) {
92  }
93
94  cricket::StaticVideoView view;
95  cricket::VideoRenderer* renderer;
96};
97
98// Maintain a mapping of (session, ssrc) to rendered view.
99typedef std::map<std::pair<cricket::Session*, uint32>,
100                 StaticRenderedView> StaticRenderedViews;
101
102class CallClient: public sigslot::has_slots<> {
103 public:
104  CallClient(buzz::XmppClient* xmpp_client,
105             const std::string& caps_node,
106             const std::string& version);
107  ~CallClient();
108
109  cricket::MediaSessionClient* media_client() const { return media_client_; }
110  void SetMediaEngine(cricket::MediaEngineInterface* media_engine) {
111    media_engine_ = media_engine;
112  }
113  void SetAutoAccept(bool auto_accept) {
114    auto_accept_ = auto_accept;
115  }
116  void SetPmucDomain(const std::string &pmuc_domain) {
117    pmuc_domain_ = pmuc_domain;
118  }
119  void SetRender(bool render) {
120    render_ = render;
121  }
122  void SetDataChannelType(cricket::DataChannelType data_channel_type) {
123    data_channel_type_ = data_channel_type;
124  }
125  void SetMultiSessionEnabled(bool multisession_enabled) {
126    multisession_enabled_ = multisession_enabled;
127  }
128  void SetConsole(Console *console) {
129    console_ = console;
130  }
131  void SetPriority(int priority) {
132    my_status_.set_priority(priority);
133  }
134  void SendStatus() {
135    SendStatus(my_status_);
136  }
137  void SendStatus(const buzz::PresenceStatus& status);
138
139  void ParseLine(const std::string &str);
140
141  void SendChat(const std::string& to, const std::string msg);
142  void SendData(const std::string& stream_name,
143                const std::string& text);
144  void InviteFriend(const std::string& user);
145  void JoinMuc(const buzz::Jid& room_jid);
146  void JoinMuc(const std::string& room_jid_str);
147  void LookupAndJoinMuc(const std::string& room_name);
148  void InviteToMuc(const std::string& user, const std::string& room);
149  bool InMuc();
150  const buzz::Jid* FirstMucJid();
151  void LeaveMuc(const std::string& room);
152  void SetNick(const std::string& muc_nick);
153  void SetPortAllocatorFlags(uint32 flags) { portallocator_flags_ = flags; }
154  void SetAllowLocalIps(bool allow_local_ips) {
155    allow_local_ips_ = allow_local_ips;
156  }
157
158  void SetSignalingProtocol(cricket::SignalingProtocol protocol) {
159    signaling_protocol_ = protocol;
160  }
161  void SetTransportProtocol(cricket::TransportProtocol protocol) {
162    transport_protocol_ = protocol;
163  }
164  void SetSecurePolicy(cricket::SecurePolicy sdes_policy,
165                       cricket::SecurePolicy dtls_policy) {
166    sdes_policy_ = sdes_policy;
167    dtls_policy_ = dtls_policy;
168  }
169  void SetSslIdentity(rtc::SSLIdentity* identity) {
170    ssl_identity_.reset(identity);
171  }
172
173  typedef std::map<buzz::Jid, buzz::Muc*> MucMap;
174
175  const MucMap& mucs() const {
176    return mucs_;
177  }
178
179  void SetShowRosterMessages(bool show_roster_messages) {
180    show_roster_messages_ = show_roster_messages;
181  }
182
183 private:
184  void AddStream(uint32 audio_src_id, uint32 video_src_id);
185  void RemoveStream(uint32 audio_src_id, uint32 video_src_id);
186  void OnStateChange(buzz::XmppEngine::State state);
187
188  void InitMedia();
189  void InitPresence();
190  void StartXmppPing();
191  void OnPingTimeout();
192  void OnRequestSignaling();
193  void OnSessionCreate(cricket::Session* session, bool initiate);
194  void OnCallCreate(cricket::Call* call);
195  void OnCallDestroy(cricket::Call* call);
196  void OnSessionState(cricket::Call* call,
197                      cricket::Session* session,
198                      cricket::Session::State state);
199  void OnStatusUpdate(const buzz::PresenceStatus& status);
200  void OnMucInviteReceived(const buzz::Jid& inviter, const buzz::Jid& room,
201      const std::vector<buzz::AvailableMediaEntry>& avail);
202  void OnMucJoined(const buzz::Jid& endpoint);
203  void OnMucStatusUpdate(const buzz::Jid& jid,
204                         const buzz::MucPresenceStatus& status);
205  void OnMucLeft(const buzz::Jid& endpoint, int error);
206  void OnPresenterStateChange(const std::string& nick,
207                              bool was_presenting, bool is_presenting);
208  void OnAudioMuteStateChange(const std::string& nick,
209                              bool was_muted, bool is_muted);
210  void OnRecordingStateChange(const std::string& nick,
211                              bool was_recording, bool is_recording);
212  void OnRemoteMuted(const std::string& mutee_nick,
213                     const std::string& muter_nick,
214                     bool should_mute_locally);
215  void OnMediaBlocked(const std::string& blockee_nick,
216                      const std::string& blocker_nick);
217  void OnHangoutRequestError(const std::string& node,
218                             const buzz::XmlElement* stanza);
219  void OnHangoutPublishAudioMuteError(const std::string& task_id,
220                                      const buzz::XmlElement* stanza);
221  void OnHangoutPublishPresenterError(const std::string& task_id,
222                                      const buzz::XmlElement* stanza);
223  void OnHangoutPublishRecordingError(const std::string& task_id,
224                                      const buzz::XmlElement* stanza);
225  void OnHangoutRemoteMuteError(const std::string& task_id,
226                                const std::string& mutee_nick,
227                                const buzz::XmlElement* stanza);
228  void OnDevicesChange();
229  void OnMediaStreamsUpdate(cricket::Call* call,
230                            cricket::Session* session,
231                            const cricket::MediaStreams& added,
232                            const cricket::MediaStreams& removed);
233  void OnSpeakerChanged(cricket::Call* call,
234                        cricket::Session* session,
235                        const cricket::StreamParams& speaker_stream);
236  void OnRoomLookupResponse(buzz::MucRoomLookupTask* task,
237                            const buzz::MucRoomInfo& room_info);
238  void OnRoomLookupError(buzz::IqTask* task,
239                         const buzz::XmlElement* stanza);
240  void OnRoomConfigResult(buzz::MucRoomConfigTask* task);
241  void OnRoomConfigError(buzz::IqTask* task,
242                         const buzz::XmlElement* stanza);
243  void OnDataReceived(cricket::Call*,
244                      const cricket::ReceiveDataParams& params,
245                      const rtc::Buffer& payload);
246  buzz::Jid GenerateRandomMucJid();
247
248  // Depending on |enable|, render (or don't) all the streams in |session|.
249  void RenderAllStreams(cricket::Call* call,
250                        cricket::Session* session,
251                        bool enable);
252
253  // Depending on |enable|, render (or don't) the streams in |video_streams|.
254  void RenderStreams(cricket::Call* call,
255                     cricket::Session* session,
256                     const std::vector<cricket::StreamParams>& video_streams,
257                     bool enable);
258
259  // Depending on |enable|, render (or don't) the supplied |stream|.
260  void RenderStream(cricket::Call* call,
261                    cricket::Session* session,
262                    const cricket::StreamParams& stream,
263                    bool enable);
264  void AddStaticRenderedView(
265      cricket::Session* session,
266      uint32 ssrc, int width, int height, int framerate,
267      int x_offset, int y_offset);
268  bool RemoveStaticRenderedView(uint32 ssrc);
269  void RemoveCallsStaticRenderedViews(cricket::Call* call);
270  void SendViewRequest(cricket::Call* call, cricket::Session* session);
271  bool SelectFirstDesktopScreencastId(cricket::ScreencastId* screencastid);
272
273  static const std::string strerror(buzz::XmppEngine::Error err);
274
275  void PrintRoster();
276  bool FindJid(const std::string& name,
277               buzz::Jid* found_jid,
278               cricket::CallOptions* options);
279  bool PlaceCall(const std::string& name, cricket::CallOptions options);
280  bool InitiateAdditionalSession(const std::string& name,
281                                 cricket::CallOptions options);
282  void TerminateAndRemoveSession(cricket::Call* call, const std::string& id);
283  void PrintCalls();
284  void SwitchToCall(uint32 call_id);
285  void Accept(const cricket::CallOptions& options);
286  void Reject();
287  void Quit();
288
289  void GetDevices();
290  void PrintDevices(const std::vector<std::string>& names);
291
292  void SetVolume(const std::string& level);
293
294  cricket::Session* GetFirstSession() { return sessions_[call_->id()][0]; }
295  void AddSession(cricket::Session* session) {
296    sessions_[call_->id()].push_back(session);
297  }
298
299  void PrintStats() const;
300  void SetupAcceptedCall();
301
302  typedef std::map<std::string, RosterItem> RosterMap;
303
304  Console *console_;
305  buzz::XmppClient* xmpp_client_;
306  rtc::Thread* worker_thread_;
307  rtc::NetworkManager* network_manager_;
308  cricket::PortAllocator* port_allocator_;
309  cricket::SessionManager* session_manager_;
310  cricket::SessionManagerTask* session_manager_task_;
311  cricket::MediaEngineInterface* media_engine_;
312  cricket::DataEngineInterface* data_engine_;
313  cricket::MediaSessionClient* media_client_;
314  MucMap mucs_;
315
316  cricket::Call* call_;
317  typedef std::map<uint32, std::vector<cricket::Session *> > SessionMap;
318  SessionMap sessions_;
319
320  buzz::HangoutPubSubClient* hangout_pubsub_client_;
321  bool incoming_call_;
322  bool auto_accept_;
323  std::string pmuc_domain_;
324  bool render_;
325  cricket::DataChannelType data_channel_type_;
326  bool multisession_enabled_;
327  cricket::VideoRenderer* local_renderer_;
328  StaticRenderedViews static_rendered_views_;
329  uint32 static_views_accumulated_count_;
330  uint32 screencast_ssrc_;
331
332  buzz::PresenceStatus my_status_;
333  buzz::PresencePushTask* presence_push_;
334  buzz::PresenceOutTask* presence_out_;
335  buzz::MucInviteRecvTask* muc_invite_recv_;
336  buzz::MucInviteSendTask* muc_invite_send_;
337  buzz::FriendInviteSendTask* friend_invite_send_;
338  RosterMap* roster_;
339  uint32 portallocator_flags_;
340
341  bool allow_local_ips_;
342  cricket::SignalingProtocol signaling_protocol_;
343  cricket::TransportProtocol transport_protocol_;
344  cricket::SecurePolicy sdes_policy_;
345  cricket::SecurePolicy dtls_policy_;
346  rtc::scoped_ptr<rtc::SSLIdentity> ssl_identity_;
347  std::string last_sent_to_;
348
349  bool show_roster_messages_;
350};
351
352#endif  // TALK_EXAMPLES_CALL_CALLCLIENT_H_
353