-
Notifications
You must be signed in to change notification settings - Fork 408
/
RTPEvent.cs
123 lines (107 loc) · 4.38 KB
/
RTPEvent.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//-----------------------------------------------------------------------------
// Filename: RTPEvent.cs
//
// Description: Represents an RTP DTMF event as specified in RFC2833.
//
// Author(s):
// Aaron Clauson (aaron@sipsorcery.com)
//
// History:
// 12 Nov 2019 Aaron Clauson Created, Dublin, Ireland.
//
// License:
// BSD 3-Clause "New" or "Revised" License, see included LICENSE.md file.
//-----------------------------------------------------------------------------
using System;
using SIPSorcery.Sys;
namespace SIPSorcery.Net
{
public class RTPEvent
{
public const int DTMF_PACKET_LENGTH = 4; // The length of an RTP DTMF event packet.
public const ushort DEFAULT_VOLUME = 10;
public const int DUPLICATE_COUNT = 3; // The number of packets to duplicate for the start and end of an event.
/// <summary>
/// The ID for the event. For a DTMF tone this is the digit/letter to represent.
/// </summary>
public byte EventID { get; private set; }
/// <summary>
/// If true the end of event flag will be set.
/// </summary>
public bool EndOfEvent { get; set; }
/// <summary>
/// The volume level to set.
/// </summary>
public ushort Volume { get; private set; }
/// <summary>
/// The duration for the full event.
/// </summary>
public ushort TotalDuration { get; private set; }
/// <summary>
/// The duration of the current event payload. This value is set in the RTP event data payload.
/// </summary>
public ushort Duration { get; set; }
/// <summary>
/// The ID of the event payload type. This gets set in the RTP header.
/// </summary>
public int PayloadTypeID { get; private set; }
/// <summary>
/// Create a new RTP event object.
/// </summary>
/// <param name="eventID">The ID for the event. For a DTMF tone this is the digit/letter to represent.</param>
/// <param name="endOfEvent">If true the end of event flag will be set.</param>
/// <param name="volume">The volume level to set.</param>
/// <param name="totalDuration">The event duration.</param>
/// <param name="payloadTypeID">The ID of the event payload type. This gets set in the RTP header.</param>
public RTPEvent(byte eventID, bool endOfEvent, ushort volume, ushort totalDuration, int payloadTypeID)
{
EventID = eventID;
EndOfEvent = endOfEvent;
Volume = volume;
TotalDuration = totalDuration;
PayloadTypeID = payloadTypeID;
}
/// <summary>
/// Gets the raw buffer for the event.
/// </summary>
/// <returns>A raw byte buffer for the event.</returns>
public byte[] GetEventPayload()
{
byte[] payload = new byte[DTMF_PACKET_LENGTH];
payload[0] = EventID;
payload[1] = (byte)(EndOfEvent ? 0x80 : 0x00);
payload[1] += (byte)(Volume & 0xcf); // The Volume field uses 6 bits.
if (BitConverter.IsLittleEndian)
{
Buffer.BlockCopy(BitConverter.GetBytes(NetConvert.DoReverseEndian(Duration)), 0, payload, 2, 2);
}
else
{
Buffer.BlockCopy(BitConverter.GetBytes(Duration), 0, payload, 2, 2);
}
return payload;
}
/// <summary>
/// Extract and load an RTP Event from a packet buffer.
/// </summary>
/// <param name="packet">The packet buffer containing the RTP Event.</param>
public RTPEvent(byte[] packet)
{
if (packet.Length < DTMF_PACKET_LENGTH)
{
throw new ApplicationException("The packet did not contain the minimum number of bytes for an RTP Event packet.");
}
EventID = packet[0];
EndOfEvent = (packet[1] & 0x80) > 1;
Volume = (ushort)(packet[1] & 0xcf);
if (BitConverter.IsLittleEndian)
{
Duration = NetConvert.DoReverseEndian(BitConverter.ToUInt16(packet, 2));
}
else
{
Duration = BitConverter.ToUInt16(packet, 2);
}
}
}
}