SocketDescriptor Class Reference

Collaboration diagram for SocketDescriptor:

Collaboration graph
[legend]

Public Member Functions

 SocketDescriptor (UsageEnvironment &env, int socketNum)
virtual ~SocketDescriptor ()
void registerRTPInterface (unsigned char streamChannelId, RTPInterface *rtpInterface)
RTPInterfacelookupRTPInterface (unsigned char streamChannelId)
void deregisterRTPInterface (unsigned char streamChannelId)
void setServerRequestAlternativeByteHandler (ServerRequestAlternativeByteHandler *handler, void *clientData)

Private Types

enum  {
  AWAITING_DOLLAR, AWAITING_STREAM_CHANNEL_ID, AWAITING_SIZE1, AWAITING_SIZE2,
  AWAITING_PACKET_DATA
}

Private Member Functions

void tcpReadHandler1 (int mask)

Static Private Member Functions

static void tcpReadHandler (SocketDescriptor *, int mask)

Private Attributes

UsageEnvironmentfEnv
int fOurSocketNum
HashTablefSubChannelHashTable
ServerRequestAlternativeByteHandlerfServerRequestAlternativeByteHandler
void * fServerRequestAlternativeByteHandlerClientData
u_int8_t fStreamChannelId
u_int8_t fSizeByte1
enum SocketDescriptor:: { ... }  fTCPReadingState

Detailed Description

Definition at line 51 of file RTPInterface.cpp.


Member Enumeration Documentation

anonymous enum [private]

Enumerator:
AWAITING_DOLLAR 
AWAITING_STREAM_CHANNEL_ID 
AWAITING_SIZE1 
AWAITING_SIZE2 
AWAITING_PACKET_DATA 

Definition at line 77 of file RTPInterface.cpp.


Constructor & Destructor Documentation

SocketDescriptor::SocketDescriptor ( UsageEnvironment env,
int  socketNum 
)

Definition at line 309 of file RTPInterface.cpp.

SocketDescriptor::~SocketDescriptor (  )  [virtual]

Definition at line 316 of file RTPInterface.cpp.

References fSubChannelHashTable.

00316                                     {
00317   delete fSubChannelHashTable;
00318 }


Member Function Documentation

void SocketDescriptor::registerRTPInterface ( unsigned char  streamChannelId,
RTPInterface rtpInterface 
)

Definition at line 320 of file RTPInterface.cpp.

References HashTable::Add(), fEnv, fOurSocketNum, fSubChannelHashTable, HashTable::IsEmpty(), UsageEnvironment::taskScheduler(), and tcpReadHandler().

Referenced by RTPInterface::startNetworkReading().

00321                                                                         {
00322   Boolean isFirstRegistration = fSubChannelHashTable->IsEmpty();
00323   fSubChannelHashTable->Add((char const*)(long)streamChannelId,
00324                             rtpInterface);
00325 
00326   if (isFirstRegistration) {
00327     // Arrange to handle reads on this TCP socket:
00328     TaskScheduler::BackgroundHandlerProc* handler
00329       = (TaskScheduler::BackgroundHandlerProc*)&tcpReadHandler;
00330     fEnv.taskScheduler().
00331       turnOnBackgroundReadHandling(fOurSocketNum, handler, this);
00332   }
00333 }

RTPInterface * SocketDescriptor::lookupRTPInterface ( unsigned char  streamChannelId  ) 

Definition at line 336 of file RTPInterface.cpp.

References fSubChannelHashTable, and HashTable::Lookup().

Referenced by tcpReadHandler1().

00336                                                   {
00337   char const* lookupArg = (char const*)(long)streamChannelId;
00338   return (RTPInterface*)(fSubChannelHashTable->Lookup(lookupArg));
00339 }

void SocketDescriptor::deregisterRTPInterface ( unsigned char  streamChannelId  ) 

Definition at line 342 of file RTPInterface.cpp.

References fEnv, fOurSocketNum, fSubChannelHashTable, HashTable::IsEmpty(), HashTable::Remove(), removeSocketDescription(), UsageEnvironment::taskScheduler(), and TaskScheduler::turnOffBackgroundReadHandling().

Referenced by deregisterSocket().

00342                                                       {
00343   fSubChannelHashTable->Remove((char const*)(long)streamChannelId);
00344 
00345   if (fSubChannelHashTable->IsEmpty()) {
00346     // No more interfaces are using us, so it's curtains for us now
00347     fEnv.taskScheduler().turnOffBackgroundReadHandling(fOurSocketNum);
00348     removeSocketDescription(fEnv, fOurSocketNum);
00349     delete this;
00350   }
00351 }

void SocketDescriptor::setServerRequestAlternativeByteHandler ( ServerRequestAlternativeByteHandler handler,
void *  clientData 
) [inline]

Definition at line 61 of file RTPInterface.cpp.

References fServerRequestAlternativeByteHandler, and fServerRequestAlternativeByteHandlerClientData.

Referenced by RTPInterface::setServerRequestAlternativeByteHandler().

00061                                                                                                               {
00062     fServerRequestAlternativeByteHandler = handler;
00063     fServerRequestAlternativeByteHandlerClientData = clientData;
00064   }

void SocketDescriptor::tcpReadHandler ( SocketDescriptor ,
int  mask 
) [static, private]

Definition at line 353 of file RTPInterface.cpp.

References tcpReadHandler1().

Referenced by registerRTPInterface().

00353                                                                                   {
00354   socketDescriptor->tcpReadHandler1(mask);
00355 }

void SocketDescriptor::tcpReadHandler1 ( int  mask  )  [private]

Definition at line 357 of file RTPInterface.cpp.

References AWAITING_DOLLAR, AWAITING_PACKET_DATA, AWAITING_SIZE1, AWAITING_SIZE2, AWAITING_STREAM_CHANNEL_ID, fEnv, RTPInterface::fNextTCPReadSize, RTPInterface::fNextTCPReadStreamChannelId, RTPInterface::fNextTCPReadStreamSocketNum, fOurSocketNum, RTPInterface::fOwner, RTPInterface::fReadHandlerProc, fServerRequestAlternativeByteHandler, fServerRequestAlternativeByteHandlerClientData, fSizeByte1, fStreamChannelId, fTCPReadingState, lookupRTPInterface(), NULL, readSocket(), size, UsageEnvironment::taskScheduler(), and TaskScheduler::turnOffBackgroundReadHandling().

Referenced by tcpReadHandler().

