
Definition at line 48 of file RTPInterface.cpp.
anonymous enum [private] |
| AWAITING_DOLLAR | |
| AWAITING_STREAM_CHANNEL_ID | |
| AWAITING_SIZE1 | |
| AWAITING_SIZE2 | |
| AWAITING_PACKET_DATA |
Definition at line 75 of file RTPInterface.cpp.
00075 { AWAITING_DOLLAR, AWAITING_STREAM_CHANNEL_ID, AWAITING_SIZE1, AWAITING_SIZE2, AWAITING_PACKET_DATA } fTCPReadingState;
| SocketDescriptor::SocketDescriptor | ( | UsageEnvironment & | env, | |
| int | socketNum | |||
| ) |
Definition at line 342 of file RTPInterface.cpp.
00343 :fEnv(env), fOurSocketNum(socketNum), 00344 fSubChannelHashTable(HashTable::create(ONE_WORD_HASH_KEYS)), 00345 fServerRequestAlternativeByteHandler(NULL), fServerRequestAlternativeByteHandlerClientData(NULL), 00346 fReadErrorOccurred(False), fDeleteMyselfNext(False), fTCPReadingState(AWAITING_DOLLAR) { 00347 }
| SocketDescriptor::~SocketDescriptor | ( | ) | [virtual] |
Definition at line 349 of file RTPInterface.cpp.
References fEnv, fOurSocketNum, fReadErrorOccurred, fServerRequestAlternativeByteHandler, fServerRequestAlternativeByteHandlerClientData, fSubChannelHashTable, NULL, HashTable::RemoveNext(), removeSocketDescription(), UsageEnvironment::taskScheduler(), and TaskScheduler::turnOffBackgroundReadHandling().
00349 { 00350 fEnv.taskScheduler().turnOffBackgroundReadHandling(fOurSocketNum); 00351 if (fServerRequestAlternativeByteHandler != NULL) { 00352 // Hack: Pass a special character to our alternative byte handler, to tell it that either 00353 // - an error occurred when reading the TCP socket, or 00354 // - no error occurred, but it needs to take over control of the TCP socket once again. 00355 u_int8_t specialChar = fReadErrorOccurred ? 0xFF : 0xFE; 00356 (*fServerRequestAlternativeByteHandler)(fServerRequestAlternativeByteHandlerClientData, specialChar); 00357 } 00358 removeSocketDescription(fEnv, fOurSocketNum); 00359 00360 if (fSubChannelHashTable != NULL) { 00361 while (fSubChannelHashTable->RemoveNext() != NULL) {} // remove the "RTPInterface"s from the table, but don't delete them 00362 delete fSubChannelHashTable; 00363 } 00364 }
| void SocketDescriptor::registerRTPInterface | ( | unsigned char | streamChannelId, | |
| RTPInterface * | rtpInterface | |||
| ) |
Definition at line 366 of file RTPInterface.cpp.
References HashTable::Add(), fEnv, fOurSocketNum, fSubChannelHashTable, HashTable::IsEmpty(), SOCKET_EXCEPTION, SOCKET_READABLE, UsageEnvironment::taskScheduler(), and tcpReadHandler().
Referenced by RTPInterface::startNetworkReading().
00367 { 00368 Boolean isFirstRegistration = fSubChannelHashTable->IsEmpty(); 00369 #if defined(DEBUG_SEND)||defined(DEBUG_RECEIVE) 00370 fprintf(stderr, "SocketDescriptor(socket %d)::registerRTPInterface(channel %d): isFirstRegistration %d\n", fOurSocketNum, streamChannelId, isFirstRegistration); 00371 #endif 00372 fSubChannelHashTable->Add((char const*)(long)streamChannelId, 00373 rtpInterface); 00374 00375 if (isFirstRegistration) { 00376 // Arrange to handle reads on this TCP socket: 00377 TaskScheduler::BackgroundHandlerProc* handler 00378 = (TaskScheduler::BackgroundHandlerProc*)&tcpReadHandler; 00379 fEnv.taskScheduler(). 00380 setBackgroundHandling(fOurSocketNum, SOCKET_READABLE|SOCKET_EXCEPTION, handler, this); 00381 } 00382 }
| RTPInterface * SocketDescriptor::lookupRTPInterface | ( | unsigned char | streamChannelId | ) |
Definition at line 385 of file RTPInterface.cpp.
References fSubChannelHashTable, and HashTable::Lookup().
Referenced by tcpReadHandler1().
00385 { 00386 char const* lookupArg = (char const*)(long)streamChannelId; 00387 return (RTPInterface*)(fSubChannelHashTable->Lookup(lookupArg)); 00388 }
| void SocketDescriptor::deregisterRTPInterface | ( | unsigned char | streamChannelId | ) |
Definition at line 391 of file RTPInterface.cpp.
References fDeleteMyselfNext, fOurSocketNum, fSubChannelHashTable, HashTable::IsEmpty(), HashTable::Remove(), and True.
Referenced by deregisterSocket().
00391 { 00392 #if defined(DEBUG_SEND)||defined(DEBUG_RECEIVE) 00393 fprintf(stderr, "SocketDescriptor(socket %d)::deregisterRTPInterface(channel %d)\n", fOurSocketNum, streamChannelId); 00394 #endif 00395 fSubChannelHashTable->Remove((char const*)(long)streamChannelId); 00396 00397 if (fSubChannelHashTable->IsEmpty()) { 00398 // No more interfaces are using us, so it's curtains for us now: 00399 fDeleteMyselfNext = True; // hack to cause ourself to be deleted from "tcpReadHandler()" below 00400 } 00401 }
| void SocketDescriptor::setServerRequestAlternativeByteHandler | ( | ServerRequestAlternativeByteHandler * | handler, | |
| void * | clientData | |||
| ) | [inline] |
Definition at line 58 of file RTPInterface.cpp.
References fServerRequestAlternativeByteHandler, and fServerRequestAlternativeByteHandlerClientData.
Referenced by RTPInterface::setServerRequestAlternativeByteHandler().
00058 { 00059 fServerRequestAlternativeByteHandler = handler; 00060 fServerRequestAlternativeByteHandlerClientData = clientData; 00061 }
| void SocketDescriptor::tcpReadHandler | ( | SocketDescriptor * | , | |
| int | mask | |||
| ) | [static, private] |
Definition at line 403 of file RTPInterface.cpp.
References fDeleteMyselfNext, and tcpReadHandler1().
Referenced by registerRTPInterface().
00403 { 00404 // Call the read handler until it returns false, with a limit to avoid starving other sockets 00405 unsigned count = 2000; 00406 while (!socketDescriptor->fDeleteMyselfNext && socketDescriptor->tcpReadHandler1(mask) && --count > 0) {} 00407 if (socketDescriptor->fDeleteMyselfNext) delete socketDescriptor; 00408 }
| Boolean SocketDescriptor::tcpReadHandler1 | ( | int | mask | ) | [private] |
Definition at line 410 of file RTPInterface.cpp.
References AWAITING_DOLLAR, AWAITING_PACKET_DATA, AWAITING_SIZE1, AWAITING_SIZE2, AWAITING_STREAM_CHANNEL_ID, False, fDeleteMyselfNext, fEnv, RTPInterface::fNextTCPReadSize, RTPInterface::fNextTCPReadStreamChannelId, RTPInterface::fNextTCPReadStreamSocketNum, fOurSocketNum, RTPInterface::fOwner, fReadErrorOccurred, RTPInterface::fReadHandlerProc, fServerRequestAlternativeByteHandler, fServerRequestAlternativeByteHandlerClientData, fSizeByte1, fStreamChannelId, fTCPReadingState, lookupRTPInterface(), NULL, readSocket(), size, and True.
Referenced by tcpReadHandler().
00410 { 00411 // We expect the following data over the TCP channel: 00412 // optional RTSP command or response bytes (before the first '$' character) 00413 // a '$' character 00414 // a 1-byte channel id 00415 // a 2-byte packet size (in network byte order) 00416 // the packet data. 00417 // However, because the socket is being read asynchronously, this data might arrive in pieces. 00418 00419 u_int8_t c; 00420 struct sockaddr_in fromAddress; 00421 if (fTCPReadingState != AWAITING_PACKET_DATA) { 00422 int result = readSocket(fEnv, fOurSocketNum, &c, 1, fromAddress); 00423 if (result == 0) { // There was no more data to read 00424 return False; 00425 } else if (result != 1) { // error reading TCP socket, so we will no longer handle it 00426 #ifdef DEBUG_RECEIVE 00427 fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): readSocket(1 byte) returned %d (error)\n", fOurSocketNum, result); 00428 #endif 00429 fReadErrorOccurred = True; 00430 fDeleteMyselfNext = True; 00431 return False; 00432 } 00433 } 00434 00435 Boolean callAgain = True; 00436 switch (fTCPReadingState) { 00437 case AWAITING_DOLLAR: { 00438 if (c == '$') { 00439 #ifdef DEBUG_RECEIVE 00440 fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): Saw '$'\n", fOurSocketNum); 00441 #endif 00442 fTCPReadingState = AWAITING_STREAM_CHANNEL_ID; 00443 } else { 00444 // This character is part of a RTSP request or command, which is handled separately: 00445 if (fServerRequestAlternativeByteHandler != NULL && c != 0xFF && c != 0xFE) { 00446 // Hack: 0xFF and 0xFE are used as special signaling characters, so don't send them 00447 (*fServerRequestAlternativeByteHandler)(fServerRequestAlternativeByteHandlerClientData, c); 00448 } 00449 } 00450 break; 00451 } 00452 case AWAITING_STREAM_CHANNEL_ID: { 00453 // The byte that we read is the stream channel id. 00454 if (lookupRTPInterface(c) != NULL) { // sanity check 00455 fStreamChannelId = c; 00456 fTCPReadingState = AWAITING_SIZE1; 00457 } else { 00458 // This wasn't a stream channel id that we expected. We're (somehow) in a strange state. Try to recover: 00459 #ifdef DEBUG_RECEIVE 00460 fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): Saw nonexistent stream channel id: 0x%02x\n", fOurSocketNum, c); 00461 #endif 00462 fTCPReadingState = AWAITING_DOLLAR; 00463 } 00464 break; 00465 } 00466 case AWAITING_SIZE1: { 00467 // The byte that we read is the first (high) byte of the 16-bit RTP or RTCP packet 'size'. 00468 fSizeByte1 = c; 00469 fTCPReadingState = AWAITING_SIZE2; 00470 break; 00471 } 00472 case AWAITING_SIZE2: { 00473 // The byte that we read is the second (low) byte of the 16-bit RTP or RTCP packet 'size'. 00474 unsigned short size = (fSizeByte1<<8)|c; 00475 00476 // Record the information about the packet data that will be read next: 00477 RTPInterface* rtpInterface = lookupRTPInterface(fStreamChannelId); 00478 if (rtpInterface != NULL) { 00479 rtpInterface->fNextTCPReadSize = size; 00480 rtpInterface->fNextTCPReadStreamSocketNum = fOurSocketNum; 00481 rtpInterface->fNextTCPReadStreamChannelId = fStreamChannelId; 00482 } 00483 fTCPReadingState = AWAITING_PACKET_DATA; 00484 break; 00485 } 00486 case AWAITING_PACKET_DATA: { 00487 callAgain = False; 00488 fTCPReadingState = AWAITING_DOLLAR; // the next state, unless we end up having to read more data in the current state 00489 // Call the appropriate read handler to get the packet data from the TCP stream: 00490 RTPInterface* rtpInterface = lookupRTPInterface(fStreamChannelId); 00491 if (rtpInterface != NULL) { 00492 if (rtpInterface->fNextTCPReadSize == 0) { 00493 // We've already read all the data for this packet. 00494 break; 00495 } 00496 if (rtpInterface->fReadHandlerProc != NULL) { 00497 #ifdef DEBUG_RECEIVE 00498 fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): reading %d bytes on channel %d\n", fOurSocketNum, rtpInterface->fNextTCPReadSize, rtpInterface->fNextTCPReadStreamChannelId); 00499 #endif 00500 fTCPReadingState = AWAITING_PACKET_DATA; 00501 rtpInterface->fReadHandlerProc(rtpInterface->fOwner, mask); 00502 } else { 00503 #ifdef DEBUG_RECEIVE 00504 fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): No handler proc for \"rtpInterface\" for channel %d; need to skip %d remaining bytes\n", fOurSocketNum, fStreamChannelId, rtpInterface->fNextTCPReadSize); 00505 #endif 00506 int result = readSocket(fEnv, fOurSocketNum, &c, 1, fromAddress); 00507 if (result < 0) { // error reading TCP socket, so we will no longer handle it 00508 #ifdef DEBUG_RECEIVE 00509 fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): readSocket(1 byte) returned %d (error)\n", fOurSocketNum, result); 00510 #endif 00511 fReadErrorOccurred = True; 00512 fDeleteMyselfNext = True; 00513 return False; 00514 } else { 00515 fTCPReadingState = AWAITING_PACKET_DATA; 00516 if (result == 1) { 00517 --rtpInterface->fNextTCPReadSize; 00518 callAgain = True; 00519 } 00520 } 00521 } 00522 } 00523 #ifdef DEBUG_RECEIVE 00524 else fprintf(stderr, "SocketDescriptor(socket %d)::tcpReadHandler(): No \"rtpInterface\" for channel %d\n", fOurSocketNum, fStreamChannelId); 00525 #endif 00526 } 00527 } 00528 00529 return callAgain; 00530 }
UsageEnvironment& SocketDescriptor::fEnv [private] |
Definition at line 68 of file RTPInterface.cpp.
Referenced by registerRTPInterface(), tcpReadHandler1(), and ~SocketDescriptor().
int SocketDescriptor::fOurSocketNum [private] |
Definition at line 69 of file RTPInterface.cpp.
Referenced by deregisterRTPInterface(), registerRTPInterface(), tcpReadHandler1(), and ~SocketDescriptor().
HashTable* SocketDescriptor::fSubChannelHashTable [private] |
Definition at line 70 of file RTPInterface.cpp.
Referenced by deregisterRTPInterface(), lookupRTPInterface(), registerRTPInterface(), and ~SocketDescriptor().
ServerRequestAlternativeByteHandler* SocketDescriptor::fServerRequestAlternativeByteHandler [private] |
Definition at line 71 of file RTPInterface.cpp.
Referenced by setServerRequestAlternativeByteHandler(), tcpReadHandler1(), and ~SocketDescriptor().
void* SocketDescriptor::fServerRequestAlternativeByteHandlerClientData [private] |
Definition at line 72 of file RTPInterface.cpp.
Referenced by setServerRequestAlternativeByteHandler(), tcpReadHandler1(), and ~SocketDescriptor().
u_int8_t SocketDescriptor::fStreamChannelId [private] |
u_int8_t SocketDescriptor::fSizeByte1 [private] |
Boolean SocketDescriptor::fReadErrorOccurred [private] |
Definition at line 74 of file RTPInterface.cpp.
Referenced by tcpReadHandler1(), and ~SocketDescriptor().
Boolean SocketDescriptor::fDeleteMyselfNext [private] |
Definition at line 74 of file RTPInterface.cpp.
Referenced by deregisterRTPInterface(), tcpReadHandler(), and tcpReadHandler1().
enum { ... } SocketDescriptor::fTCPReadingState [private] |
Referenced by tcpReadHandler1().
1.5.2