1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef REMOTING_PROTOCOL_SESSION_CONFIG_H_
6#define REMOTING_PROTOCOL_SESSION_CONFIG_H_
7
8#include <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/memory/scoped_ptr.h"
13
14namespace remoting {
15namespace protocol {
16
17extern const int kDefaultStreamVersion;
18
19// Struct for configuration parameters of a single channel.
20// Some channels (like video) may have multiple underlying sockets that need
21// to be configured simultaneously.
22struct ChannelConfig {
23  enum TransportType {
24    TRANSPORT_STREAM,
25    TRANSPORT_MUX_STREAM,
26    TRANSPORT_DATAGRAM,
27    TRANSPORT_NONE,
28  };
29
30  enum Codec {
31    CODEC_UNDEFINED,  // Used for event and control channels.
32    CODEC_VERBATIM,
33    CODEC_ZIP,
34    CODEC_VP8,
35    CODEC_VP9,
36    CODEC_OPUS,
37    CODEC_SPEEX,
38  };
39
40  // Creates a config with transport field set to TRANSPORT_NONE which indicates
41  // that corresponding channel is disabled.
42  static ChannelConfig None();
43
44  // Default constructor. Equivalent to None().
45  ChannelConfig();
46
47  // Creates a channel config with the specified parameters.
48  ChannelConfig(TransportType transport, int version, Codec codec);
49
50  // operator== is overloaded so that std::find() works with
51  // std::vector<ChannelConfig>.
52  bool operator==(const ChannelConfig& b) const;
53
54  TransportType transport;
55  int version;
56  Codec codec;
57};
58
59// SessionConfig is used by the chromoting Session to store negotiated
60// chromotocol configuration.
61class SessionConfig {
62 public:
63  SessionConfig();
64
65  void set_control_config(const ChannelConfig& control_config) {
66    control_config_ = control_config;
67  }
68  const ChannelConfig& control_config() const { return control_config_; }
69  void set_event_config(const ChannelConfig& event_config) {
70    event_config_ = event_config;
71  }
72  const ChannelConfig& event_config() const { return event_config_; }
73  void set_video_config(const ChannelConfig& video_config) {
74    video_config_ = video_config;
75  }
76  const ChannelConfig& video_config() const { return video_config_; }
77  void set_audio_config(const ChannelConfig& audio_config) {
78    audio_config_ = audio_config;
79  }
80  const ChannelConfig& audio_config() const { return audio_config_; }
81
82  bool is_audio_enabled() const {
83    return audio_config_.transport != ChannelConfig::TRANSPORT_NONE;
84  }
85
86  // Returns true if the control channel supports capabilities.
87  bool SupportsCapabilities() const;
88
89  // Returns a suitable session configuration for use in tests.
90  static SessionConfig ForTest();
91
92 private:
93  ChannelConfig control_config_;
94  ChannelConfig event_config_;
95  ChannelConfig video_config_;
96  ChannelConfig audio_config_;
97};
98
99// Defines session description that is sent from client to the host in the
100// session-initiate message. It is different from the regular Config
101// because it allows one to specify multiple configurations for each channel.
102class CandidateSessionConfig {
103 public:
104  ~CandidateSessionConfig();
105
106  const std::vector<ChannelConfig>& control_configs() const {
107    return control_configs_;
108  }
109
110  std::vector<ChannelConfig>* mutable_control_configs() {
111    return &control_configs_;
112  }
113
114  const std::vector<ChannelConfig>& event_configs() const {
115    return event_configs_;
116  }
117
118  std::vector<ChannelConfig>* mutable_event_configs() {
119    return &event_configs_;
120  }
121
122  const std::vector<ChannelConfig>& video_configs() const {
123    return video_configs_;
124  }
125
126  std::vector<ChannelConfig>* mutable_video_configs() {
127    return &video_configs_;
128  }
129
130  const std::vector<ChannelConfig>& audio_configs() const {
131    return audio_configs_;
132  }
133
134  std::vector<ChannelConfig>* mutable_audio_configs() {
135    return &audio_configs_;
136  }
137
138  // Selects session configuration that is supported by both participants.
139  // NULL is returned if such configuration doesn't exist. When selecting
140  // channel configuration priority is given to the configs listed first
141  // in |client_config|.
142  bool Select(const CandidateSessionConfig* client_config,
143              SessionConfig* result);
144
145  // Returns true if |config| is supported.
146  bool IsSupported(const SessionConfig& config) const;
147
148  // Extracts final protocol configuration. Must be used for the description
149  // received in the session-accept stanza. If the selection is ambiguous
150  // (e.g. there is more than one configuration for one of the channel)
151  // or undefined (e.g. no configurations for a channel) then NULL is returned.
152  bool GetFinalConfig(SessionConfig* result) const;
153
154  scoped_ptr<CandidateSessionConfig> Clone() const;
155
156  static scoped_ptr<CandidateSessionConfig> CreateEmpty();
157  static scoped_ptr<CandidateSessionConfig> CreateFrom(
158      const SessionConfig& config);
159  static scoped_ptr<CandidateSessionConfig> CreateDefault();
160
161  // Modifies |config| to disable specific features.
162  static void DisableAudioChannel(CandidateSessionConfig* config);
163  static void DisableVideoCodec(CandidateSessionConfig* config,
164                                ChannelConfig::Codec codec);
165
166 private:
167  CandidateSessionConfig();
168  explicit CandidateSessionConfig(const CandidateSessionConfig& config);
169  CandidateSessionConfig& operator=(const CandidateSessionConfig& b);
170
171  static bool SelectCommonChannelConfig(
172      const std::vector<ChannelConfig>& host_configs_,
173      const std::vector<ChannelConfig>& client_configs_,
174      ChannelConfig* config);
175  static bool IsChannelConfigSupported(const std::vector<ChannelConfig>& vector,
176                                       const ChannelConfig& value);
177
178  std::vector<ChannelConfig> control_configs_;
179  std::vector<ChannelConfig> event_configs_;
180  std::vector<ChannelConfig> video_configs_;
181  std::vector<ChannelConfig> audio_configs_;
182};
183
184}  // namespace protocol
185}  // namespace remoting
186
187#endif  // REMOTING_PROTOCOL_SESSION_CONFIG_H_
188