[Live-devel] derived RTSPServer class - get RTSPClientSession by SessionId

Thomas Göllner goelli at goelli.de
Wed Jan 1 06:59:15 PST 2014


Happy New Year to everyone!

I'm trying to write my own special RTSPServer which extends the
functionality of the library's RTSPServer for some special protocol.
My RTSPServer is supposed to make little changes to the RTSP Messages before
they are send. I'm now stuck at the point where I want to implement a
DESCRIBE-Response for Requests with only rtsp://<server-ip>:<port>/ as
Content-Base but with a correct SessionID. For the special protocol I have
to safe some parameters in the myRTSPClientSession-class. To access them
during DESCRIBE-handle I must have access to the private
fOurServer.fClientSessions->Lookup(sessionId) method to get the correct
ClientSession. I am wondering that this does not work, because fOurServer is
a RTSPServer&
I had some trouble before that with access to protected
RTSPServer::RTSPClientConnactio::fResponseBuffer from a ClientSession. I was
able to do that with some casting. This solution seems not to work here.

I also thought about getting the modifications into the ServerMedieSession
and ServerMediaSubssion classes, but I want to be able to access the Streams
via "normal" clients and "mySpecial" clients. The changes to the description
will confuse the "normal" clients.

To clarify what I mean and what I've done so far, I post a shortend version
of the SourceCode to myRTSPServer-class.

Please tell me how I can access fClientSessions Hashtable which is declared
as private. Or am I supposed to do this in another way?

Best regards,
Thomas Göllner


#include "RTSPServer.hh"
#include "RTSPCommon.hh"
#include <string>
using namespace std;

class myRTSPServer :public RTSPServer {
public:
	class myRTSPClientSession; // forward
	class myRTSPClientConnection; // forward

private:
	friend class myRTSPClientSession;
	friend class myRTSPClientConnection;
	
public:
	//static create new


protected:
	//Constructor
	//virtual Destructor

	virtual RTSPClientConnection* createNewClientConnection(int
clientSocket, struct sockaddr_in clientAddr) {
		return new myRTSPClientConnection (*this, clientSocket,
clientAddr);
	}
	virtual RTSPClientSession* createNewClientSession(u_int32_t
sessionId) {
		return new myRTSPClientSession (*this, sessionId);
	}

public:
	class myRTSPClientConnection: public
RTSPServer::RTSPClientConnection {
	public:
		//Constructor and Destructor

	protected:
		friend class myRTSPClientSession;

		virtual void handleCmd_DESCRIBE(char const* urlPreSuffix,
char const* urlSuffix, char const* fullRequestStr) {
			char sessionId[RTSP_PARAM_STRING_MAX];

			//some Test if the request is one I want to change
			Boolean result = testFunction(urlSuffix,
fullRequestStr, sessionId); 
			// call standard DESCRIBE-handle 
			if (!result)
	
RTSPServer::RTSPClientConnection::handleCmd_DESCRIBE(urlPreSuffix,
urlSuffix, fullRequestStr);
			// change urlSuffix to create DESCRIBE-Reply which I
want to change
			else {
	
RTSPServer::RTSPClientConnection::handleCmd_DESCRIBE(urlPreSuffix,
"DummyStream", fullRequestStr);
				
				RTSPServer::RTSPClientSession* clientSession
=
	
(RTSPServer::RTSPClientSession*)(fOurServer.fClientSessions->Lookup(sessionI
d));
				if (clientSession == NULL) { // Check for
wrong SessionId
					strcpy((char*)fResponseBuffer, "");
					handleCmd_bad();
					return;
				}
				
				// Get the SpecialParameters
				float mySpecialParameter1 = clientSession->
fmySpecialParameter1;
				float mySpecialParameter2 = clientSession->
fmySpecialParameter2;
				char* mySpecialParameter3 = clientSession->
fmySpecialParameter3;
				char* mySpecialLine = new
char[RTSP_PARAM_STRING_MAX];

				// Create special line
				sprintf(mySpecialLine, "This is my special
message.\r\n"
							"It contains the
three special parameters.\r\n"
							"
mySpecialParameter1 = %.3f\r\n"
							"
mySpecialParameter2 = %.3f\r\n"
							"
mySpecialParameter3 = %s\r\n",
							mySpecialParameter1,
							mySpecialParameter2,
	
mySpecialParameter3);

				stringstream oldResponseBuffer;
				oldResponseBuffer << fResponseBuffer;
				string newResponseBuffer;
				
				// Do my changes
				
				//write them back
				snprintf((char*)fResponseBuffer, sizeof
fResponseBuffer,
						"%s"
						"%s\r\n\r\n",
						newResponseBuffer,
						mySpecialLine);
			}
		}
	};


	class myRTSPClientSession: public RTSPServer::RTSPClientSession {
	public:
		// Constructor and virtual Destructor


	protected:
		friend class myRTSPClientConnection;
		float fmySpecialParameter1;
		float fmySpecialParameter2;
		char fmySpecialParameter3[5];

		virtual void
handleCmd_SETUP(RTSPServer::RTSPClientConnection* ourClientConnection,
				char const* urlPreSuffix, char const*
urlSuffix, char const* fullRequestStr) {
			char sessionId[RTSP_PARAM_STRING_MAX];
			char mySpecialParameter1[RTSP_PARAM_STRING_MAX];
			char mySpecialParameter2[RTSP_PARAM_STRING_MAX];
			char mySpecialParameter3[RTSP_PARAM_STRING_MAX];
			//some Test if the request is one I want to change
			Boolean result = testFunction(urlSuffix,
fullRequestStr, sessionId, mySpecialParameter1, mySpecialParameter2,
mySpecialParameter3);
			// call standard DESCRIBE-handle 
			if (!result)
	
RTSPServer::RTSPClientSession::handleCmd_SETUP(ourClientConnection,
urlPreSuffix, urlSuffix, fullRequestStr);
			// change urlSuffix to create DummyStream
			else {
	
RTSPServer::RTSPClientSession::handleCmd_SETUP(ourClientConnection,
urlPreSuffix, "DummyStream", fullRequestStr);
				
				// Set the SpecialParameters for this
SETUP-Request
				fmySpecialParameter1 =
atof(mySpecialParameter1);
				fmySpecialParameter2 =
atof(mySpecialParameter2);
				snprintf(fmySpecialParameter3, 4,
mySpecialParameter3);

				// I had the same problem, but in this case
I resolved it this way
				myRTSPServer::myRTSPClientConnection*
myOurClientConnection =
	
(myRTSPServer::myRTSPClientConnection*)ourClientConnection;
				char *ptr;
				// cut last \r\n from fResponseBuffer
				ptr =
strrchr((char*)myOurClientConnection->fResponseBuffer, '\r');
				*ptr = '\0';
				// add one special line for my protocol
	
strcat((char*)myOurClientConnection->fResponseBuffer, "This is my special
line\r\n\r\n");
			}
		}
	};
};




More information about the live-devel mailing list