RTSP Class Reference

<class description="" goes="" here=""> <short description=""> More...

#include <RTSP.hpp>

Inheritance diagram for RTSP:

Protocol List of all members.

Public Member Functions

bool applyReqToSession (const char *req, u32 bytesRead, Session *ses)
bool applyReqToSession (const char *req, u32 bytesRead, Session *ses, bool optionsCallback)
 wrapper method for applyReqToSession()
ContainerInfoparseResponseDescribe (const char *response, const char *url, char **serverName, list< rtx_group * > *groups=NULL)
 parses the response generated by a DESCRIBE (the SDP description) and builds a ContainerInfo object from this info.
int parseResponseSetup (const char *buffer, int *sessionID, int *clientPort, int *serverPort, bool *unicast, char **ssrc, rtx_info *info=NULL)
 parses a reponse to a setup, returns the number of parameters successfully extracted.
void generateDescribeForUrl (const char *url, const char *playerId, const TerminalCapabilities *tc=NULL, const UserPreferences *up=NULL)
void generateSetup (const char *url, int trackId, int clientPort, bool unicast, u32 rtxPort=0, int sessionId=-1)
void generatePlay (const char *url, u32 session, double startTime, double nptEnd, double maxPrefetch)
void generatePause (const char *url, u32 session)
void generateTeardown (const char *url, u32 session)
void generateRedirect (const char *url, const char *newUrl, const time_t *redirectAllowedAtTimePoint=NULL)
void generateFileNotFound ()
void generateOk ()
void generateSessionNotFound ()
void generateInternalServerError ()
void generateDestUnreachable ()
void generateNotImplemented ()
void generateBadCMD ()
void generateIllegalTransport ()
void generateNotEnoughBandwidth ()
void generateInvalidParameter (const int numParams, const char *const *const param)
void generateSetParameter (const char *url, u32 session, std::map< char *, char *, struct stringCompare > *params)
void generateGetParameter (const char *url, const u32 session, const int numParams, const char **params)
void parseGetParameter (const char *req, u32 *session, int *numParams, char ***params)
 parses a GET_PARAMETER
void parseSetParameter (const char *req, u32 *session, std::map< char *, char *, struct stringCompare > *params)
 will parse a SET_PARAMETER
bool parseCMDDescribe (Session *ses, const Url *fileName, const char *remaining, char **playerId)
bool parseCMDSetup (Session *ses, const Url *fileName, const char *const remaining, bool *hasSessionKey, int *sesKey, char **protocols, char **unicast, int *esId, int *rPort, int *rPort2, bool *hasRtxPort, u32 *clientRtxPort, char **clientAddress=NULL)
bool parseCMDPlay (Session *ses, const Url *filename, const char *remaining, int *sessionId, double *startTime, double *endTime, double *maxPrefetch)
void parseCMDRedirect (Session *ses, const Url *fileName, const char *remaining, char **newUrl, time_t *redirectAllowedAtTimePoint)
 newUrl and redirectAllowedAtTimePoint are out parameters.
void generateResponseGetParameter (std::map< char *, char *, struct stringCompare > *params)
bool generateCMDDescribeReply (Session *ses, const Url *fileName, const char *sourceServerName, const char *playerId)
bool generateSetupReply (Session *ses, const Url *fileName, const int sesKey, const char *protocols, const char *unicast, const char *sourceAddress, const int esId, const int rPort, const int rPort2, const int lport, const u32 clientRtxPort, const u32 serverRtxPort)
void generateCMDnotSupportedReply ()
void generateCMDOptionsReply ()
void incSeqNr ()
void decSeqNr ()
int getLastStatus () const
const char * getBuffer () const
int getDefaultPort () const
int generateSessionKey ()
int extractSessionKeyFromCMD (const char *remaining)
 returns INVALID_SESSIONID if no sessionid was found
int getSeqNr ()
 returns last sequence number

Static Public Member Functions

