1/*
2 * libjingle
3 * Copyright 2012, 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// This file contains structures used for retrieving statistics from an ongoing
29// libjingle session.
30
31#ifndef TALK_APP_WEBRTC_STATSTYPES_H_
32#define TALK_APP_WEBRTC_STATSTYPES_H_
33
34#include <set>
35#include <string>
36#include <vector>
37
38#include "webrtc/base/basictypes.h"
39#include "webrtc/base/common.h"
40#include "webrtc/base/stringencode.h"
41
42namespace webrtc {
43
44// TODO(tommi): Move all the implementation that's in this file and
45// statscollector.cc related to these types, into a new, statstypes.cc file.
46
47class StatsReport {
48 public:
49  // TODO(tommi): Remove this ctor.
50  StatsReport() : timestamp(0) {}
51
52  // TODO(tommi): Make protected and disallow copy completely once not needed.
53  StatsReport(const StatsReport& src)
54    : id(src.id),
55      type(src.type),
56      timestamp(src.timestamp),
57      values(src.values) {}
58
59  // TODO(tommi): Make this copy constructor protected.
60  StatsReport& operator=(const StatsReport& src) {
61    ASSERT(id == src.id);
62    type = src.type;
63    timestamp = src.timestamp;
64    values = src.values;
65    return *this;
66  }
67
68  // Constructor is protected to force use of StatsSet.
69  // TODO(tommi): Make this ctor protected.
70  explicit StatsReport(const std::string& id) : id(id), timestamp(0) {}
71
72  // Operators provided for STL container/algorithm support.
73  bool operator<(const StatsReport& other) const { return id < other.id; }
74  bool operator==(const StatsReport& other) const { return id == other.id; }
75  // Special support for being able to use std::find on a container
76  // without requiring a new StatsReport instance.
77  bool operator==(const std::string& other_id) const { return id == other_id; }
78
79  // TODO(tommi): Change this to be an enum type that holds all the
80  // kStatsValueName constants.
81  typedef const char* StatsValueName;
82
83  // The unique identifier for this object.
84  // This is used as a key for this report in ordered containers,
85  // so it must never be changed.
86  // TODO(tommi): Make this member variable const.
87  std::string id;  // See below for contents.
88  std::string type;  // See below for contents.
89
90  struct Value {
91    Value() : name(NULL) {}
92    // The copy ctor can't be declared as explicit due to problems with STL.
93    Value(const Value& other) : name(other.name), value(other.value) {}
94    explicit Value(StatsValueName name) : name(name) {}
95    Value(StatsValueName name, const std::string& value)
96        : name(name), value(value) {
97    }
98
99    // TODO(tommi): Remove this operator once we don't need it.
100    // The operator is provided for compatibility with STL containers.
101    // The public |name| member variable is otherwise meant to be read-only.
102    Value& operator=(const Value& other) {
103      const_cast<StatsValueName&>(name) = other.name;
104      value = other.value;
105      return *this;
106    }
107
108    // TODO(tommi): Change implementation to do a simple enum value-to-static-
109    // string conversion when client code has been updated to use this method
110    // instead of the |name| member variable.
111    const char* display_name() const { return name; }
112
113    const StatsValueName name;
114
115    std::string value;
116  };
117
118  void AddValue(StatsValueName name, const std::string& value);
119  void AddValue(StatsValueName name, int64 value);
120  template <typename T>
121  void AddValue(StatsValueName name, const std::vector<T>& value);
122  void AddBoolean(StatsValueName name, bool value);
123
124  void ReplaceValue(StatsValueName name, const std::string& value);
125
126  double timestamp;  // Time since 1970-01-01T00:00:00Z in milliseconds.
127  typedef std::vector<Value> Values;
128  Values values;
129
130  // TODO(tommi): These should all be enum values.
131
132  // StatsReport types.
133  // A StatsReport of |type| = "googSession" contains overall information
134  // about the thing libjingle calls a session (which may contain one
135  // or more RTP sessions.
136  static const char kStatsReportTypeSession[];
137
138  // A StatsReport of |type| = "googTransport" contains information
139  // about a libjingle "transport".
140  static const char kStatsReportTypeTransport[];
141
142  // A StatsReport of |type| = "googComponent" contains information
143  // about a libjingle "channel" (typically, RTP or RTCP for a transport).
144  // This is intended to be the same thing as an ICE "Component".
145  static const char kStatsReportTypeComponent[];
146
147  // A StatsReport of |type| = "googCandidatePair" contains information
148  // about a libjingle "connection" - a single source/destination port pair.
149  // This is intended to be the same thing as an ICE "candidate pair".
150  static const char kStatsReportTypeCandidatePair[];
151
152  // StatsReport of |type| = "VideoBWE" is statistics for video Bandwidth
153  // Estimation, which is global per-session.  The |id| field is "bweforvideo"
154  // (will probably change in the future).
155  static const char kStatsReportTypeBwe[];
156
157  // StatsReport of |type| = "ssrc" is statistics for a specific rtp stream.
158  // The |id| field is the SSRC in decimal form of the rtp stream.
159  static const char kStatsReportTypeSsrc[];
160
161  // StatsReport of |type| = "remoteSsrc" is statistics for a specific
162  // rtp stream, generated by the remote end of the connection.
163  static const char kStatsReportTypeRemoteSsrc[];
164
165  // StatsReport of |type| = "googTrack" is statistics for a specific media
166  // track. The |id| field is the track id.
167  static const char kStatsReportTypeTrack[];
168
169  // StatsReport of |type| = "iceCandidate" is statistics on a specific
170  // ICE Candidate. It links to its transport.
171  static const char kStatsReportTypeIceCandidate[];
172
173  // The id of StatsReport of type VideoBWE.
174  static const char kStatsReportVideoBweId[];
175
176  // A StatsReport of |type| = "googCertificate" contains an SSL certificate
177  // transmitted by one of the endpoints of this connection.  The |id| is
178  // controlled by the fingerprint, and is used to identify the certificate in
179  // the Channel stats (as "googLocalCertificateId" or
180  // "googRemoteCertificateId") and in any child certificates (as
181  // "googIssuerId").
182  static const char kStatsReportTypeCertificate[];
183
184  // StatsValue names
185  static const char kStatsValueNameAudioOutputLevel[];
186  static const char kStatsValueNameAudioInputLevel[];
187  static const char kStatsValueNameBytesSent[];
188  static const char kStatsValueNamePacketsSent[];
189  static const char kStatsValueNameBytesReceived[];
190  static const char kStatsValueNamePacketsReceived[];
191  static const char kStatsValueNamePacketsLost[];
192  static const char kStatsValueNameTransportId[];
193  static const char kStatsValueNameLocalAddress[];
194  static const char kStatsValueNameRemoteAddress[];
195  static const char kStatsValueNameWritable[];
196  static const char kStatsValueNameReadable[];
197  static const char kStatsValueNameActiveConnection[];
198
199
200  // Internal StatsValue names
201  static const char kStatsValueNameAvgEncodeMs[];
202  static const char kStatsValueNameEncodeRelStdDev[];
203  static const char kStatsValueNameEncodeUsagePercent[];
204  static const char kStatsValueNameCaptureJitterMs[];
205  static const char kStatsValueNameCaptureQueueDelayMsPerS[];
206  static const char kStatsValueNameCodecName[];
207  static const char kStatsValueNameBandwidthLimitedResolution[];
208  static const char kStatsValueNameCpuLimitedResolution[];
209  static const char kStatsValueNameViewLimitedResolution[];
210  static const char kStatsValueNameAdaptationChanges[];
211  static const char kStatsValueNameEchoCancellationQualityMin[];
212  static const char kStatsValueNameEchoDelayMedian[];
213  static const char kStatsValueNameEchoDelayStdDev[];
214  static const char kStatsValueNameEchoReturnLoss[];
215  static const char kStatsValueNameEchoReturnLossEnhancement[];
216  static const char kStatsValueNameExpandRate[];
217  static const char kStatsValueNameFirsReceived[];
218  static const char kStatsValueNameFirsSent[];
219  static const char kStatsValueNameFrameHeightInput[];
220  static const char kStatsValueNameFrameHeightReceived[];
221  static const char kStatsValueNameFrameHeightSent[];
222  static const char kStatsValueNameFrameRateReceived[];
223  static const char kStatsValueNameFrameRateDecoded[];
224  static const char kStatsValueNameFrameRateOutput[];
225  static const char kStatsValueNameDecodeMs[];
226  static const char kStatsValueNameMaxDecodeMs[];
227  static const char kStatsValueNameCurrentDelayMs[];
228  static const char kStatsValueNameTargetDelayMs[];
229  static const char kStatsValueNameJitterBufferMs[];
230  static const char kStatsValueNameMinPlayoutDelayMs[];
231  static const char kStatsValueNameRenderDelayMs[];
232  static const char kStatsValueNameCaptureStartNtpTimeMs[];
233  static const char kStatsValueNameFrameRateInput[];
234  static const char kStatsValueNameFrameRateSent[];
235  static const char kStatsValueNameFrameWidthInput[];
236  static const char kStatsValueNameFrameWidthReceived[];
237  static const char kStatsValueNameFrameWidthSent[];
238  static const char kStatsValueNameJitterReceived[];
239  static const char kStatsValueNameNacksReceived[];
240  static const char kStatsValueNameNacksSent[];
241  static const char kStatsValueNamePlisReceived[];
242  static const char kStatsValueNamePlisSent[];
243  static const char kStatsValueNamePreferredJitterBufferMs[];
244  static const char kStatsValueNameRtt[];
245  static const char kStatsValueNameAvailableSendBandwidth[];
246  static const char kStatsValueNameAvailableReceiveBandwidth[];
247  static const char kStatsValueNameTargetEncBitrate[];
248  static const char kStatsValueNameActualEncBitrate[];
249  static const char kStatsValueNameRetransmitBitrate[];
250  static const char kStatsValueNameTransmitBitrate[];
251  static const char kStatsValueNameBucketDelay[];
252  static const char kStatsValueNameInitiator[];
253  static const char kStatsValueNameTransportType[];
254  static const char kStatsValueNameContentName[];
255  static const char kStatsValueNameComponent[];
256  static const char kStatsValueNameChannelId[];
257  static const char kStatsValueNameTrackId[];
258  static const char kStatsValueNameSsrc[];
259  static const char kStatsValueNameTypingNoiseState[];
260  static const char kStatsValueNameDer[];
261  static const char kStatsValueNameFingerprint[];
262  static const char kStatsValueNameFingerprintAlgorithm[];
263  static const char kStatsValueNameIssuerId[];
264  static const char kStatsValueNameLocalCertificateId[];
265  static const char kStatsValueNameRemoteCertificateId[];
266  static const char kStatsValueNameLocalCandidateType[];
267  static const char kStatsValueNameRemoteCandidateType[];
268  static const char kStatsValueNameRecvPacketGroupArrivalTimeDebug[];
269  static const char kStatsValueNameRecvPacketGroupPropagationDeltaDebug[];
270  static const char kStatsValueNameRecvPacketGroupPropagationDeltaSumDebug[];
271  static const char kStatsValueNameDecodingCTSG[];
272  static const char kStatsValueNameDecodingCTN[];
273  static const char kStatsValueNameDecodingNormal[];
274  static const char kStatsValueNameDecodingPLC[];
275  static const char kStatsValueNameDecodingCNG[];
276  static const char kStatsValueNameDecodingPLCCNG[];
277};
278
279// This class is provided for the cases where we need to keep
280// snapshots of reports around.  This is an edge case.
281// TODO(tommi): Move into the private section of StatsSet.
282class StatsReportCopyable : public StatsReport {
283 public:
284  StatsReportCopyable(const std::string& id) : StatsReport(id) {}
285  explicit StatsReportCopyable(const StatsReport& src)
286      : StatsReport(src) {}
287
288  using StatsReport::operator=;
289};
290
291// Typedef for an array of const StatsReport pointers.
292// Ownership of the pointers held by this implementation is assumed to lie
293// elsewhere and lifetime guarantees are made by the implementation that uses
294// this type.  In the StatsCollector, object ownership lies with the StatsSet
295// class.
296typedef std::vector<const StatsReport*> StatsReports;
297
298// A map from the report id to the report.
299// This class wraps an STL container and provides a limited set of
300// functionality in order to keep things simple.
301// TODO(tommi): Use a thread checker here (currently not in libjingle).
302class StatsSet {
303 public:
304  StatsSet() {}
305  ~StatsSet() {}
306
307  typedef std::set<StatsReportCopyable> Container;
308  typedef Container::iterator iterator;
309  typedef Container::const_iterator const_iterator;
310
311  const_iterator begin() const { return list_.begin(); }
312  const_iterator end() const { return list_.end(); }
313
314  // Creates a new report object with |id| that does not already
315  // exist in the list of reports.
316  StatsReport* InsertNew(const std::string& id) {
317    ASSERT(Find(id) == NULL);
318    const StatsReport* ret = &(*list_.insert(StatsReportCopyable(id)).first);
319    return const_cast<StatsReport*>(ret);
320  }
321
322  StatsReport* FindOrAddNew(const std::string& id) {
323    StatsReport* ret = Find(id);
324    return ret ? ret : InsertNew(id);
325  }
326
327  StatsReport* ReplaceOrAddNew(const std::string& id) {
328    list_.erase(id);
329    return InsertNew(id);
330  }
331
332  // Looks for a report with the given |id|.  If one is not found, NULL
333  // will be returned.
334  StatsReport* Find(const std::string& id) {
335    const_iterator it = std::find(begin(), end(), id);
336    return it == end() ? NULL :
337        const_cast<StatsReport*>(static_cast<const StatsReport*>(&(*it)));
338  }
339
340 private:
341  Container list_;
342};
343
344}  // namespace webrtc
345
346#endif  // TALK_APP_WEBRTC_STATSTYPES_H_
347