1/*
2 * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef OHOS_SHARING_RTCP_H
17#define OHOS_SHARING_RTCP_H
18
19#include <memory>
20#include <cstdint>
21#include <string>
22#include <sys/time.h>
23#include <vector>
24#include "rtcp_def.h"
25
26namespace OHOS {
27namespace Sharing {
28/*
29    RTCP Header
30
31     0                   1                   2                   3
32     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
33    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
34    |V=2|P|    RC   |       PT      |             length            |
35    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
36*/
37
38struct RtcpHeader {
39public:
40    void SetSize(int32_t size);
41
42    int32_t GetSize() const;
43    int32_t GetPaddingSize() const;
44
45public:
46    uint8_t pt_;
47    uint8_t padding_ : 1;
48    uint8_t version_ : 2;
49    uint8_t reportCount_ : 5;
50
51private:
52    uint16_t length_;
53};
54
55// ReportBlock
56struct ReportItem {
57public:
58    // Highest sequence number received
59    uint16_t seqMax_;
60    // Sequence number cycles count
61    uint16_t seqCycles_;
62
63    uint32_t ssrc_;
64    // Interarrival jitter
65    uint32_t jitter_;
66    // Last SR timestamp, NTP timestamp,(ntpmsw & 0xFFFF) << 16  | (ntplsw >> 16) & 0xFFFF)
67    uint32_t lastSrStamp_;
68    // Cumulative number of packets lost
69    uint32_t cumulative_ : 24;
70    // Packet loss rate (percentage) * 256
71    uint32_t fractionLost_ : 8;
72    // Delay since last SR timestamp,expressed in units of 1/65536 seconds
73    uint32_t delaySinceLastSr_;
74};
75
76//------------------------------ RtcpSR ------------------------------//
77
78/*
79    SR: Sender Report RTCP Packet
80
81        0                   1                   2                   3
82        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
83       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84header |V=2|P|    RC   |   PT=SR=200   |             length            |
85       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86       |                         SSRC of sender                        |
87       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
88sender |              NTP timestamp, most significant word             |
89info   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90       |             NTP timestamp, least significant word             |
91       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
92       |                         RTP timestamp                         |
93       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
94       |                     sender's packet count                     |
95       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96       |                      sender's octet count                     |
97       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
98report |                 SSRC_1 (SSRC of first source)                 |
99block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
100  1    | fraction lost |       cumulative number of packets lost       |
101       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
102       |           extended highest sequence number received           |
103       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104       |                      interarrival jitter                      |
105       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106       |                         last SR (LSR)                         |
107       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
108       |                   delay since last SR (DLSR)                  |
109       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
110report |                 SSRC_2 (SSRC of second source)                |
111block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
112  2    :                               ...                             :
113       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
114       |                  profile-specific extensions                  |
115       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
116*/
117
118// sender report
119struct RtcpSR : public RtcpHeader {
120public:
121    static std::shared_ptr<RtcpSR> Create(int32_t itemCount);
122
123    RtcpSR &SetSsrc(uint32_t ssrc);
124    RtcpSR &SetNtpStamp(timeval tv);
125    RtcpSR &SetPacketCount(uint32_t);
126    RtcpSR &SetNtpStamp(uint64_t unixStampMs);
127
128    uint32_t GetSsrc() const;
129    uint32_t GetPacketCount() const;
130    uint64_t GetNtpUnixStampMS() const;
131
132    std::string GetNtpStamp() const;
133    std::vector<ReportItem *> GetItemList();
134
135public:
136    uint32_t ssrc_;
137    // rtp timestamp
138    uint32_t rtpts_;
139    // ntp timestamp MSW(in second)
140    uint32_t ntpmsw_;
141    // ntp timestamp LSW(in picosecond)
142    uint32_t ntplsw_;
143    // sender octet count
144    uint32_t octetCount_;
145    // sender packet count
146    uint32_t packetCount_;
147
148    ReportItem items_;
149};
150
151//------------------------------ RtcpRR ------------------------------//
152
153/*
154    RR: Receiver Report RTCP Packet
155
156        0                   1                   2                   3
157        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
158       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159header |V=2|P|    RC   |   PT=RR=201   |             length            |
160       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161       |                     SSRC of packet sender                     |
162       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
163report |                 SSRC_1 (SSRC of first source)                 |
164block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
165  1    | fraction lost |       cumulative number of packets lost       |
166       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
167       |           extended highest sequence number received           |
168       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
169       |                      interarrival jitter                      |
170       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
171       |                         last SR (LSR)                         |
172       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
173       |                   delay since last SR (DLSR)                  |
174       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
175report |                 SSRC_2 (SSRC of second source)                |
176block  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
177  2    :                               ...                             :
178       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
179       |                  profile-specific extensions                  |
180       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
181*/
182
183// Receiver Report
184struct RtcpRR : public RtcpHeader {
185public:
186    std::vector<ReportItem *> GetItemList();
187    static std::shared_ptr<RtcpRR> Create(size_t itemCount);
188
189public:
190    uint32_t ssrc_;
191    ReportItem items_;
192};
193
194//------------------------------ RtcpSdes ------------------------------//
195
196/*
197    SDES: Source Description RTCP Packet
198        0                   1                   2                   3
199        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
200       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
201header |V=2|P|    SC   |  PT=SDES=202  |             length            |
202       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
203chunk  |                          SSRC/CSRC_1                          |
204  1    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
205       |                           SDES items                          |
206       |                              ...                              |
207       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
208chunk  |                          SSRC/CSRC_2                          |
209  2    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
210       |                           SDES items                          |
211       |                              ...                              |
212       +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
213*/
214
215/*
216    SDES items
217    0                   1                   2                   3
218    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
219    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
220    |   SdesType  |     length    | user and domain name        ...
221    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
222*/
223
224// Source description Chunk
225struct SdesChunk {
226public:
227    static size_t MinSize();
228    size_t TotalBytes() const;
229
230public:
231    char text_[1]; // variable length field
232
233    uint8_t end_; // placeholder
234    uint8_t txtLen_;
235
236    uint32_t ssrc_;
237
238    SdesType type_; // uint8_t
239};
240
241// Source description
242struct RtcpSdes : public RtcpHeader {
243public:
244    std::vector<SdesChunk *> GetChunkList();
245    static std::shared_ptr<RtcpSdes> Create(const std::vector<std::string> &itemText);
246
247public:
248    SdesChunk chunks_;
249};
250
251//------------------------------ RtcpFB ------------------------------//
252
253/*     Common Packet Format for Feedback Messages
254
255       All FB messages MUST use a common packet format that is depicted in
256       Figure 3:
257
258        0                   1                   2                   3
259        0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
260       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
261       |V=2|P|   FMT   |       PT      |          length               |
262       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
263       |                  SSRC of packet sender                        |
264       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
265       |                  SSRC of media source                         |
266       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
267       :            Feedback Control Information (FCI)                 :
268       :                                                               :
269*/
270
271// RtcpFB: Rtpfb or Psfb
272struct RtcpFB : public RtcpHeader {
273public:
274    int32_t GetFciSize() const;
275    const uint8_t *GetFciPtr() const;
276    // for psfb fb
277    static std::shared_ptr<RtcpFB> Create(PsfbType fmt, const void *fci = nullptr, size_t fci_len = 0);
278    // for rtpfb fb
279    static std::shared_ptr<RtcpFB> Create(RtpfbType fmt, const void *fci = nullptr, size_t fci_len = 0);
280
281private:
282    static std::shared_ptr<RtcpFB> CreateInner(RtcpType type, int32_t fmt, const void *fci, size_t fci_len);
283
284public:
285    uint32_t ssrc_;
286    uint32_t ssrcMedia_;
287};
288
289//------------------------------ RtcpBye ------------------------------//
290
291/*
292    BYE
293
294       0                   1                   2                   3
295       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
296      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
297      |V=2|P|    SC   |   PT=BYE=203  |             length            |
298      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
299      |                           SSRC/CSRC                           |
300      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
301      :                              ...                              :
302      +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
303(opt) |     length    |               reason for leaving            ...
304      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
305*/
306
307struct RtcpBye : public RtcpHeader {
308public:
309    std::string GetReason() const;
310    std::vector<uint32_t> GetSSRC() const;
311    static std::shared_ptr<RtcpBye> Create(const std::vector<uint32_t> &ssrc, const std::string &reason);
312
313public:
314    char reason_[1];
315    // optional
316    uint8_t reasonLen_;
317    // variable length for multiple ssrc
318    uint32_t ssrc_[1];
319};
320
321//------------------------------ XR - RtcpXRRRTR ------------------------------//
322
323/*
324    RTCP Extended Reports (RTCP XR) Packet Format
325
326    0                   1                   2                   3
327    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
328    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
329    |V=2|P|reserved |   PT=XR=207   |             length            |
330    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
331    |                              SSRC                             |
332    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
333    :                         report blocks                         :
334    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
335
336*/
337/*
338    RTCP XR - Receiver Reference Time Report Block
339
340    0                   1                   2                   3
341    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
342   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
343   |     BT=4      |   reserved    |       block length = 2        |
344   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
345   |              NTP timestamp, most significant word             |
346   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
347   |             NTP timestamp, least significant word             |
348   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
349
350*/
351
352// XR - Receiver Reference Time Report
353struct RtcpXRRRTR : public RtcpHeader {
354public:
355    uint8_t bt_ = 4;
356    uint8_t reserved_;
357    uint16_t blockLength_ = 0x0200; // = htons(2)
358
359    uint32_t ssrc_;
360    // ntp timestamp MSW(in second)
361    uint32_t ntpmsw_;
362    // ntp timestamp LSW(in picosecond)
363    uint32_t ntplsw_;
364};
365
366//------------------------------ XR - RtcpXRDLRR ------------------------------//
367
368/*
369    RTCP XR - Delay since the Last Receiver Report (DLRR)
370
371     0                   1                   2                   3
372     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
373    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
374    |     BT=5      |   reserved    |         block length          |
375    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
376    |                 SSRC_1 (SSRC of first receiver)               | sub-
377    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
378    |                         last RR (LRR)                         |   1
379    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
380    |                   delay since last RR (DLRR)                  |
381    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
382    |                 SSRC_2 (SSRC of second receiver)              | sub-
383    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
384    :                               ...                             :   2
385    +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
386*/
387
388struct RtcpXRDLRRReportItem {
389public:
390    uint32_t lrr_;
391    uint32_t ssrc_;
392    uint32_t dlrr_;
393};
394
395// RTCP XR - Delay since the Last Receiver Report (DLRR)
396struct RtcpXRDLRR : public RtcpHeader {
397public:
398    std::vector<RtcpXRDLRRReportItem *> GetItemList();
399    static std::shared_ptr<RtcpXRDLRR> Create(size_t itemCount);
400
401public:
402    uint8_t bt_;
403    uint8_t reserved_;
404    uint16_t blockLength_;
405    uint32_t ssrc_;
406
407    RtcpXRDLRRReportItem items_;
408};
409} // namespace Sharing
410} // namespace OHOS
411#endif