bool isSupportedTransport (const char *protocols)
bool isCmdOk (const char *buf)
u32 extractSessionId (const char *buffer)
char * replaceSessionIdWith (u32 newId, const char *buffer)
void doTest ()
void freeMapMemory (std::map< char *, char *, struct stringCompare > *params)

Protected Types

enum  MSG_Type {
  MSG_DESCRIBE, MSG_SETUP, MSG_PLAY, MSG_PAUSE,
  MSG_OPTIONS, MSG_TEARDOWN, GET_PARAMETER, SET_PARAMETER,
  MSG_REDIRECT, MSG_UNKNOWN
}
 returns the sessionId which will be terminated

Protected Attributes

int seqNr
int lastStatus
char buffer [MSG_BUFFER_SIZE]
bool optionsCallback

Static Protected Attributes

const char *const allowedCommands
const int SL_PAYLOAD_TYPE = 96
const int TTL = 16

Detailed Description

<class description="" goes="" here=""> <short description="">

Author:
Michael Kropfberger and Peter Schojer
Version:
Id
RTSP.hpp,v 1.15 2006/01/20 15:37:54 mkropfbe Exp

Definition at line 75 of file RTSP.hpp.


Member Function Documentation

void RTSP::generateRedirect const char *  url,
const char *  newUrl,
const time_t *  redirectAllowedAtTimePoint = NULL
 

Parameters:
url contains the requested file
newUrl contains the new url that the client should use for the request
redirectAllowedAtTimePoint contains the time when the client is allowed to send the request to the new location. This is an optional parameter.
Definition at line 1781 of file RTSP.cpp.
01783 { 01784 int offset=sprintf(buffer,"REDIRECT %s RTSP/1.0\r\n" 01785 "CSeq: %i\r\n" 01786 "Location: %s\r\n",url,seqNr,newUrl); 01787 if(redirectAllowedAtTimePoint) { 01788 struct tm* tl=localtime(redirectAllowedAtTimePoint); 01789 char timeStr[30]; 01790 strftime(timeStr, 30, "%Y%m%dT%H%M%SZ-", tl); 01791 sprintf(offset+buffer,"Range: clock=%s\r\n\r\n",timeStr); 01792 } 01793 else 01794 sprintf(buffer+offset,"\r\n"); 01795 }

void RTSP::generateSetup const char *  url,
int  trackId,
int  clientPort,
bool  unicast,
u32  rtxPort = 0,
int  sessionId = -1
 

Parameters:
rtxPort specifies the client port used for retransmission, set to 0 to disable retransmisson,
sessionId should be -1 if you want the server to generate a sessionid
Definition at line 1297 of file RTSP.cpp.
01298 { 01299 assert(url && trackId>=0 && clientPort>0); 01300 buffer[0]=0; 01301 char* mcast[]={"multicast","unicast"}; 01302 01303 if(rtxPort==0) { 01304 if(sessionId<=0) { 01305 sprintf(buffer,"SETUP %s/trackID=%i RTSP/1.0\r\n" 01306 "CSeq: %i\r\n" 01307 "Transport: RTP/UDP;%s;client_port=%i-%i\r\n\r\n", 01308 url,trackId, 01309 seqNr, 01310 mcast[unicast ? 1 :0],clientPort,clientPort+1); 01311 } 01312 else { 01313 sprintf(buffer,"SETUP %s/trackID=%i RTSP/1.0\r\n" 01314 "CSeq: %i\r\n" 01315 "Session: %i\r\n" 01316 "Transport: RTP/UDP;%s;client_port=%i-%i\r\n\r\n", 01317 url,trackId, 01318 sessionId, 01319 seqNr, 01320 mcast[unicast ? 1 :0],clientPort,clientPort+1); 01321 } 01322 } 01323 else { 01324 if(sessionId<=0) { 01325 sprintf(buffer,"SETUP %s/trackID=%i RTSP/1.0\r\n" 01326 "CSeq: %i\r\n" 01327 "Transport: RTP/UDP;%s;client_port=%i-%i;client_rtx_port=%u\r\n\r\n", 01328 url,trackId, 01329 seqNr, 01330 mcast[unicast ? 1 :0],clientPort,clientPort+1,rtxPort); 01331 } 01332 else { 01333 sprintf(buffer,"SETUP %s/trackID=%i RTSP/1.0\r\n" 01334 "CSeq: %i\r\n" 01335 "Session: %i\r\n" 01336 "Transport: RTP/UDP;%s;client_port=%i-%i;client_rtx_port=%u\r\n\r\n", 01337 url,trackId, 01338 sessionId, 01339 seqNr, 01340 mcast[unicast ? 1 :0],clientPort,clientPort+1,rtxPort); 01341 } 01342 } 01343 };

