[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