SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
rtpinternalsourcedata.cpp
Go to the documentation of this file.
1 /*
2 
3  This file is a part of JRTPLIB
4  Copyright (c) 1999-2017 Jori Liesenborgs
5 
6  Contact: jori.liesenborgs@gmail.com
7 
8  This library was developed at the Expertise Centre for Digital Media
9  (http://www.edm.uhasselt.be), a research center of the Hasselt University
10  (http://www.uhasselt.be). The library is based upon work done for
11  my thesis at the School for Knowledge Technology (Belgium/The Netherlands).
12 
13  Permission is hereby granted, free of charge, to any person obtaining a
14  copy of this software and associated documentation files (the "Software"),
15  to deal in the Software without restriction, including without limitation
16  the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  and/or sell copies of the Software, and to permit persons to whom the
18  Software is furnished to do so, subject to the following conditions:
19 
20  The above copyright notice and this permission notice shall be included
21  in all copies or substantial portions of the Software.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29  IN THE SOFTWARE.
30 
31  */
32 
33 #include "rtpinternalsourcedata.h"
34 #include "rtppacket.h"
35 #include <string.h>
36 
37 #define RTPINTERNALSOURCEDATA_MAXPROBATIONPACKETS 32
38 
39 namespace qrtplib
40 {
41 
43  RTPSourceData(ssrc)
44 {
45 }
46 
48 {
49 }
50 
51 // The following function should delete rtppack if necessary
52 int RTPInternalSourceData::ProcessRTPPacket(RTPPacket *rtppack, const RTPTime &receivetime, bool *stored, RTPSources *sources)
53 {
54  bool accept;
55  double tsunit;
56 
57  *stored = false;
58 
59  if (timestampunit < 0)
61  else
62  tsunit = timestampunit;
63 
64  stats.ProcessPacket(rtppack, receivetime, tsunit, ownssrc, &accept);
65 
66  if (!accept)
67  return 0;
68  validated = true;
69 
70  if (validated && !ownssrc) // for own ssrc these variables depend on the outgoing packets, not on the incoming
71  issender = true;
72 
73  bool isonprobation = !validated;
74  bool ispackethandled = false;
75 
76  sources->OnValidatedRTPPacket(this, rtppack, isonprobation, &ispackethandled);
77  if (ispackethandled) // Packet is already handled in the callback, no need to store it in the list
78  {
79  // Set 'stored' to true to avoid the packet being deallocated
80  *stored = true;
81  return 0;
82  }
83 
84  // Now, we can place the packet in the queue
85 
86  if (packetlist.empty())
87  {
88  *stored = true;
89  packetlist.push_back(rtppack);
90  return 0;
91  }
92 
93  if (!validated) // still on probation
94  {
95  // Make sure that we don't buffer too much packets to avoid wasting memory
96  // on a bad source. Delete the packet in the queue with the lowest sequence
97  // number.
99  {
100  RTPPacket *p = *(packetlist.begin());
101  packetlist.pop_front();
102  delete p;
103  }
104  }
105 
106  // find the right position to insert the packet
107 
108  std::list<RTPPacket*>::iterator it, start;
109  bool done = false;
110  uint32_t newseqnr = rtppack->GetExtendedSequenceNumber();
111 
112  it = packetlist.end();
113  --it;
114  start = packetlist.begin();
115 
116  while (!done)
117  {
118  RTPPacket *p;
119  uint32_t seqnr;
120 
121  p = *it;
122  seqnr = p->GetExtendedSequenceNumber();
123  if (seqnr > newseqnr)
124  {
125  if (it != start)
126  --it;
127  else // we're at the start of the list
128  {
129  *stored = true;
130  done = true;
131  packetlist.push_front(rtppack);
132  }
133  }
134  else if (seqnr < newseqnr) // insert after this packet
135  {
136  ++it;
137  packetlist.insert(it, rtppack);
138  done = true;
139  *stored = true;
140  }
141  else // they're equal !! Drop packet
142  {
143  done = true;
144  }
145  }
146 
147  return 0;
148 }
149 
150 int RTPInternalSourceData::ProcessSDESItem(uint8_t sdesid, const uint8_t *data, std::size_t itemlen, const RTPTime &receivetime, bool *cnamecollis)
151 {
152  *cnamecollis = false;
153 
154  stats.SetLastMessageTime(receivetime);
155 
156  switch (sdesid)
157  {
158  case RTCP_SDES_ID_CNAME:
159  {
160  std::size_t curlen;
161  uint8_t *oldcname;
162 
163  // NOTE: we're going to make sure that the CNAME is only set once.
164  oldcname = SDESinf.GetCNAME(&curlen);
165  if (curlen == 0)
166  {
167  // if CNAME is set, the source is validated
168  SDESinf.SetCNAME(data, itemlen);
169  validated = true;
170  }
171  else // check if this CNAME is equal to the one that is already present
172  {
173  if (curlen != itemlen)
174  *cnamecollis = true;
175  else
176  {
177  if (memcmp(data, oldcname, itemlen) != 0)
178  *cnamecollis = true;
179  }
180  }
181  }
182  break;
183  case RTCP_SDES_ID_NAME:
184  {
185  std::size_t oldlen;
186 
187  SDESinf.GetName(&oldlen);
188  if (oldlen == 0) // Name not set
189  return SDESinf.SetName(data, itemlen);
190  }
191  break;
192  case RTCP_SDES_ID_EMAIL:
193  {
194  std::size_t oldlen;
195 
196  SDESinf.GetEMail(&oldlen);
197  if (oldlen == 0)
198  return SDESinf.SetEMail(data, itemlen);
199  }
200  break;
201  case RTCP_SDES_ID_PHONE:
202  return SDESinf.SetPhone(data, itemlen);
204  return SDESinf.SetLocation(data, itemlen);
205  case RTCP_SDES_ID_TOOL:
206  {
207  std::size_t oldlen;
208 
209  SDESinf.GetTool(&oldlen);
210  if (oldlen == 0)
211  return SDESinf.SetTool(data, itemlen);
212  }
213  break;
214  case RTCP_SDES_ID_NOTE:
215  stats.SetLastNoteTime(receivetime);
216  return SDESinf.SetNote(data, itemlen);
217  }
218  return 0;
219 }
220 
221 #ifdef RTP_SUPPORT_SDESPRIV
222 
223 int RTPInternalSourceData::ProcessPrivateSDESItem(const uint8_t *prefix, std::size_t prefixlen, const uint8_t *value, std::size_t valuelen, const RTPTime &receivetime)
224 {
225  int status;
226 
227  stats.SetLastMessageTime(receivetime);
228  status = SDESinf.SetPrivateValue(prefix, prefixlen, value, valuelen);
229  if (status == ERR_RTP_SDES_MAXPRIVITEMS)
230  return 0; // don't stop processing just because the number of items is full
231  return status;
232 }
233 
234 #endif // RTP_SUPPORT_SDESPRIV
235 
236 int RTPInternalSourceData::ProcessBYEPacket(const uint8_t *reason, std::size_t reasonlen, const RTPTime &receivetime)
237 {
238  if (byereason)
239  {
240  delete[] byereason;
241  byereason = 0;
242  byereasonlen = 0;
243  }
244 
245  byetime = receivetime;
246  byereason = new uint8_t[reasonlen];
247  memcpy(byereason, reason, reasonlen);
248  byereasonlen = reasonlen;
249  receivedbye = true;
250  stats.SetLastMessageTime(receivetime);
251  return 0;
252 }
253 
254 } // end namespace
255 
#define RTCP_SDES_ID_EMAIL
Definition: rtpdefines.h:58
#define RTCP_SDES_ID_LOCATION
Definition: rtpdefines.h:60
uint8_t * GetTool(std::size_t *len) const
Definition: rtcpsdesinfo.h:153
void ProcessPacket(RTPPacket *pack, const RTPTime &receivetime, double tsunit, bool ownpacket, bool *accept)
virtual void OnValidatedRTPPacket(RTPSourceData *srcdat, RTPPacket *rtppack, bool isonprobation, bool *ispackethandled)
Definition: rtpsources.h:427
int ProcessBYEPacket(const uint8_t *reason, std::size_t reasonlen, const RTPTime &receivetime)
uint8_t * GetCNAME(std::size_t *len) const
Definition: rtcpsdesinfo.h:123
int SetPhone(const uint8_t *s, std::size_t l)
Definition: rtcpsdesinfo.h:88
#define RTCP_SDES_ID_NOTE
Definition: rtpdefines.h:62
#define RTPINTERNALSOURCEDATA_MAXPROBATIONPACKETS
#define ERR_RTP_SDES_MAXPRIVITEMS
Definition: rtperrors.h:108
unsigned int uint32_t
Definition: rtptypes_win.h:46
int SetPrivateValue(const uint8_t *prefix, std::size_t prefixlen, const uint8_t *value, std::size_t valuelen)
int SetEMail(const uint8_t *s, std::size_t l)
Definition: rtcpsdesinfo.h:82
int SetCNAME(const uint8_t *s, std::size_t l)
Definition: rtcpsdesinfo.h:70
void SetLastNoteTime(const RTPTime &t)
unsigned char uint8_t
Definition: rtptypes_win.h:42
uint8_t * GetName(std::size_t *len) const
Definition: rtcpsdesinfo.h:129
double INF_GetEstimatedTimestampUnit() const
uint8_t * GetEMail(std::size_t *len) const
Definition: rtcpsdesinfo.h:135
uint32_t GetExtendedSequenceNumber() const
Definition: rtppacket.h:149
int ProcessRTPPacket(RTPPacket *rtppack, const RTPTime &receivetime, bool *stored, RTPSources *sources)
#define RTCP_SDES_ID_TOOL
Definition: rtpdefines.h:61
int SetTool(const uint8_t *s, std::size_t l)
Definition: rtcpsdesinfo.h:100
int SetLocation(const uint8_t *s, std::size_t l)
Definition: rtcpsdesinfo.h:94
#define RTCP_SDES_ID_CNAME
Definition: rtpdefines.h:56
int SetName(const uint8_t *s, std::size_t l)
Definition: rtcpsdesinfo.h:76
RTPSourceStats stats
void SetLastMessageTime(const RTPTime &t)
#define RTCP_SDES_ID_NAME
Definition: rtpdefines.h:57
int ProcessSDESItem(uint8_t sdesid, const uint8_t *data, std::size_t itemlen, const RTPTime &receivetime, bool *cnamecollis)
#define RTCP_SDES_ID_PHONE
Definition: rtpdefines.h:59
std::list< RTPPacket * > packetlist
int SetNote(const uint8_t *s, std::size_t l)
Definition: rtcpsdesinfo.h:106
int ProcessPrivateSDESItem(const uint8_t *prefix, std::size_t prefixlen, const uint8_t *value, std::size_t valuelen, const RTPTime &receivetime)