1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// An abstraction of a network interface used for RTP (or RTCP).
19// (This allows the RTP-over-TCP hack (RFC 2326, section 10.12) to
20// be implemented transparently.)
21// C++ header
22
23#ifndef _RTP_INTERFACE_HH
24#define _RTP_INTERFACE_HH
25
26#ifndef _MEDIA_HH
27#include <Media.hh>
28#endif
29#ifndef _GROUPSOCK_HH
30#include "Groupsock.hh"
31#endif
32
33// Typedef for an optional auxilliary handler function, to be called
34// when each new packet is read:
35typedef void AuxHandlerFunc(void* clientData, unsigned char* packet,
36 unsigned& packetSize);
37
38typedef void ServerRequestAlternativeByteHandler(void* instance, u_int8_t requestByte);
39// A hack that allows a handler for RTP/RTCP packets received over TCP to process RTSP commands that may also appear within
40// the same TCP connection. A RTSP server implementation would supply a function like this - as a parameter to
41// "ServerMediaSubsession::startStream()".
42
43class tcpStreamRecord {
44public:
45 tcpStreamRecord(int streamSocketNum, unsigned char streamChannelId,
46 tcpStreamRecord* next);
47 virtual ~tcpStreamRecord();
48
49public:
50 tcpStreamRecord* fNext;
51 int fStreamSocketNum;
52 unsigned char fStreamChannelId;
53};
54
55class RTPInterface {
56public:
57 RTPInterface(Medium* owner, Groupsock* gs);
58 virtual ~RTPInterface();
59
60 Groupsock* gs() const { return fGS; }
61
62 void setStreamSocket(int sockNum, unsigned char streamChannelId);
63 void addStreamSocket(int sockNum, unsigned char streamChannelId);
64 void removeStreamSocket(int sockNum, unsigned char streamChannelId);
65 static void setServerRequestAlternativeByteHandler(UsageEnvironment& env, int socketNum,
66 ServerRequestAlternativeByteHandler* handler, void* clientData);
67 static void clearServerRequestAlternativeByteHandler(UsageEnvironment& env, int socketNum);
68
69 Boolean sendPacket(unsigned char* packet, unsigned packetSize);
70 void startNetworkReading(TaskScheduler::BackgroundHandlerProc*
71 handlerProc);
72 Boolean handleRead(unsigned char* buffer, unsigned bufferMaxSize,
73 // out parameters:
74 unsigned& bytesRead, struct sockaddr_in& fromAddress,
75 int& tcpSocketNum, unsigned char& tcpStreamChannelId,
76 Boolean& packetReadWasIncomplete);
77 // Note: If "tcpSocketNum" < 0, then the packet was received over UDP, and "tcpStreamChannelId"
78 // is undefined (and irrelevant).
79
80
81 // Otherwise (if "tcpSocketNum" >= 0), the packet was received (interleaved) over TCP, and
82 // "tcpStreamChannelId" will return the channel id.
83
84 void stopNetworkReading();
85
86 UsageEnvironment& envir() const { return fOwner->envir(); }
87
88 void setAuxilliaryReadHandler(AuxHandlerFunc* handlerFunc,
89 void* handlerClientData) {
90 fAuxReadHandlerFunc = handlerFunc;
91 fAuxReadHandlerClientData = handlerClientData;
92 }
93
94 void forgetOurGroupsock() { fGS = NULL; }
95 // This may be called - *only immediately prior* to deleting this - to prevent our destructor
96 // from turning off background reading on the 'groupsock'. (This is in case the 'groupsock'
97 // is also being read from elsewhere.)
98
99private:
100 // Helper functions for sending a RTP or RTCP packet over a TCP connection:
101 Boolean sendRTPorRTCPPacketOverTCP(unsigned char* packet, unsigned packetSize,
102 int socketNum, unsigned char streamChannelId);
103 Boolean sendDataOverTCP(int socketNum, u_int8_t const* data, unsigned dataSize, Boolean forceSendToSucceed);
104
105private:
106 friend class SocketDescriptor;
107 Medium* fOwner;
108 Groupsock* fGS;
109 tcpStreamRecord* fTCPStreams; // optional, for RTP-over-TCP streaming/receiving
110
111 unsigned short fNextTCPReadSize;
112 // how much data (if any) is available to be read from the TCP stream
113 int fNextTCPReadStreamSocketNum;
114 unsigned char fNextTCPReadStreamChannelId;
115 TaskScheduler::BackgroundHandlerProc* fReadHandlerProc; // if any
116
117 AuxHandlerFunc* fAuxReadHandlerFunc;
118 void* fAuxReadHandlerClientData;
119};
120
121#endif
122