RTSPServer::RTSPClientSession
::RTSPClientSession(RTSPServer& ourServer, unsigned sessionId,
	      int clientSocket, struct sockaddr_in clientAddr)
  : fOurServer(ourServer), fOurSessionId(sessionId),
    fOurServerMediaSession(NULL),
    fClientSocket(clientSocket), fClientAddr(clientAddr),
    fLivenessCheckTask(NULL),
    fIsMulticast(False), fSessionIsActive(True), fStreamAfterSETUP(False),
    fTCPStreamIdCount(0), fNumStreamStates(0), fStreamStates(NULL) {
  // Arrange to handle incoming requests:
  resetRequestBuffer();
  envir().taskScheduler().turnOnBackgroundReadHandling(fClientSocket,
     (TaskScheduler::BackgroundHandlerProc*)&incomingRequestHandler, this);
  noteLiveness();
}
Exemple #2
0
void RTSPServer::RTSPClientSession::incomingRequestHandler1() {
  noteLiveness();

  struct sockaddr_in dummy; // 'from' address, meaningless in this case
  Boolean endOfMsg = False;
  unsigned char* ptr = &fRequestBuffer[fRequestBytesAlreadySeen];
  
  int bytesRead = readSocket(envir(), fClientSocket,
			     ptr, fRequestBufferBytesLeft, dummy);
  if (bytesRead <= 0 || (unsigned)bytesRead >= fRequestBufferBytesLeft) {
    // Either the client socket has died, or the request was too big for us.
    // Terminate this connection:
#ifdef DEBUG
    fprintf(stderr, "RTSPClientSession[%p]::incomingRequestHandler1() read %d bytes (of %d); terminating connection!\n", this, bytesRead, fRequestBufferBytesLeft);
#endif
    delete this;
    return;
  }
#ifdef DEBUG
  ptr[bytesRead] = '\0';
  fprintf(stderr, "RTSPClientSession[%p]::incomingRequestHandler1() read %d bytes:%s\n", this, bytesRead, ptr);
#endif

  // Look for the end of the message: <CR><LF><CR><LF>
  unsigned char *tmpPtr = ptr;
  if (fRequestBytesAlreadySeen > 0) --tmpPtr;
      // in case the last read ended with a <CR>
  while (tmpPtr < &ptr[bytesRead-1]) {
    if (*tmpPtr == '\r' && *(tmpPtr+1) == '\n') {
      if (tmpPtr - fLastCRLF == 2) { // This is it:
	endOfMsg = 1;
	break;
      }
      fLastCRLF = tmpPtr;
    }
    ++tmpPtr;
  }
  
  fRequestBufferBytesLeft -= bytesRead;
  fRequestBytesAlreadySeen += bytesRead;

  if (!endOfMsg) return; // subsequent reads will be needed to complete the request

  fRequestBuffer[fRequestBytesAlreadySeen] = '\0';
  handleRequest();
}
Exemple #3
0
GenericMediaServer::ClientSession
::ClientSession(GenericMediaServer& ourServer, u_int32_t sessionId)
  : fOurServer(ourServer), fOurSessionId(sessionId), fOurServerMediaSession(NULL),
    fLivenessCheckTask(NULL) {
  noteLiveness();
}
void RTSPServer::RTSPClientSession::incomingRequestHandler1() {
  noteLiveness();

  struct sockaddr_in dummy; // 'from' address, meaningless in this case
  Boolean endOfMsg = False;
  unsigned char* ptr = &fRequestBuffer[fRequestBytesAlreadySeen];

  int bytesRead = readSocket(envir(), fClientSocket,
					 ptr, fRequestBufferBytesLeft, dummy);
  if (bytesRead <= 0 || (unsigned)bytesRead >= fRequestBufferBytesLeft) {
		// Either the client socket has died, or the request was too big for us.
		// Terminate this connection:
#ifdef DEBUG
	  fprintf(stderr, "RTSPClientSession[%p]::incomingRequestHandler1() read %d bytes (of %d); terminating connection!\n", this, bytesRead, fRequestBufferBytesLeft);
#endif
	  delete this;
	  return;
	}
#ifdef DEBUG
  ptr[bytesRead] = '\0';
  fprintf(stderr, "RTSPClientSession[%p]::incomingRequestHandler1() read %d bytes:%s\n", this, bytesRead, ptr);
#endif

	// Look for the end of the message: <CR><LF><CR><LF>
  unsigned char *tmpPtr = ptr;
  if (fRequestBytesAlreadySeen > 0) --tmpPtr;
			// in case the last read ended with a <CR>
  while (tmpPtr < &ptr[bytesRead-1]) {
	  if (*tmpPtr == '\r' && *(tmpPtr+1) == '\n') {
		  if (tmpPtr - fLastCRLF == 2) { // This is it:
	endOfMsg = 1;
	break;
			}
		  fLastCRLF = tmpPtr;
		}
		++tmpPtr;
	}

  fRequestBufferBytesLeft -= bytesRead;
  fRequestBytesAlreadySeen += bytesRead;

  if (!endOfMsg) return; // subsequent reads will be needed to complete the request

	// Parse the request string into command name and 'CSeq',
	// then handle the command:
  fRequestBuffer[fRequestBytesAlreadySeen] = '\0';
  char cmdName[RTSP_PARAM_STRING_MAX];
  char urlPreSuffix[RTSP_PARAM_STRING_MAX];
  char urlSuffix[RTSP_PARAM_STRING_MAX];
  char cseq[RTSP_PARAM_STRING_MAX];
  if (!parseRTSPRequestString((char*)fRequestBuffer, fRequestBytesAlreadySeen,
					  cmdName, sizeof cmdName,
					  urlPreSuffix, sizeof urlPreSuffix,
					  urlSuffix, sizeof urlSuffix,
					  cseq, sizeof cseq)) {
#ifdef DEBUG
	  fprintf(stderr, "parseRTSPRequestString() failed!\n");
#endif
	  handleCmd_bad(cseq);
	} else {
#ifdef DEBUG
	  fprintf(stderr, "parseRTSPRequestString() returned cmdName \"%s\", urlPreSuffix \"%s\", urlSuffix \"%s\"\n", cmdName, urlPreSuffix, urlSuffix);
#endif
	  if (strcmp(cmdName, "OPTIONS") == 0) {
		  handleCmd_OPTIONS(cseq);
		} else if (strcmp(cmdName, "DESCRIBE") == 0) {
		  handleCmd_DESCRIBE(cseq, urlSuffix, (char const*)fRequestBuffer);
		} else if (strcmp(cmdName, "SETUP") == 0) {
		  handleCmd_SETUP(cseq, urlPreSuffix, urlSuffix, (char const*)fRequestBuffer);
		} else if (strcmp(cmdName, "TEARDOWN") == 0
				 || strcmp(cmdName, "PLAY") == 0
				 || strcmp(cmdName, "PAUSE") == 0
				 || strcmp(cmdName, "GET_PARAMETER") == 0
				 || strcmp(cmdName, "SET_PARAMETER") == 0) {
		  handleCmd_withinSession(cmdName, urlPreSuffix, urlSuffix, cseq,
						(char const*)fRequestBuffer);
		} else {
		  handleCmd_notSupported(cseq);
		}
	}

#ifdef DEBUG
  fprintf(stderr, "sending response: %s", fResponseBuffer);
#endif
  send(fClientSocket, (char const*)fResponseBuffer, strlen((char*)fResponseBuffer), 0);

  if (strcmp(cmdName, "SETUP") == 0 && fStreamAfterSETUP) {
		// The client has asked for streaming to commence now, rather than after a
		// subsequent "PLAY" command.  So, simulate the effect of a "PLAY" command:
	  handleCmd_withinSession("PLAY", urlPreSuffix, urlSuffix, cseq,
					(char const*)fRequestBuffer);
	}

  resetRequestBuffer(); // to prepare for any subsequent request
  if (!fSessionIsActive) delete this;
}