void RTSP::parseCMDRedirect Session ses,
const Url fileName,
const char *  remaining,
char **  newUrl,
time_t *  redirectAllowedAtTimePoint
 

newUrl and redirectAllowedAtTimePoint are out parameters.

Memory for newUrl is reserved inside the function. Make sure that *newUrl=NULL prior callingDefinition at line 1800 of file RTSP.cpp.

01802 { 01803 assert(remaining); 01804 assert(*newUrl==NULL); // otherwise mem leak created 01805 assert(redirectAllowedAtTimePoint); 01806 01807 time(redirectAllowedAtTimePoint); 01808 *newUrl=NULL; 01809 01810 const char* pStr=strstr(remaining,"Location:"); 01811 if(!pStr) 01812 return; 01813 01814 while(pStr[0]==' ') 01815 pStr++; 01816 // points to first char of url 01817 const char* pStrEnd=strstr(pStr,"\r\n"); 01818 if(!pStrEnd) // invalid request 01819 return; 01820 pStrEnd--; 01821 if(pStr>=pStrEnd) 01822 return; 01823 while(pStrEnd[0]==' ') 01824 pStrEnd--; 01825 //pStrEnd points to the last Char of the Url 01826 *newUrl=new char[pStrEnd-pStr+2]; 01827 strncpy(*newUrl,pStr,pStrEnd-pStr+1); 01828 (*newUrl)[pStrEnd-pStr+1]='\0'; 01829 01830 // now search for timepoint 01831 pStr=strstr(remaining,"Range:"); 01832 if(!pStr) 01833 return; 01834 pStr=strstr(pStr,"clock="); 01835 if(!pStr) 01836 return; 01837 pStr+=strlen("clock="); 01838 01839 //we now point to the first char of the timestring 01840 struct tm val; 01841 if(6==sscanf(pStr,"%4i%2i%2iT%2i%2i%2i", 01842 &val.tm_year,&val.tm_mon,&val.tm_mday,&val.tm_hour,&val.tm_min,&val.tm_sec)) { 01843 time_t t=mktime(&val); 01844 *redirectAllowedAtTimePoint=t; 01845 } 01846 01847 };

void RTSP::parseGetParameter const char *  req,
u32 *  session,
int *  numParams,
char ***  params
 

parses a GET_PARAMETER

Parameters:
req and extracts the list of parameters specified in the request
numParams contains the number of parameters requested, or 0 on error
session contains the session identifier, or 0 on error
params contains the strings of parameters requested: (*params)[0] will contain the first
Definition at line 1594 of file RTSP.cpp.
01595 { 01596 assert(session && numParams && params); 01597 *session=0; 01598 *numParams=0; 01599 *params=NULL; 01600 const char* lptr=NULL; 01601 u32 length=0; 01602 lptr=strstr(request,"Session:"); 01603 if(lptr) { 01604 lptr+=strlen("Session:"); 01605 while(*lptr==' ') 01606 lptr++; 01607 sscanf(lptr,"%u",session); 01608 } 01609 lptr=strstr(request,"Content-Length:"); 01610 if(lptr) { 01611 lptr+=strlen("Content-Length:"); 01612 while(*lptr==' ') 01613 lptr++; 01614 sscanf(lptr,"%u",&length); 01615 } 01616 if(lptr && length>0) { 01617 // count \r\n to determine numParams 01618 const char* tptr=lptr; 01619 int p=0; 01620 while((tptr=strstr(tptr,"\r\n"))!=NULL) { 01621 p++; 01622 tptr+=2; 01623 } 01624 p-=3; // one \r\n from prev line, one empty line before + one after 01625 *numParams=p; 01626 *params=new char*[p]; 01627 // now extract single params 01628 tptr=lptr; 01629 p=0; 01630 while((tptr=strstr(tptr,"\r\n"))!=NULL) { 01631 if((tptr-lptr)>2) { 01632 // not an empty line 01633 (*params)[p]=new char[tptr-lptr+1]; 01634 strncpy((*params)[p],lptr,tptr-lptr); 01635 (*params)[p][tptr-lptr]='\0'; 01636 dprintf_full("RTSP::parseGetParameter found param %s\n",(*params)[p]); 01637 p++; 01638 } 01639 lptr=(tptr+=2); // next line 01640 } 01641 } 01642 };

ContainerInfo * RTSP::parseResponseDescribe const char *  response,
const char *  url,
char **  serverName,
list< rtx_group * > *  groups = NULL
 

parses the response generated by a DESCRIBE (the SDP description) and builds a ContainerInfo object from this info.

Definition at line 816 of file RTSP.cpp.

References ContainerInfo::addESInfo(), ESInfo::enableFrameStatistic(), and ContainerInfo::setIODHandle().

Referenced by ClientSession::connect().

00818 { 00819 assert( response && url && serverName); 00820 // check if it is really an ok message 00821 if(!strstr(response,"RTSP/1.0 200 OK")) 00822 return NULL; 00823 00824 const char* serverBegin=strstr(response,"Server:"); 00825 if(serverBegin) { 00826 serverBegin+=strlen("Server:"); 00827 while(*serverBegin==' ') 00828 serverBegin++; 00829 const char* serverEnd=strstr(serverBegin,"\r\n"); 00830 if(serverEnd) { 00831 *serverName=new char[serverEnd-serverBegin+1]; 00832 strncpy(*serverName,serverBegin,serverEnd-serverBegin); 00833 (*serverName)[serverEnd-serverBegin]='\0'; 00834 dprintf_full("RTSP::parseResponseDescribe extracted serverName %s\n",*serverName); 00835 } 00836 else 00837 *serverName=NULL; 00838 } 00839 else 00840 *serverName=NULL; 00841 00842 ContainerInfo * mp4Info = new ContainerInfo(url, NULL, ContainerInfo::SDP); 00843 00844 // search rtx_groups 00845 if(groups) { 00846 const char* grp=response; 00847 while( (grp=strstr(grp,"a=group:FID"))!=NULL ) { 00848 rtx_group* group=new rtx_group(NACK,0); 00849 grp+=strlen("a=group:FID"); 00850 if(2!=sscanf( grp, 00851 "%u %u", 00852 &(group->midESInfo), &(group->rtx->mId))) { 00853 delete group; 00854 } 00855 else { 00856 dprintf_full("RTSP::parseResponseDescribe found rtx group: mid %u midES %u\n", 00857 group->rtx->mId,group->midESInfo); 00858 groups->push_back(group); 00859 } 00860 } 00861 } 00862 // we have created the groups 00863 00864 // extract iod 00865 const char *iod = strstr(response, "mpeg4-iod:"); 00866 iod = strstr(iod, "base64,"); 00867 if (iod) { 00868 iod += 7; // points to first char of iod 00869 // iod ends with ", there shouldn't be any space within the IOD 00870 // but there can be a \n! 00871 const char *temp2 = strchr(iod, '"'); 00872 int iodSizeEncoded = temp2 - iod; 00873 u8 iodHandle[MAX_IOD_SIZE]; 00874 00875 //decode 00876 // int iodenclen = str_base64((char*)iod, iodSizeEncoded, iodHandle, MAX_IOD_SIZE, STR_BASE64_DECODE); 00877 int iodenclen = base64decode((unsigned char*)iod, iodSizeEncoded, iodHandle, MAX_IOD_SIZE); 00878 00879 if (iodenclen <= 0) { //wrong or no IOD 00880 dprintf_err("RTSP::parseResponseDescribe: there was a wrong/empty IOD given... ignoring...\n"); 00881 } else 00882 // set decoded IOD 00883 mp4Info->setIODHandle(iodHandle, iodenclen); 00884 } 00885 // search for a=range:npt=0- 66.47000 00886 double durSeconds=0; 00887 00888 const char* temp2=strstr(response,"range:"); 00889 if(temp2) { 00890 temp2=strstr(temp2,"-"); 00891 if(temp2) { 00892 temp2++; 00893 sscanf(temp2,"%lf",&durSeconds); 00894 } 00895 } 00896 const char* media=NULL; 00897 const char* endOfMedia=NULL; 00898 const char* copy=response; 00899 00900 // search media blocks 00901 // media blocks begin with m= 00902 while ((media = strstr(copy, "\nm=")) != NULL) { 00903 00904 //media now points to first m= 00905 media += 3; 00906 copy = media; 00907 endOfMedia = strstr(copy, "\nm="); 00908 if (!endOfMedia) { 00909 // set to end of sdp desc. 00910 endOfMedia = media + strlen(media); 00911 } 00912 00913 // we can have two different media blocks 00914 // one normal one which describes the media 00915 // or one rtx transmission block 00916 // detect this by searching "rtx" 00917 const char* pRtx=strstr(media,"rtx"); 00918 if(pRtx > media && pRtx < endOfMedia) { 00919 // we have a rtx entry 00920 // should we ignore it ? 00921 if(groups) 00922 parseSDP_RTXBlock(media,endOfMedia,groups); 00923 } 00924 else { 00925 ESInfo* es=parseSDPMediaBlock(media,endOfMedia, 00926 durSeconds,mp4Info,groups); 00927 if(es) { 00928 // add es to mp4info 00929 es->enableFrameStatistic(); 00930 mp4Info->addESInfo(es); 00931 } 00932 else { 00933 delete mp4Info; 00934 return NULL; 00935 } 00936 } 00937 } 00938 00939 return mp4Info; 00940 };

int RTSP::parseResponseSetup const char *  buffer,
int *  sessionID,
int *  clientPort,
int *  serverPort,
bool *  unicast,
char **  ssrc,
rtx_info *  info = NULL
 

parses a reponse to a setup, returns the number of parameters successfully extracted.

Every return value below two should be considered as an illegal reponse.

Parameters:
buffer is an IN-param, rest are OUT-params
Definition at line 1397 of file RTSP.cpp.
01399 { 01400 01401 if(!strstr(buffer,"RTSP/1.0 200 OK")) 01402 return 0; 01403 *ssrc=NULL; 01404 const char* pBuffer=NULL; 01405 int retVal=5; 01406 if(strstr(buffer,"multicast")) 01407 *unicast=false; 01408 else 01409 *unicast=true; 01410 01411 pBuffer=strstr(buffer,"Session: "); 01412 if(pBuffer) 01413 sscanf(pBuffer,"%*s %i",sessionID); 01414 else { 01415 dprintf_err("RTSP.parseResponseSetup: no sessionID found???\n"); 01416 return 0; 01417 } 01418 pBuffer=strstr(buffer,"client_port="); 01419 if(pBuffer) { 01420 pBuffer+=strlen("client_port="); 01421 if(1!=sscanf(pBuffer,"%i",clientPort)) 01422 return 0; 01423 } 01424 pBuffer=strstr(buffer,"server_port="); 01425 if(pBuffer) { 01426 pBuffer+=strlen("server_port="); 01427 if(1!=sscanf(pBuffer,"%i",serverPort)) 01428 return 0; 01429 } 01430 // scan for ssrc 01431 pBuffer=strstr(buffer,"ssrc="); 01432 if(pBuffer) { 01433 pBuffer+=strlen("ssrc="); 01434 *ssrc=new char[9]; 01435 strncpy(*ssrc,pBuffer,8); 01436 (*ssrc)[8]='\0'; 01437 } 01438 else 01439 retVal--; 01440 01441 // check for rtx, rtx is not a must-param, so exclude it from retval 01442 if(info) { 01443 u32 rtxSPort=0; 01444 u32 rtxCPort=0; 01445 pBuffer=strstr(buffer,"server_rtx_port="); 01446 if(pBuffer) { 01447 sscanf( (pBuffer+strlen("server_rtx_port=")), 01448 "%u",&rtxSPort); 01449 } 01450 pBuffer=strstr(buffer,"client_rtx_port="); 01451 if(pBuffer) { 01452 sscanf( (pBuffer+strlen("client_rtx_port=")), 01453 "%u",&rtxCPort); 01454 } 01455 info->localPort=rtxCPort; 01456 info->remotePort=rtxSPort; 01457 } 01458 return retVal; 01459 01460 };

void RTSP::parseSetParameter const char *  req,
u32 *  session,
std::map< char *, char *, struct stringCompare > *  params
 

will parse a SET_PARAMETER

Parameters:
req,writes into
session the session identifier, and writes into (*params)[parameterkey] the pointer to a string. You MUST free the map memory with Rtsp::freeMapMemory
Definition at line 1652 of file RTSP.cpp.
01653 { 01654 assert(remaining && session && params); 01655 *session=0; 01656 const char* lptr=strstr(remaining,"Session:"); 01657 if(lptr) { 01658 lptr+=strlen("Session:"); 01659 while(*lptr==' ') 01660 ++lptr; 01661 sscanf(lptr,"%u",session); 01662 } 01663 // no session could be valid, so continue always 01664 lptr=strstr(remaining,"Content-type:"); 01665 if( !(lptr && (lptr=strstr(lptr,"text/parameters")))) { 01666 dprintf_full("RTSP::parseSetParameter illegal content: X%sX\n",remaining); 01667 return; 01668 } 01669 // lptr points to text/.. 01670 lptr=strstr(lptr,"\r\n"); 01671 if(lptr) 01672 lptr+=2; 01673 else 01674 return; 01675 01676 remaining=lptr; 01677 while((lptr=strstr(lptr,"\r\n")) != NULL) { 01678 if(lptr-remaining>2) { 01679 // we have a line starting with remaining 01680 // ending at pos lptr 01681 // we have two strings in this line "a: b" 01682 const char* sepToken=strstr(remaining,":"); 01683 if(!sepToken) 01684 return; 01685 char* param1=new char[sepToken-remaining+1]; 01686 strncpy(param1,remaining,sepToken-remaining); 01687 param1[sepToken-remaining]='\0'; 01688 sepToken++; //skip after : 01689 while(*sepToken == ' ') 01690 ++sepToken; 01691 char* param2=new char[lptr-sepToken+1]; 01692 strncpy(param2,sepToken,lptr-sepToken); 01693 param2[lptr-sepToken]='\0'; 01694 (*params)[param1]=param2; 01695 } 01696 remaining=(lptr+=2); 01697 } 01698 };


Member Data Documentation

const char *const RTSP::allowedCommands [static, protected]
 

Initial value:

"OPTIONS, DESCRIBE, SETUP, PLAY, PAUSE, TEARDOWN, GET_PARAMETER, SET_PARAMETER, REDIRECT"
Definition at line 97 of file RTSP.cpp.

The documentation for this class was generated from the following files: