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_OPUS,
36    CODEC_SPEEX,
37  };
38
39  // Creates a config with transport field set to TRANSPORT_NONE which indicates
40  // that corresponding channel is disabled.
41  static ChannelConfig None();
42
43  // Default constructor. Equivalent to None().
44  ChannelConfig();
45
46  // Creates a channel config with the specified parameters.
47  ChannelConfig(TransportType transport, int version, Codec codec);
48
49  // operator== is overloaded so that std::find() works with
50  // std::vector<ChannelConfig>.
51  bool operator==(const ChannelConfig& b) const;
52
53  TransportType transport;
54  int version;
55  Codec codec;
56};
57
58// SessionConfig is used by the chromoting Session to store negotiated
59// chromotocol configuration.
60class SessionConfig {
61 public:
62  SessionConfig();
63
64  void set_control_config(const ChannelConfig& control_config) {
65    control_config_ = control_config;
66  }
67  const ChannelConfig& control_config() const { return control_config_; }
68  void set_event_config(const ChannelConfig& event_config) {
69    event_config_ = event_config;
70  }
71  const ChannelConfig& event_config() const { return event_config_; }
72  void set_video_config(const ChannelConfig& video_config) {
73    video_config_ = video_config;
74  }
75  const ChannelConfig& video_config() const { return video_config_; }
76  void set_audio_config(const ChannelConfig& audio_config) {
77    audio_config_ = audio_config;
78  }
79  const ChannelConfig& audio_config() const { return audio_config_; }
80
81  bool is_audio_enabled() const {
82    return audio_config_.transport != ChannelConfig::TRANSPORT_NONE;
83  }
84
85  // Returns true if the control channel supports capabilities.
86  bool SupportsCapabilities() const;
87
88  // Returns a suitable session configuration for use in tests.
89  static SessionConfig ForTest();
90
91 private:
92  ChannelConfig control_config_;
93  ChannelConfig event_config_;
94  ChannelConfig video_config_;
95  ChannelConfig audio_config_;
96};
97
98// Defines session description that is sent from client to the host in the
99// session-initiate message. It is different from the regular Config
100// because it allows one to specify multiple configurations for each channel.
101class CandidateSessionConfig {
102 public:
103  ~CandidateSessionConfig();
104
105  const std::vector<ChannelConfig>& control_configs() const {
106    return control_configs_;
107  }
108
109  std::vector<ChannelConfig>* mutable_control_configs() {
110    return &control_configs_;
111  }
112
113  const std::vector<ChannelConfig>& event_configs() const {
114    return event_configs_;
115  }
116
117  std::vector<ChannelConfig>* mutable_event_configs() {
118    return &event_configs_;
119  }
120
121  const std::vector<ChannelConfig>& video_configs() const {
122    return video_configs_;
123  }
124
125  std::vector<ChannelConfig>* mutable_video_configs() {
126    return &video_configs_;
127  }
128
129  const std::vector<ChannelConfig>& audio_configs() const {
130    return audio_configs_;
131  }
132
133  std::vector<ChannelConfig>* mutable_audio_configs() {
134    return &audio_configs_;
135  }
136
137  // Selects session configuration that is supported by both participants.
138  // NULL is returned if such configuration doesn't exist. When selecting
139  // channel configuration priority is given to the configs listed first
140  // in |client_config|.
141  bool Select(const CandidateSessionConfig* client_config,
142              SessionConfig* result);
143
144  // Returns true if |config| is supported.
145  bool IsSupported(const SessionConfig& config) const;
146
147  // Extracts final protocol configuration. Must be used for the description
148  // received in the session-accept stanza. If the selection is ambiguous
149  // (e.g. there is more than one configuration for one of the channel)
150  // or undefined (e.g. no configurations for a channel) then NULL is returned.
151  bool GetFinalConfig(SessionConfig* result) const;
152
153  scoped_ptr<CandidateSessionConfig> Clone() const;
154
155  static scoped_ptr<CandidateSessionConfig> CreateEmpty();
156  static scoped_ptr<CandidateSessionConfig> CreateFrom(
157      const SessionConfig& config);
158  static scoped_ptr<CandidateSessionConfig> CreateDefault();
159
160  // Helper method that modifies |config| to disable audio support.
161  static void DisableAudioChannel(CandidateSessionConfig* config);
162
163 private:
164  CandidateSessionConfig();
165  explicit CandidateSessionConfig(const CandidateSessionConfig& config);
166  CandidateSessionConfig& operator=(const CandidateSessionConfig& b);
167
168  static bool SelectCommonChannelConfig(
169      const std::vector<ChannelConfig>& host_configs_,
170      const std::vector<ChannelConfig>& client_configs_,
171      ChannelConfig* config);
172  static bool IsChannelConfigSupported(const std::vector<ChannelConfig>& vector,
173                                       const ChannelConfig& value);
174
175  std::vector<ChannelConfig> control_configs_;
176  std::vector<ChannelConfig> event_configs_;
177  std::vector<ChannelConfig> video_configs_;
178  std::vector<ChannelConfig> audio_configs_;
179};
180
181}  // namespace protocol
182}  // namespace remoting
183
184#endif  // REMOTING_PROTOCOL_SESSION_CONFIG_H_
185