1 /**
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /** \addtogroup  RTP_Stack
18  *  @{
19  */
20 
21 #ifndef __RTP_SESSION_H__
22 #define __RTP_SESSION_H__
23 
24 #include <RtpGlobal.h>
25 #include <RtpPayloadInfo.h>
26 #include <RtpStack.h>
27 #include <IRtpAppInterface.h>
28 #include <RtcpConfigInfo.h>
29 #include <RtpPacket.h>
30 #include <RtpTimerInfo.h>
31 #include <RtpReceiverInfo.h>
32 #include <RtcpPacket.h>
33 #include <mutex>
34 #include <list>
35 
36 class RtpStack;
37 
38 /**
39  * @class   RtpSession
40  * @brief   This is an interface class to the RTP application for RTP session handling.
41  * An RTP session is capable of processing packets received for that session.
42  * This represents the RTP and the associated RTCP session.
43  * The RTP session has a reference to the RTP stack instance to which it belongs.
44  * When a session is deleted, the stack is notified before deleting so that the session list in the
45  * stack can be updated.
46  * The destructor is made private so that this notification mechanism cannot be bypassed while
47  * deleting the session object.
48  */
49 class RtpSession
50 {
51     std::mutex m_objRtpSessionLock;
52 
53     // Ip address assigned to RTP session
54     RtpBuffer* m_pobjTransAddr;
55 
56     // RTP Port number assigned to RTP session
57     RtpDt_UInt16 m_usRtpPort;
58 
59     // RTCP port assigned to RTP session
60     RtpDt_UInt16 m_usRtcpPort;
61 
62     // The stack context for this session. This is got from constructor
63     RtpStack* m_pobjRtpStack;
64 
65     // It tells RTP extension header support
66     RtpDt_UInt16 m_usExtHdrLen;
67 
68     // RtcpConfigInfo
69     RtcpConfigInfo* m_pobjRtcpCfgInfo;
70 
71     // Process RTP in this session
72     eRtp_Bool m_bEnableRTP;
73 
74     // Use RTCP in this session
75     eRtp_Bool m_bEnableRTCP;
76 
77     // Enable RTCP Bye
78     eRtp_Bool m_bEnableRTCPBye;
79 
80     // App configured RTCP timer value
81     RtpDt_UInt16 m_usRTCPTimerVal;
82 
83     // current sequence number that the will be used for next packet that will constructed.
84     RtpDt_UInt16 m_usSeqNum;
85 
86     // Number of times the seqNum has wrapped at 2^16
87     RtpDt_UInt16 m_usSeqNumCycles;
88 
89     /**
90      * Payload descriptions used in the session
91      */
92     RtpPayloadInfo* m_pobjPayloadInfo;
93 
94     /**
95      * Interface for app callbacks. These call backs will be used to notify app
96      * about stack events.
97      */
98     IRtpAppInterface* m_pobjAppInterface;
99 
100     // our SSRC for this session
101     RtpDt_UInt32 m_uiSsrc;
102 
103     // contains the state variables required for calculating RTCP Transmission Timer
104     RtpTimerInfo m_objTimerInfo;
105 
106     // list of RtpReceiverInfo
107     std::list<RtpReceiverInfo*>* m_pobjRtpRcvrInfoList;
108 
109     // list of RtpReceiverInfo
110     std::list<RtpReceiverInfo*>* m_pobjUtlRcvrList;
111 
112     // MTU size to be used for this session. This will be used when preparing a
113     // compound RTCP packet to limit the number of sources for which we are sending
114     // the report
115     RtpDt_UInt32 m_uiSessionMtu;
116 
117     // Count of number of RTP packets I have sent
118     RtpDt_UInt32 m_uiRtpSendPktCount;
119 
120     // Count of number of octets of RTP I have sent
121     RtpDt_UInt32 m_uiRtpSendOctCount;
122 
123     // Count of number of RTCP packets I have sent
124     RtpDt_UInt32 m_uiRtcpSendPktCount;
125 
126     // Count of number of octets of RTCP I have sent
127     RtpDt_UInt32 m_uiRtcpSendOctCount;
128 
129     /* SPR # 473 END */
130     /*as per spec, if we receive our own packets then send bye once, change ssrc,
131     and then ignore the received packets if they continue to loop back to us
132     due to a faulty mixer/translator implementation.
133     */
134     eRtp_Bool m_bSelfCollisionByeSent;
135 
136     // Timer Id
137     RtpDt_Void* m_pTimerId; /* Storing Timer Id to stop while deleting
138                          session*/
139 
140     // Previous RTP timestamp
141     RtpDt_UInt32 m_prevRtpTimestamp;
142 
143     // Current RTP timestamp
144     RtpDt_UInt32 m_curRtpTimestamp;
145 
146     // Current Ntp Timestamp
147     tRTP_NTP_TIME m_stCurNtpTimestamp;
148 
149     // Previous Ntp Timestamp
150     tRTP_NTP_TIME m_stPrevNtpTimestamp;
151 
152     // it tells RTP packet has been sent after timer expiry
153     eRtp_Bool m_bRtpSendPkt;
154 
155     // To control the RTCP transmission packets
156     eRtp_Bool m_bRtcpTxFlag;
157 
158     // To control the RTCP reception packets
159     eRtp_Bool m_bRtcpRxFlag;
160 
161     // Timer callback for RTCP
162     RTPCB_TIMERHANDLER m_pfnTimerCb;
163 
164     // Current RTCP timestamp
165     RtpDt_UInt32 m_curRtcpTimestamp;
166 
167     // Current Ntp Timestamp
168     tRTP_NTP_TIME m_stCurNtpRtcpTs;
169 
170     // it tells RTCP packet has been sent
171     eRtp_Bool m_bRtcpSendPkt;
172 
173     // It will be enabled @ delete session
174     eRtp_Bool m_bSndRtcpByePkt;
175 
176     // it will store RTTD value
177     RtpDt_UInt32 m_lastRTTDelay;
178 
179     // RTCP-XR data
180     tRTCP_XR_DATA m_stRtcpXr;
181 
182     // to check if Xr packet is being sent
183     eRtp_Bool m_bisXr;
184 
185     // it will check if first RTP packet received
186     eRtp_Bool m_bFirstRtpRecvd;
187 
188     /**
189      * It checks SSRC is present in the receiver list
190      */
191     eRtp_Bool findEntryInRcvrList(IN RtpDt_UInt32 uiSsrc);
192 
193     /**
194      * It processes the Received CSRC list after receiving the RTP packet
195      */
196     eRTP_STATUS_CODE processCsrcList(IN RtpHeader* pobjRtpHeader, IN RtpDt_UChar ucCsrcCount);
197 
198     /**
199      * Decodes received RTCP packet and adds entry to Receiver list
200      * if SSRC is not present.
201      */
202     RtpReceiverInfo* processRtcpPkt(
203             IN RtpDt_UInt32 uiRcvdSsrc, IN RtpBuffer* pobjRtcpAddr, IN RtpDt_UInt16 usPort);
204 
205     /**
206      * It deletes entry from Receiver list
207      */
208     RtpDt_Void delEntryFromRcvrList(IN RtpDt_UInt32* puiSsrc);
209 
210     /**
211      * It processes the Received RTCP BYE packet. Deletes entry from Receiver list.
212      */
213     eRTP_STATUS_CODE processByePacket(
214             IN RtcpByePacket* pobjByePkt, IN RtpBuffer* pobjRtcpAddr, IN RtpDt_UInt16 usPort);
215 
216     /**
217      * It processes the Received SDES packet
218      */
219     eRTP_STATUS_CODE processSdesPacket(IN RtcpSdesPacket* pobjSdesPkt);
220 
221     /**
222      * Calculate the timer interval for RTCP
223      */
224     RtpDt_Double rtcp_interval(IN RtpDt_UInt16 usMembers);
225 
226     /**
227      * It iterates through the pobjCsrcList to find uiSsrc.
228      */
229     eRtp_Bool findEntryInCsrcList(IN std::list<RtpDt_UInt32>& pobjCsrcList, IN RtpDt_UInt32 uiSsrc);
230 
231     /**
232      * Checks if the received packet has the same ssrc as ours.
233      */
234     RtpReceiverInfo* checkSsrcCollisionOnRcv(IN RtpBuffer* pobjRtpAddr, IN RtpDt_UInt16 usPort,
235             IN RtpDt_UInt32 uiRcvdSsrc, OUT eRTP_STATUS_CODE& eResult);
236 
237     /**
238      * It sends the RTCP bye packet to  uiReceivedSsrc
239      */
240     eRTP_STATUS_CODE collisionSendRtcpByePkt(IN RtpDt_UInt32 uiReceivedSsrc);
241 
242     /**
243      * It populates Rtp header
244      */
245     eRTP_STATUS_CODE populateRtpHeader(
246             IN RtpHeader* pobjRtpHdr, IN eRtp_Bool eSetMarker, IN RtpDt_UChar ucPayloadType);
247 
248     /**
249      * It calculates number of senders in the receiver list
250      */
251     RtpDt_UInt32 getSenderCount();
252 
253     /**
254      * It populates RTCP SR packet
255      */
256     eRTP_STATUS_CODE populateSrpacket(OUT RtcpSrPacket* pobjSrPkt, IN RtpDt_UInt32 uiRecepCount);
257 
258     /**
259      * It populates RTCP RR packet
260      */
261     eRTP_STATUS_CODE populateReportPacket(
262             OUT RtcpRrPacket* pobjRrPkt, IN eRtp_Bool bRrPkt, IN RtpDt_UInt32 uiRecepCount);
263 
264     /**
265      * It populates RTCP BYE packet
266      */
267     eRTP_STATUS_CODE populateByePacket(IN_OUT RtcpPacket* pobjRtcpPkt);
268 
269     /**
270      * It populates RTCP APP packet
271      */
272     eRTP_STATUS_CODE populateAppPacket(IN_OUT RtcpPacket* pobjRtcpPkt);
273 
274     eRTP_STATUS_CODE populateRtcpFbPacket(IN_OUT RtcpPacket* pobjRtcpPkt, IN RtpDt_UInt32 uiFbType,
275             IN RtpDt_Char* pcBuff, IN RtpDt_UInt32 uiLen, IN RtpDt_UInt32 uiMediaSSRC,
276             IN RtpDt_UInt32 uiPayloadType);
277 
278     /**
279      * It constructs SR packet list
280      */
281     eRTP_STATUS_CODE formSrList(IN RtpDt_UInt32 uiSndrCount, OUT RtcpPacket* pobjRtcpPkt);
282     /**
283      * It constructs RR packet list
284      */
285     eRTP_STATUS_CODE formRrList(IN RtpDt_UInt32 uiSndrCount, OUT RtcpPacket* pobjRtcpPkt);
286 
287     /**
288      * It estimates the total size of APP, SDES and BYE
289      */
290     RtpDt_UInt32 estimateRtcpPktSize();
291 
292     /**
293      * It cleans utl receiver list
294      */
295     RtpDt_Void cleanUtlReceiverList();
296 
297     /**
298      * it will set RTTD value
299      */
300     RtpDt_Void calculateAndSetRTTD(
301             IN RtpDt_UInt32 currentTime, IN RtpDt_UInt32 lsr, IN RtpDt_UInt32 dlsr);
302 
303     eRTP_STATUS_CODE updatePayload(IN RtpPayloadInfo* pstPayloadInfo);
304 
305     /**
306      * It iterates through the receiver list to verify the status of the uiRcvdSsrc.
307      * @param[in] pobjRtpAddr ip address associated to uiRcvdSsrc
308      * @param[in] usPort port number associated to uiRcvdSsrc
309      * @param[in] uiRcvdSsrc received synchronization source.
310      */
311     eRTP_STATUS_CODE chkRcvdSsrcStatus(
312             IN RtpBuffer* pobjRtpAddr, IN RtpDt_UInt16 usPort, IN RtpDt_UInt32 uiRcvdSsrc);
313 
314     RtpDt_UInt16 getRtpPort();
315 
316     RtpBuffer* getRtpTransAddr();
317 
318     RtpDt_UInt16 getExtHdrLen();
319 
320     /**
321      * method for sending rtcp packet
322      */
323     eRTP_STATUS_CODE rtpSendRtcpPacket(IN_OUT RtcpPacket* objRtcpPkt);
324 
325     /**
326      * method for setting timestamp for RTCP packet
327      */
328     RtpDt_Void rtpSetTimestamp();
329 
330     /**
331      * method for making compound rtcp packet
332      */
333     eRTP_STATUS_CODE rtpMakeCompoundRtcpPacket(IN_OUT RtcpPacket* objRtcpPkt);
334 
335     /**
336      * method for calculating total rtcp packet size
337      */
338     RtpDt_UInt32 calculateTotalRtcpSize(
339             IN RtpDt_UInt32 uiSndrCount, IN RtpDt_UInt32 uiEstRtcpSize, IN eRtp_Bool isSR);
340 
341     /**
342      * method for calculating number of report block in SR/RR
343      */
344     RtpDt_UInt32 numberOfReportBlocks(IN RtpDt_UInt32 uiMtuSize, IN RtpDt_UInt32 uiEstRtcpSize);
345 
346     eRTP_STATUS_CODE constructSdesPkt(IN_OUT RtcpPacket* pobjRtcpPkt);
347 
348     eRTP_STATUS_CODE populateRtcpXrPacket(IN_OUT RtcpPacket* pobjRtcpPkt);
349 
350     /**
351      * Check of the received RTP packet payload type is matching with the expected payload types.
352      *
353      * @param RtpHeader
354      * @return true if mathes and false otherwise.
355      */
356     eRtp_Bool checkRtpPayloadType(
357             IN RtpHeader* pobjRtpHeader, IN RtpPayloadInfo* m_pobjPayloadInfo);
358 
359 public:
360     ~RtpSession();
361 
362     /**
363      * Creates a session as part of a stack instance. Application will never create a session
364      * directly by instantiating this object. It will use the Rtp_Stack::CreateRTPSession()
365      * interface to do this.
366      * @param pobjStack Instance of the stack to which this session belongs
367      */
368     RtpSession(IN RtpStack* pobjStack);
369 
370     /**
371      * The default constructor is used only for unit test.
372      */
373     RtpSession();
374 
375     /**
376      * Initialize the session with
377      * - payload information. This will be the number used to send in the packet
378      * - creating a ssrc for the session
379      * - Application interface object for notifications
380      * - RTCP related initialization
381      * - Enables RTCP based on bRtcpEnable flag
382      * - Starts an RTCP timer based on calculated timer interval
383      *
384      * This API would be invoked after creating the RTP session to initialize Rtp session info.
385      *
386      * @param[in] pstPayloadInfo payload type and sampling rate
387      * @param[in] bRtcpEnable Pass eRTP_TRUE if application wants to disable RTCP
388      * @param[in] pobjAppInterface This will be stored by stack for giving notifications to
389      * application
390      * @param[in] pobjRtcpConfigInfo This contains SDES info, CNAME, NAME, EMAIL, PHONE, TOOL,
391      * - Frequency at which each SDES info shall be sent.
392      * - Frequency at which the App packet shall be sent
393      */
394     eRTP_STATUS_CODE initSession(
395             IN IRtpAppInterface* pobjAppInterface, IN RtcpConfigInfo* pobjRtcpConfigInfo);
396     /**
397      * Update the payload info for this stream if it changes after initSession().
398      *
399      * @param pstPayloadInfo: payload type and sampling rate
400      */
401     eRTP_STATUS_CODE setPayload(IN RtpPayloadInfo* pstPayloadInfo, IN RtpDt_UInt16 usExtHdrLen);
402 
403     eRTP_STATUS_CODE setRTCPTimerValue(IN RtpDt_UInt16 usRTCPTimerVal);
404 
405     /**
406      * calls the delete stream of RTP stack.
407      */
408     eRTP_STATUS_CODE deleteRtpSession();
409 
410     /**
411      * Decode a received RTP packet.
412      * Check for ssrc collision
413      * Information updated per session participant
414      *   - Total packets received
415      *   - Bytes of payload received
416      *   - Sequence number of the packet received
417      *   - roll over couter to track the number of times seq number has wrapped
418      *   - received packet list.. to calculate packet loss
419      *   - inter arrival jitter updation using
420      *       - Last packet's receiver RTP time stamp
421      *       - Last packet's sender RTP time stamp
422      *       - last calculated jitter value
423      *       - Current packet's receiver RTP timestamp
424      *       - Current packet's sender RTP timestamp
425      * update total number of members
426      * update list of members
427      * update total number of active senders
428      * update list of active senders
429      * @param[in] pobjRtpAddr Ip address from which packet is received
430      * @param[in] usPort port number from which packet is received.
431      * @param[in] pobjRTPPacket Buffer from network and the number of bytes in the buffer
432      * @param[out] pobjRtpPkt Decoded RTP packet
433      */
434     eRTP_STATUS_CODE processRcvdRtpPkt(IN RtpBuffer* pobjRtpAddr, IN RtpDt_UInt16 usPort,
435             IN RtpBuffer* pobjRTPPacket, OUT RtpPacket* pobjRtpPkt);
436 
437     /**
438      * It constructs the RTP packet.
439      *     - It allocates the memory for RTP packet
440      *     - if any error is encountered in RTP packet construction,
441      *        memory will be released by the RTP Stack.
442      *     - if any error is NOT encountered in RTP packet construction,
443      *        memory will be released by the Application.
444      *     - It updates the Statistics parameters associated to the SSRC.
445      *         - Update the number of packets that we have sent in uiSendPktCount
446      *         - Update the number of bytes that we have sent:
447      *            This includes RTP header. Update uiSendOctCount
448      *
449      * @param[in] pobjPayload Rtp payload with length
450      * @param[in] eSetMarker if marker flag is set, marker bit will be set in RTP header.
451      * @param[out] pRtpPkt Rtp packet with length.
452      */
453     eRTP_STATUS_CODE createRtpPacket(IN RtpBuffer* pobjPayload, IN eRtp_Bool eSetMarker,
454             IN RtpDt_UChar ucPayloadType, IN eRtp_Bool bUseLastTimestamp,
455             IN RtpDt_UInt32 uiRtpTimestampDiff, IN RtpBuffer* pobjXHdr, OUT RtpBuffer* pRtpPkt);
456 
457     /**
458      * - Decode a received RTCP packet.
459      * - Check for ssrc collision.
460      * - update total number of members.
461      * - update list of members.
462      * - update total number of active senders.
463      * - update list of active senders.
464      * @param[in] pobjRtcpAddr Ip address from which packet is received
465      * @param[in] usPort port number from which packet is received.
466      * @param[in] pobjRTCPPacket Buffer from network and the number of bytes in the buffer
467      * @param[out] pobjRtcpPkt Decoded RTCP packet
468      */
469     eRTP_STATUS_CODE processRcvdRtcpPkt(IN RtpBuffer* pobjRtcpAddr, IN RtpDt_UInt16 usPort,
470             IN RtpBuffer* pobjRTCPPacket, OUT RtcpPacket* pobjRtcpPkt);
471 
472     eRtp_Bool sendRtcpByePacket();
473 
474     eRtp_Bool sendRtcpRtpFbPacket(IN RtpDt_UInt32 uiFbType, IN RtpDt_Char* pcBuff,
475             IN RtpDt_UInt32 uiLen, IN RtpDt_UInt32 uiMediaSsrc);
476 
477     eRtp_Bool sendRtcpPayloadFbPacket(IN RtpDt_UInt32 uiFbType, IN RtpDt_Char* pcBuff,
478             IN RtpDt_UInt32 uiLen, IN RtpDt_UInt32 uiMediaSsrc);
479 
480     /**
481      * It sets the m_bRtcpTxFlag to control the RTCP data transmission.
482      * @param[in] bRtcpTxFlag
483      */
484     RtpDt_Void setRtcpTxFlag(IN eRtp_Bool bRtcpTxFlag);
485 
486     /**
487      * It sets the bRtcpRxFlag to control the RTCP data reception.
488      * @param[in] bRtcpRxFlag
489      */
490     RtpDt_Void setRtcpRxFlag(IN eRtp_Bool bRtcpRxFlag);
491 
492     /**
493      * It sets the m_bRtpTxFlag to control the RTCP data transmission.
494      *
495      * @param[in] bRtpTxFlag
496      */
497     RtpDt_Void setRtpTxFlag(IN eRtp_Bool bRtpTxFlag);
498 
499     /**
500      *
501      * It sets the bRtpRxFlag to control the RTP data reception.
502      * @param[in] bRtpRxFlag
503      */
504     RtpDt_Void setRtpRxFlag(IN eRtp_Bool bRtpRxFlag);
505 
506     RtpDt_Void setSsrc(IN RtpDt_UInt32 uiSsrc);
507 
508     RtpDt_UInt32 getSsrc();
509 
510     RtpDt_Void setSequenceNumber(IN RtpDt_UInt16 uiSeqNumber);
511 
512     RtpDt_UInt16 getSequenceNumber();
513 
514     RtpDt_Void setRtpPort(IN RtpDt_UInt16 usPort);
515 
516     RtpDt_Void setRtpTransAddr(IN RtpBuffer* pobjDestTransAddr);
517 
518     /**
519      * It compares the DestAddr, Port and SSRC with this object.
520      *
521      * @param pobjSession Session to be compared.
522      */
523     eRtp_Bool compareRtpSessions(IN RtpSession* pobjSession);
524 
525     /**
526      * Handling of RTCP timer expiry.
527      * It constructs the RTCP compound packet after rtcp timer expiry.
528      * It re-calculates the RTCP timer value and starts the timer.
529      */
530     RtpDt_Void rtcpTimerExpiry(IN RtpDt_Void* pvTimerId);
531 
532     eRTP_STATUS_CODE disableRtcp();
533 
534     eRTP_STATUS_CODE enableRtcp(eRtp_Bool enableRTCPBye);
535 
536     /**
537      * disables Rtp processing
538      */
539     eRTP_STATUS_CODE disableRtp();
540 
541     /**
542      * enables Rtp Processing
543      */
544     eRTP_STATUS_CODE enableRtp();
545 
546     /**
547      * To check if RTP processing is enabled
548      */
549     eRtp_Bool isRtpEnabled();
550 
551     eRTP_STATUS_CODE sendRtcpXrPacket(IN RtpDt_UChar* m_pBlockBuffer, IN RtpDt_UInt16 nblockLength);
552 
553     RtpDt_UInt32 getRTTD();
554 };
555 
556 #endif  //__RTP_SESSION_H__
557 
558 /** @}*/
559