00357                                                {
00358   // We expect the following data over the TCP channel:
00359   //   optional RTSP command or response bytes (before the first '$' character)
00360   //   a '$' character
00361   //   a 1-byte channel id
00362   //   a 2-byte packet size (in network byte order)
00363   //   the packet data.
00364   // However, because the socket is being read asynchronously, this data might arrive in pieces.
00365   
00366   u_int8_t c;
00367   struct sockaddr_in fromAddress;
00368   if (fTCPReadingState != AWAITING_PACKET_DATA) {
00369     int result = readSocket(fEnv, fOurSocketNum, &c, 1, fromAddress);
00370     if (result != 1) { // error reading TCP socket, or no more data available
00371       if (result < 0) { // error
00372         fEnv.taskScheduler().turnOffBackgroundReadHandling(fOurSocketNum); // stops further calls to us
00373       }
00374       return;
00375     }
00376   }
00377   
00378   switch (fTCPReadingState) {
00379     case AWAITING_DOLLAR: {
00380       if (c == '$') {
00381         fTCPReadingState = AWAITING_STREAM_CHANNEL_ID;
00382       } else {
00383         // This character is part of a RTSP request or command, which is handled separately:
00384         if (fServerRequestAlternativeByteHandler != NULL) {
00385           (*fServerRequestAlternativeByteHandler)(fServerRequestAlternativeByteHandlerClientData, c);
00386         }
00387       }
00388       break;
00389     }
00390     case AWAITING_STREAM_CHANNEL_ID: {
00391       // The byte that we read is the stream channel id.
00392       if (lookupRTPInterface(c) != NULL) { // sanity check
00393         fStreamChannelId = c;
00394         fTCPReadingState = AWAITING_SIZE1;
00395       } else {
00396         // This wasn't a stream channel id that we expected.  We're (somehow) in a strange state.  Try to recover:
00397         fTCPReadingState = AWAITING_DOLLAR;
00398       }
00399       break;
00400     }
00401     case AWAITING_SIZE1: {
00402       // The byte that we read is the first (high) byte of the 16-bit RTP or RTCP packet 'size'.
00403       fSizeByte1 = c;
00404       fTCPReadingState = AWAITING_SIZE2;
00405       break;
00406     }
00407     case AWAITING_SIZE2: {
00408       // The byte that we read is the second (low) byte of the 16-bit RTP or RTCP packet 'size'.
00409       unsigned short size = (fSizeByte1<<8)|c;
00410       
00411       // Record the information about the packet data that will be read next:
00412       RTPInterface* rtpInterface = lookupRTPInterface(fStreamChannelId);
00413       if (rtpInterface != NULL) {
00414         rtpInterface->fNextTCPReadSize = size;
00415         rtpInterface->fNextTCPReadStreamSocketNum = fOurSocketNum;
00416         rtpInterface->fNextTCPReadStreamChannelId = fStreamChannelId;
00417       }
00418       fTCPReadingState = AWAITING_PACKET_DATA;
00419       break;
00420     }
00421     case AWAITING_PACKET_DATA: {
00422       // Call the appropriate read handler to get the packet data from the TCP stream:
00423       RTPInterface* rtpInterface = lookupRTPInterface(fStreamChannelId);
00424       if (rtpInterface != NULL) {
00425         if (rtpInterface->fNextTCPReadSize == 0) {
00426           // We've already read all the data for this packet.
00427           fTCPReadingState = AWAITING_DOLLAR;
00428           break;
00429         }
00430         if (rtpInterface->fReadHandlerProc != NULL) {
00431 #ifdef DEBUG
00432           fprintf(stderr, "SocketDescriptor::tcpReadHandler() reading %d bytes on channel %d\n", rtpInterface->fNextTCPReadSize, rtpInterface->fNextTCPReadStreamChannelId);
00433 #endif
00434           rtpInterface->fReadHandlerProc(rtpInterface->fOwner, mask);
00435         }
00436       }
00437       return;
00438     }
00439   }
00440 }


Field Documentation

UsageEnvironment& SocketDescriptor::fEnv [private]

Definition at line 71 of file RTPInterface.cpp.

Referenced by deregisterRTPInterface(), registerRTPInterface(), and tcpReadHandler1().

int SocketDescriptor::fOurSocketNum [private]

Definition at line 72 of file RTPInterface.cpp.

Referenced by deregisterRTPInterface(), registerRTPInterface(), and tcpReadHandler1().

HashTable* SocketDescriptor::fSubChannelHashTable [private]

Definition at line 73 of file RTPInterface.cpp.

Referenced by deregisterRTPInterface(), lookupRTPInterface(), registerRTPInterface(), and ~SocketDescriptor().

ServerRequestAlternativeByteHandler* SocketDescriptor::fServerRequestAlternativeByteHandler [private]

Definition at line 74 of file RTPInterface.cpp.

Referenced by setServerRequestAlternativeByteHandler(), and tcpReadHandler1().

void* SocketDescriptor::fServerRequestAlternativeByteHandlerClientData [private]

Definition at line 75 of file RTPInterface.cpp.

Referenced by setServerRequestAlternativeByteHandler(), and tcpReadHandler1().

u_int8_t SocketDescriptor::fStreamChannelId [private]

Definition at line 76 of file RTPInterface.cpp.

Referenced by tcpReadHandler1().

u_int8_t SocketDescriptor::fSizeByte1 [private]

Definition at line 76 of file RTPInterface.cpp.

Referenced by tcpReadHandler1().

enum { ... } SocketDescriptor::fTCPReadingState [private]

Referenced by tcpReadHandler1().


The documentation for this class was generated from the following file:
Generated on Thu Feb 2 23:55:57 2012 for live by  doxygen 1.5.2