Esempio n. 1
0
GenericMediaServer::ClientConnection
::ClientConnection(GenericMediaServer& ourServer, int clientSocket, struct sockaddr_in clientAddr)
  : fOurServer(ourServer), fOurSocket(clientSocket), fClientAddr(clientAddr) {
  // Add ourself to our 'client connections' table:
  fOurServer.fClientConnections->Add((char const*)this, this);

  // Arrange to handle incoming requests:
  resetRequestBuffer();
  envir().taskScheduler()
    .setBackgroundHandling(fOurSocket, SOCKET_READABLE|SOCKET_EXCEPTION, incomingRequestHandler, this);
}
Esempio n. 2
0
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();
}
Esempio n. 3
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

	// 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;
}
Esempio n. 4
0
bool RTSPServer::RTSPClientSession::handleRequest() {
  // Parse the request string into command name and 'CSeq',
  // then handle the command:
  char cmdName[RTSP_PARAM_STRING_MAX];
  char urlPreSuffix[RTSP_PARAM_STRING_MAX];
  char urlSuffix[RTSP_PARAM_STRING_MAX];
  char cseq[RTSP_PARAM_STRING_MAX];
  char* request = (char*)fRequestBuffer;

  if (!parseRTSPRequestString(request, strlen(request),
			      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) {
	  if (strlen(urlPreSuffix) > 0)
	    strcat(urlPreSuffix, "/");
	  strcat(urlPreSuffix, urlSuffix);
      handleCmd_DESCRIBE(cseq, urlPreSuffix, request);
    } else if (strcmp(cmdName, "SETUP") == 0) {
      handleCmd_SETUP(cseq, urlPreSuffix, urlSuffix, request);
    } else if (strcmp(cmdName, "TEARDOWN") == 0
	       || strcmp(cmdName, "PLAY") == 0
	       || strcmp(cmdName, "PAUSE") == 0
	       || strcmp(cmdName, "GET_PARAMETER") == 0) {
      handleCmd_withinSession(cmdName, urlPreSuffix, urlSuffix, cseq,
			      request);
    } 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,
			    request);
  }

  resetRequestBuffer(); // to prepare for any subsequent request

  if (fObserver != NULL) {
	int statusCode = 0;

	sscanf((char const*)fResponseBuffer, "RTSP/1.0 %d", &statusCode);
    fObserver->requestHandled(this, statusCode);
  }

  if (!fSessionIsActive) {
    if (fObserver != NULL) {
       fObserver->clientSessionEnded(this);
	}
	
	delete this;
	return false;
  }

  return true;
}