SIPClient Class Reference

#include <SIPClient.hh>

Inheritance diagram for SIPClient:

Inheritance graph
[legend]
Collaboration diagram for SIPClient:

Collaboration graph
[legend]

Public Member Functions

void setProxyServer (unsigned proxyServerAddress, portNumBits proxyServerPortNum)
void setClientStartPortNum (portNumBits clientStartPortNum)
char * invite (char const *url, Authenticator *authenticator=NULL)
char * inviteWithPassword (char const *url, char const *username, char const *password)
Boolean sendACK ()
Boolean sendBYE ()
UsageEnvironmentenvir () const
char const * name () const
virtual Boolean isSource () const
virtual Boolean isSink () const
virtual Boolean isRTCPInstance () const
virtual Boolean isRTSPClient () const
virtual Boolean isRTSPServer () const
virtual Boolean isMediaSession () const
virtual Boolean isServerMediaSession () const
virtual Boolean isDarwinInjector () const

Static Public Member Functions

static SIPClientcreateNew (UsageEnvironment &env, unsigned char desiredAudioRTPPayloadFormat, char const *mimeSubtype=NULL, int verbosityLevel=0, char const *applicationName=NULL)
static Boolean parseSIPURL (UsageEnvironment &env, char const *url, NetAddress &address, portNumBits &portNum)
static Boolean parseSIPURLUsernamePassword (char const *url, char *&username, char *&password)
static Boolean lookupByName (UsageEnvironment &env, char const *mediumName, Medium *&resultMedium)
static void close (UsageEnvironment &env, char const *mediumName)
static void close (Medium *medium)

Protected Member Functions

virtual ~SIPClient ()
TaskTokennextTask ()

Private Member Functions

 SIPClient (UsageEnvironment &env, unsigned char desiredAudioRTPPayloadFormat, char const *mimeSubtype, int verbosityLevel, char const *applicationName)
void reset ()
char * invite1 (Authenticator *authenticator)
Boolean processURL (char const *url)
Boolean sendINVITE ()
void doInviteStateMachine (unsigned responseCode)
void doInviteStateTerminated (unsigned responseCode)
char * createAuthenticatorString (Authenticator const *authenticator, char const *cmd, char const *url)
Boolean sendRequest (char const *requestString, unsigned requestLength)
unsigned getResponseCode ()
unsigned getResponse (char *&responseBuffer, unsigned responseBufferSize)
Boolean parseResponseCode (char const *line, unsigned &responseCode)

Static Private Member Functions

static void inviteResponseHandler (void *clientData, int mask)
static void timerAHandler (void *clientData)
static void timerBHandler (void *clientData)
static void timerDHandler (void *clientData)

Private Attributes

TaskToken fTimerA
TaskToken fTimerB
TaskToken fTimerD
unsigned const fT1
unsigned fTimerALen
unsigned fTimerACount
unsigned char fDesiredAudioRTPPayloadFormat
char * fMIMESubtype
unsigned fMIMESubtypeSize
int fVerbosityLevel
unsigned fCSeq
char const * fApplicationName
unsigned fApplicationNameSize
char const * fOurAddressStr
unsigned fOurAddressStrSize
portNumBits fOurPortNum
GroupsockfOurSocket
char * fUserAgentHeaderStr
unsigned fUserAgentHeaderStrSize
char const * fURL
unsigned fURLSize
in_addr fServerAddress
portNumBits fServerPortNum
portNumBits fClientStartPortNum
unsigned fCallId
unsigned fFromTag
char const * fToTagStr
unsigned fToTagStrSize
Authenticator fValidAuthenticator
char const * fUserName
unsigned fUserNameSize
char * fInviteSDPDescription
char * fInviteCmd
unsigned fInviteCmdSize
AuthenticatorfWorkingAuthenticator
inviteClientState fInviteClientState
char fEventLoopStopFlag

Detailed Description

Definition at line 37 of file SIPClient.hh.


Constructor & Destructor Documentation

SIPClient::~SIPClient (  )  [protected, virtual]

Definition at line 119 of file SIPClient.cpp.

References fApplicationName, fMIMESubtype, fOurAddressStr, fOurSocket, fUserAgentHeaderStr, and reset().

00119                       {
00120   reset();
00121 
00122   delete[] fUserAgentHeaderStr;
00123   delete fOurSocket;
00124   delete[] (char*)fOurAddressStr;
00125   delete[] (char*)fApplicationName;
00126   delete[] (char*)fMIMESubtype;
00127 }

SIPClient::SIPClient ( UsageEnvironment env,
unsigned char  desiredAudioRTPPayloadFormat,
char const *  mimeSubtype,
int  verbosityLevel,
char const *  applicationName 
) [private]

Definition at line 41 of file SIPClient.cpp.

References env, Medium::envir(), fApplicationName, fApplicationNameSize, fMIMESubtype, fMIMESubtypeSize, fOurAddressStr, fOurAddressStrSize, fOurPortNum, fOurSocket, fUserAgentHeaderStr, fUserAgentHeaderStrSize, UsageEnvironment::getResultMsg(), getSourcePort(), libVersionStr, LIVEMEDIA_LIBRARY_VERSION_STRING, NULL, Port::num(), our_inet_ntoa(), ourIPAddress(), Groupsock::output(), reset(), Socket::socketNum(), and strDup().

00045   : Medium(env),
00046     fT1(500000 /* 500 ms */),
00047     fDesiredAudioRTPPayloadFormat(desiredAudioRTPPayloadFormat),
00048     fVerbosityLevel(verbosityLevel),
00049     fCSeq(0), fURL(NULL), fURLSize(0),
00050     fToTagStr(NULL), fToTagStrSize(0),
00051     fUserName(NULL), fUserNameSize(0),
00052     fInviteSDPDescription(NULL), fInviteCmd(NULL), fInviteCmdSize(0){
00053   if (mimeSubtype == NULL) mimeSubtype = "";
00054   fMIMESubtype = strDup(mimeSubtype);
00055   fMIMESubtypeSize = strlen(fMIMESubtype);
00056 
00057   if (applicationName == NULL) applicationName = "";
00058   fApplicationName = strDup(applicationName);
00059   fApplicationNameSize = strlen(fApplicationName);
00060 
00061   struct in_addr ourAddress;
00062   ourAddress.s_addr = ourIPAddress(env); // hack
00063   fOurAddressStr = strDup(our_inet_ntoa(ourAddress));
00064   fOurAddressStrSize = strlen(fOurAddressStr);
00065 
00066   fOurSocket = new Groupsock(env, ourAddress, 0, 255);
00067   if (fOurSocket == NULL) {
00068     env << "ERROR: Failed to create socket for addr "
00069         << our_inet_ntoa(ourAddress) << ": "
00070         << env.getResultMsg() << "\n";
00071   }
00072 
00073   // Now, find out our source port number.  Hack: Do this by first trying to
00074   // send a 0-length packet, so that the "getSourcePort()" call will work.
00075   fOurSocket->output(envir(), 255, (unsigned char*)"", 0);
00076   Port srcPort(0);
00077   getSourcePort(env, fOurSocket->socketNum(), srcPort);
00078   if (srcPort.num() != 0) {
00079     fOurPortNum = ntohs(srcPort.num());
00080   } else {
00081     // No luck.  Try again using a default port number:
00082     fOurPortNum = 5060;
00083     delete fOurSocket;
00084     fOurSocket = new Groupsock(env, ourAddress, fOurPortNum, 255);
00085     if (fOurSocket == NULL) {
00086       env << "ERROR: Failed to create socket for addr "
00087           << our_inet_ntoa(ourAddress) << ", port "
00088           << fOurPortNum << ": "
00089           << env.getResultMsg() << "\n";
00090     }
00091   }
00092 
00093   // Set various headers to be used in each request:
00094   char const* formatStr;
00095   unsigned headerSize;
00096 
00097   // Set the "User-Agent:" header:
00098   char const* const libName = "LIVE555 Streaming Media v";
00099   char const* const libVersionStr = LIVEMEDIA_LIBRARY_VERSION_STRING;
00100   char const* libPrefix; char const* libSuffix;
00101   if (applicationName == NULL || applicationName[0] == '\0') {
00102     applicationName = libPrefix = libSuffix = "";
00103   } else {
00104     libPrefix = " (";
00105     libSuffix = ")";
00106   }
00107   formatStr = "User-Agent: %s%s%s%s%s\r\n";
00108   headerSize
00109     = strlen(formatStr) + fApplicationNameSize + strlen(libPrefix)
00110     + strlen(libName) + strlen(libVersionStr) + strlen(libSuffix);
00111   fUserAgentHeaderStr = new char[headerSize];
00112   sprintf(fUserAgentHeaderStr, formatStr,
00113           applicationName, libPrefix, libName, libVersionStr, libSuffix);
00114   fUserAgentHeaderStrSize = strlen(fUserAgentHeaderStr);
00115 
00116   reset();
00117 }


Member Function Documentation

SIPClient * SIPClient::createNew ( UsageEnvironment env,
unsigned char  desiredAudioRTPPayloadFormat,
char const *  mimeSubtype = NULL,
int  verbosityLevel = 0,
char const *  applicationName = NULL 
) [static]

Definition at line 33 of file SIPClient.cpp.

References env.

Referenced by createClient().

00036                                                              {
00037   return new SIPClient(env, desiredAudioRTPPayloadFormat, mimeSubtype,
00038                        verbosityLevel, applicationName);
00039 }

void SIPClient::setProxyServer ( unsigned  proxyServerAddress,
portNumBits  proxyServerPortNum 
)

Definition at line 145 of file SIPClient.cpp.

References Groupsock::changeDestinationParameters(), fOurSocket, fServerAddress, fServerPortNum, and NULL.

Referenced by getSDPDescription().

00146                                                                {
00147   fServerAddress.s_addr = proxyServerAddress;
00148   fServerPortNum = proxyServerPortNum;
00149   if (fOurSocket != NULL) {
00150     fOurSocket->changeDestinationParameters(fServerAddress,
00151                                             fServerPortNum, 255);
00152   }
00153 }

void SIPClient::setClientStartPortNum ( portNumBits  clientStartPortNum  )  [inline]

Definition at line 48 of file SIPClient.hh.

References fClientStartPortNum.

Referenced by getSDPDescription().

00048                                                              {
00049     fClientStartPortNum = clientStartPortNum;
00050   }

char * SIPClient::invite ( char const *  url,
Authenticator authenticator = NULL 
)

Definition at line 169 of file SIPClient.cpp.

References fCallId, fFromTag, fURL, fURLSize, invite1(), inviteWithPassword(), NULL, our_random(), parseSIPURLUsernamePassword(), password, processURL(), strDup(), and username.

Referenced by getSDPDescription(), and inviteWithPassword().

00169                                                                      {
00170   // First, check whether "url" contains a username:password to be used:
00171   char* username; char* password;
00172   if (authenticator == NULL
00173       && parseSIPURLUsernamePassword(url, username, password)) {
00174     char* result = inviteWithPassword(url, username, password);
00175     delete[] username; delete[] password; // they were dynamically allocated
00176     return result;
00177   }
00178 
00179   if (!processURL(url)) return NULL;
00180 
00181   delete[] (char*)fURL; fURL = strDup(url);
00182   fURLSize = strlen(fURL);
00183 
00184   fCallId = our_random();
00185   fFromTag = our_random();
00186 
00187   return invite1(authenticator);
00188 }

char * SIPClient::inviteWithPassword ( char const *  url,
char const *  username,
char const *  password 
)

Definition at line 604 of file SIPClient.cpp.

References fUserName, fUserNameSize, fValidAuthenticator, invite(), invite1(), Authenticator::nonce(), NULL, Authenticator::realm(), Authenticator::setUsernameAndPassword(), and strDup().

Referenced by getSDPDescription(), and invite().

00605                                                           {
00606   delete[] (char*)fUserName; fUserName = strDup(username);
00607   fUserNameSize = strlen(fUserName);
00608 
00609   Authenticator authenticator;
00610   authenticator.setUsernameAndPassword(username, password);
00611   char* inviteResult = invite(url, &authenticator);
00612   if (inviteResult != NULL) {
00613     // We are already authorized
00614     return inviteResult;
00615   }
00616 
00617   // The "realm" and "nonce" fields should have been filled in:
00618   if (authenticator.realm() == NULL || authenticator.nonce() == NULL) {
00619     // We haven't been given enough information to try again, so fail:
00620     return NULL;
00621   }
00622 
00623   // Try again (but with the same CallId):
00624   inviteResult = invite1(&authenticator);
00625   if (inviteResult != NULL) {
00626     // The authenticator worked, so use it in future requests:
00627     fValidAuthenticator = authenticator;
00628   }
00629 
00630   return inviteResult;
00631 }

Boolean SIPClient::sendACK (  ) 

Definition at line 633 of file SIPClient.cpp.

References Medium::envir(), False, fCallId, fCSeq, fFromTag, fOurAddressStr, fOurAddressStrSize, fOurPortNum, fToTagStr, fToTagStrSize, fURL, fURLSize, fUserName, fUserNameSize, NULL, sendRequest(), UsageEnvironment::setResultErrMsg(), and True.

Referenced by doInviteStateMachine(), and startPlayingSession().

00633                            {
00634   char* cmd = NULL;
00635   do {
00636     char const* const cmdFmt =
00637       "ACK %s SIP/2.0\r\n"
00638       "From: %s <sip:%s@%s>;tag=%u\r\n"
00639       "Via: SIP/2.0/UDP %s:%u\r\n"
00640       "To: %s;tag=%s\r\n"
00641       "Call-ID: %u@%s\r\n"
00642       "CSeq: %d ACK\r\n"
00643       "Content-length: 0\r\n\r\n";
00644     unsigned cmdSize = strlen(cmdFmt)
00645       + fURLSize
00646       + 2*fUserNameSize + fOurAddressStrSize + 20 /* max int len */
00647       + fOurAddressStrSize + 5 /* max port len */
00648       + fURLSize + fToTagStrSize
00649       + 20 + fOurAddressStrSize
00650       + 20;
00651     cmd = new char[cmdSize];
00652     sprintf(cmd, cmdFmt,
00653             fURL,
00654             fUserName, fUserName, fOurAddressStr, fFromTag,
00655             fOurAddressStr, fOurPortNum,
00656             fURL, fToTagStr,
00657             fCallId, fOurAddressStr,
00658             fCSeq /* note: it's the same as before; not incremented */);
00659 
00660     if (!sendRequest(cmd, strlen(cmd))) {
00661       envir().setResultErrMsg("ACK send() failed: ");
00662       break;
00663     }
00664 
00665     delete[] cmd;
00666     return True;
00667   } while (0);
00668 
00669   delete[] cmd;
00670   return False;
00671 }

Boolean SIPClient::sendBYE (  ) 

Definition at line 673 of file SIPClient.cpp.

References Medium::envir(), False, fCallId, fCSeq, fFromTag, fOurAddressStr, fOurAddressStrSize, fOurPortNum, fToTagStr, fToTagStrSize, fURL, fURLSize, fUserName, fUserNameSize, NULL, sendRequest(), UsageEnvironment::setResultErrMsg(), and True.

Referenced by tearDownSession().

00673                            {
00674   // NOTE: This should really be retransmitted, for reliability #####
00675   char* cmd = NULL;
00676   do {
00677     char const* const cmdFmt =
00678       "BYE %s SIP/2.0\r\n"
00679       "From: %s <sip:%s@%s>;tag=%u\r\n"
00680       "Via: SIP/2.0/UDP %s:%u\r\n"
00681       "To: %s;tag=%s\r\n"
00682       "Call-ID: %u@%s\r\n"
00683       "CSeq: %d ACK\r\n"
00684       "Content-length: 0\r\n\r\n";
00685     unsigned cmdSize = strlen(cmdFmt)
00686       + fURLSize
00687       + 2*fUserNameSize + fOurAddressStrSize + 20 /* max int len */
00688       + fOurAddressStrSize + 5 /* max port len */
00689       + fURLSize + fToTagStrSize
00690       + 20 + fOurAddressStrSize
00691       + 20;
00692     cmd = new char[cmdSize];
00693     sprintf(cmd, cmdFmt,
00694             fURL,
00695             fUserName, fUserName, fOurAddressStr, fFromTag,
00696             fOurAddressStr, fOurPortNum,
00697             fURL, fToTagStr,
00698             fCallId, fOurAddressStr,
00699             ++fCSeq);
00700 
00701     if (!sendRequest(cmd, strlen(cmd))) {
00702       envir().setResultErrMsg("BYE send() failed: ");
00703       break;
00704     }
00705 
00706     delete[] cmd;
00707     return True;
00708   } while (0);
00709 
00710   delete[] cmd;
00711   return False;
00712 }

Boolean SIPClient::parseSIPURL ( UsageEnvironment env,
char const *  url,
NetAddress address,
portNumBits portNum 
) [static]

Definition at line 735 of file SIPClient.cpp.

References _strncasecmp, env, False, NetAddressList::firstAddress(), NetAddressList::numAddresses(), UsageEnvironment::setResultMsg(), and True.

Referenced by processURL().

00737                                                      {
00738   do {
00739     // Parse the URL as "sip:<username>@<address>:<port>/<etc>"
00740     // (with ":<port>" and "/<etc>" optional)
00741     // Also, skip over any "<username>[:<password>]@" preceding <address>
00742     char const* prefix = "sip:";
00743     unsigned const prefixLength = 4;
00744     if (_strncasecmp(url, prefix, prefixLength) != 0) {
00745       env.setResultMsg("URL is not of the form \"", prefix, "\"");
00746       break;
00747     }
00748 
00749     unsigned const parseBufferSize = 100;
00750     char parseBuffer[parseBufferSize];
00751     unsigned addressStartIndex = prefixLength;
00752     while (url[addressStartIndex] != '\0'
00753            && url[addressStartIndex++] != '@') {}
00754     char const* from = &url[addressStartIndex];
00755 
00756     // Skip over any "<username>[:<password>]@"
00757     char const* from1 = from;
00758     while (*from1 != '\0' && *from1 != '/') {
00759       if (*from1 == '@') {
00760         from = ++from1;
00761         break;
00762       }
00763       ++from1;
00764     }
00765 
00766     char* to = &parseBuffer[0];
00767     unsigned i;
00768     for (i = 0; i < parseBufferSize; ++i) {
00769       if (*from == '\0' || *from == ':' || *from == '/') {
00770         // We've completed parsing the address
00771         *to = '\0';
00772         break;
00773       }
00774       *to++ = *from++;
00775     }
00776     if (i == parseBufferSize) {
00777       env.setResultMsg("URL is too long");
00778       break;
00779     }
00780 
00781     NetAddressList addresses(parseBuffer);
00782     if (addresses.numAddresses() == 0) {
00783       env.setResultMsg("Failed to find network address for \"",
00784                            parseBuffer, "\"");
00785       break;
00786     }
00787     address = *(addresses.firstAddress());
00788 
00789     portNum = 5060; // default value
00790     char nextChar = *from;
00791     if (nextChar == ':') {
00792       int portNumInt;
00793       if (sscanf(++from, "%d", &portNumInt) != 1) {
00794         env.setResultMsg("No port number follows ':'");
00795         break;
00796       }
00797       if (portNumInt < 1 || portNumInt > 65535) {
00798         env.setResultMsg("Bad port number");
00799         break;
00800       }
00801       portNum = (portNumBits)portNumInt;
00802     }
00803 
00804     return True;
00805   } while (0);
00806 
00807   return False;
00808 }

Boolean SIPClient::parseSIPURLUsernamePassword ( char const *  url,
char *&  username,
char *&  password 
) [static]

Definition at line 810 of file SIPClient.cpp.

References _strncasecmp, False, NULL, strDup(), and True.

Referenced by invite().

00812                                                                 {
00813   username = password = NULL; // by default
00814   do {
00815     // Parse the URL as "sip:<username>[:<password>]@<whatever>"
00816     char const* prefix = "sip:";
00817     unsigned const prefixLength = 4;
00818     if (_strncasecmp(url, prefix, prefixLength) != 0) break;
00819 
00820     // Look for the ':' and '@':
00821     unsigned usernameIndex = prefixLength;
00822     unsigned colonIndex = 0, atIndex = 0;
00823     for (unsigned i = usernameIndex; url[i] != '\0' && url[i] != '/'; ++i) {
00824       if (url[i] == ':' && colonIndex == 0) {
00825         colonIndex = i;
00826       } else if (url[i] == '@') {
00827         atIndex = i;
00828         break; // we're done
00829       }
00830     }
00831     if (atIndex == 0) break; // no '@' found
00832 
00833     char* urlCopy = strDup(url);
00834     urlCopy[atIndex] = '\0';
00835     if (colonIndex > 0) {
00836       urlCopy[colonIndex] = '\0';
00837       password = strDup(&urlCopy[colonIndex+1]);
00838     } else {
00839       password = strDup("");
00840     }
00841     username = strDup(&urlCopy[usernameIndex]);
00842     delete[] urlCopy;
00843 
00844     return True;
00845   } while (0);
00846 
00847   return False;
00848 }

void SIPClient::reset (  )  [private]

Definition at line 129 of file SIPClient.cpp.

References fApplicationName, fInviteCmd, fInviteCmdSize, fInviteSDPDescription, fServerAddress, fServerPortNum, fToTagStr, fToTagStrSize, fURL, fURLSize, fUserName, fUserNameSize, fValidAuthenticator, fWorkingAuthenticator, NULL, Authenticator::reset(), and strDup().

Referenced by SIPClient(), and ~SIPClient().

00129                       {
00130   fWorkingAuthenticator = NULL;
00131   delete[] fInviteCmd; fInviteCmd = NULL; fInviteCmdSize = 0;
00132   delete[] fInviteSDPDescription; fInviteSDPDescription = NULL;
00133 
00134   delete[] (char*)fUserName; fUserName = strDup(fApplicationName);
00135   fUserNameSize = strlen(fUserName);
00136 
00137   fValidAuthenticator.reset();
00138 
00139   delete[] (char*)fToTagStr; fToTagStr = NULL; fToTagStrSize = 0;
00140   fServerPortNum = 0;
00141   fServerAddress.s_addr = 0;
00142   delete[] (char*)fURL; fURL = NULL; fURLSize = 0;
00143 }

char * SIPClient::invite1 ( Authenticator authenticator  )  [private]

Definition at line 190 of file SIPClient.cpp.

References Calling, createAuthenticatorString(), TaskScheduler::doEventLoop(), Medium::envir(), fApplicationName, fApplicationNameSize, fCallId, fClientStartPortNum, fCSeq, fDesiredAudioRTPPayloadFormat, fEventLoopStopFlag, fFromTag, fInviteClientState, fInviteCmd, fInviteCmdSize, fInviteSDPDescription, fMIMESubtype, fMIMESubtypeSize, fOurAddressStr, fOurAddressStrSize, fOurPortNum, fOurSocket, fT1, fTimerA, fTimerACount, fTimerALen, fTimerB, fTimerD, fURL, fURLSize, fUserAgentHeaderStr, fUserAgentHeaderStrSize, fUserName, fUserNameSize, fValidAuthenticator, fWorkingAuthenticator, inviteResponseHandler(), NULL, Authenticator::reset(), TaskScheduler::scheduleDelayedTask(), sendINVITE(), Socket::socketNum(), strDup(), UsageEnvironment::taskScheduler(), timerAHandler(), timerBHandler(), TaskScheduler::turnOffBackgroundReadHandling(), TaskScheduler::turnOnBackgroundReadHandling(), and TaskScheduler::unscheduleDelayedTask().

Referenced by invite(), and inviteWithPassword().

00190                                                      {
00191   do {
00192     // Send the INVITE command:
00193 
00194     // First, construct an authenticator string:
00195     fValidAuthenticator.reset();
00196     fWorkingAuthenticator = authenticator;
00197     char* authenticatorStr
00198       = createAuthenticatorString(fWorkingAuthenticator, "INVITE", fURL);
00199 
00200     // Then, construct the SDP description to be sent in the INVITE:
00201     char* rtpmapLine;
00202     unsigned rtpmapLineSize;
00203     if (fMIMESubtypeSize > 0) {
00204       char const* const rtpmapFmt =
00205         "a=rtpmap:%u %s/8000\r\n";
00206       unsigned rtpmapFmtSize = strlen(rtpmapFmt)
00207         + 3 /* max char len */ + fMIMESubtypeSize;
00208       rtpmapLine = new char[rtpmapFmtSize];
00209       sprintf(rtpmapLine, rtpmapFmt,
00210               fDesiredAudioRTPPayloadFormat, fMIMESubtype);
00211       rtpmapLineSize = strlen(rtpmapLine);
00212     } else {
00213       // Static payload type => no "a=rtpmap:" line
00214       rtpmapLine = strDup("");
00215       rtpmapLineSize = 0;
00216     }
00217     char const* const inviteSDPFmt =
00218       "v=0\r\n"
00219       "o=- %u %u IN IP4 %s\r\n"
00220       "s=%s session\r\n"
00221       "c=IN IP4 %s\r\n"
00222       "t=0 0\r\n"
00223       "m=audio %u RTP/AVP %u\r\n"
00224       "%s";
00225     unsigned inviteSDPFmtSize = strlen(inviteSDPFmt)
00226       + 20 /* max int len */ + 20 + fOurAddressStrSize
00227       + fApplicationNameSize
00228       + fOurAddressStrSize
00229       + 5 /* max short len */ + 3 /* max char len */
00230       + rtpmapLineSize;
00231     delete[] fInviteSDPDescription;
00232     fInviteSDPDescription = new char[inviteSDPFmtSize];
00233     sprintf(fInviteSDPDescription, inviteSDPFmt,
00234             fCallId, fCSeq, fOurAddressStr,
00235             fApplicationName,
00236             fOurAddressStr,
00237             fClientStartPortNum, fDesiredAudioRTPPayloadFormat,
00238             rtpmapLine);
00239     unsigned inviteSDPSize = strlen(fInviteSDPDescription);
00240     delete[] rtpmapLine;
00241 
00242     char const* const cmdFmt =
00243       "INVITE %s SIP/2.0\r\n"
00244       "From: %s <sip:%s@%s>;tag=%u\r\n"
00245       "Via: SIP/2.0/UDP %s:%u\r\n"
00246       "To: %s\r\n"
00247       "Contact: sip:%s@%s:%u\r\n"
00248       "Call-ID: %u@%s\r\n"
00249       "CSeq: %d INVITE\r\n"
00250       "Content-Type: application/sdp\r\n"
00251       "%s" /* Proxy-Authorization: line (if any) */
00252       "%s" /* User-Agent: line */
00253       "Content-length: %d\r\n\r\n"
00254       "%s";
00255     unsigned inviteCmdSize = strlen(cmdFmt)
00256       + fURLSize
00257       + 2*fUserNameSize + fOurAddressStrSize + 20 /* max int len */
00258       + fOurAddressStrSize + 5 /* max port len */
00259       + fURLSize
00260       + fUserNameSize + fOurAddressStrSize + 5
00261       + 20 + fOurAddressStrSize
00262       + 20
00263       + strlen(authenticatorStr)
00264       + fUserAgentHeaderStrSize
00265       + 20
00266       + inviteSDPSize;
00267     delete[] fInviteCmd; fInviteCmd = new char[inviteCmdSize];
00268     sprintf(fInviteCmd, cmdFmt,
00269             fURL,
00270             fUserName, fUserName, fOurAddressStr, fFromTag,
00271             fOurAddressStr, fOurPortNum,
00272             fURL,
00273             fUserName, fOurAddressStr, fOurPortNum,
00274             fCallId, fOurAddressStr,
00275             ++fCSeq,
00276             authenticatorStr,
00277             fUserAgentHeaderStr,
00278             inviteSDPSize,
00279             fInviteSDPDescription);
00280     fInviteCmdSize = strlen(fInviteCmd);
00281     delete[] authenticatorStr;
00282 
00283     // Before sending the "INVITE", arrange to handle any response packets,
00284     // and set up timers:
00285     fInviteClientState = Calling;
00286     fEventLoopStopFlag = 0;
00287     TaskScheduler& sched = envir().taskScheduler(); // abbrev.
00288     sched.turnOnBackgroundReadHandling(fOurSocket->socketNum(),
00289                                        &inviteResponseHandler, this);
00290     fTimerALen = 1*fT1; // initially
00291     fTimerACount = 0; // initially
00292     fTimerA = sched.scheduleDelayedTask(fTimerALen, timerAHandler, this);
00293     fTimerB = sched.scheduleDelayedTask(64*fT1, timerBHandler, this);
00294     fTimerD = NULL; // for now
00295 
00296     if (!sendINVITE()) break;
00297 
00298     // Enter the event loop, to handle response packets, and timeouts:
00299     envir().taskScheduler().doEventLoop(&fEventLoopStopFlag);
00300 
00301     // We're finished with this "INVITE".
00302     // Turn off response handling and timers:
00303     sched.turnOffBackgroundReadHandling(fOurSocket->socketNum());
00304     sched.unscheduleDelayedTask(fTimerA);
00305     sched.unscheduleDelayedTask(fTimerB);
00306     sched.unscheduleDelayedTask(fTimerD);
00307 
00308     // NOTE: We return the SDP description that we used in the "INVITE",
00309     // not the one that we got from the server.
00310     // ##### Later: match the codecs in the response (offer, answer) #####
00311     if (fInviteSDPDescription != NULL) {
00312       return strDup(fInviteSDPDescription);
00313     }
00314   } while (0);
00315 
00316   return NULL;
00317 }

Boolean SIPClient::processURL ( char const *  url  )  [private]

Definition at line 714 of file SIPClient.cpp.

References Groupsock::changeDestinationParameters(), NetAddress::data(), Medium::envir(), False, fOurSocket, fServerAddress, fServerPortNum, NULL, parseSIPURL(), and True.

Referenced by invite().

00714                                              {
00715   do {
00716     // If we don't already have a server address/port, then
00717     // get these by parsing the URL:
00718     if (fServerAddress.s_addr == 0) {
00719       NetAddress destAddress;
00720       if (!parseSIPURL(envir(), url, destAddress, fServerPortNum)) break;
00721       fServerAddress.s_addr = *(unsigned*)(destAddress.data());
00722 
00723       if (fOurSocket != NULL) {
00724         fOurSocket->changeDestinationParameters(fServerAddress,
00725                                                 fServerPortNum, 255);
00726       }
00727     }
00728 
00729     return True;
00730   } while (0);
00731 
00732   return False;
00733 }

Boolean SIPClient::sendINVITE (  )  [private]

Definition at line 441 of file SIPClient.cpp.

References Medium::envir(), False, fInviteCmd, fInviteCmdSize, sendRequest(), UsageEnvironment::setResultErrMsg(), and True.

Referenced by doInviteStateMachine(), and invite1().

00441                               {
00442   if (!sendRequest(fInviteCmd, fInviteCmdSize)) {
00443     envir().setResultErrMsg("INVITE send() failed: ");
00444     return False;
00445   }
00446   return True;
00447 }

void SIPClient::inviteResponseHandler ( void *  clientData,
int  mask 
) [static, private]

Definition at line 319 of file SIPClient.cpp.

References doInviteStateMachine(), and getResponseCode().

Referenced by invite1().

00319                                                                     {
00320   SIPClient* client = (SIPClient*)clientData;
00321   unsigned responseCode = client->getResponseCode();
00322   client->doInviteStateMachine(responseCode);
00323 }

void SIPClient::doInviteStateMachine ( unsigned  responseCode  )  [private]

Definition at line 358 of file SIPClient.cpp.

References Calling, Completed, doInviteStateTerminated(), Medium::envir(), fInviteClientState, fTimerA, fTimerALen, fTimerB, fTimerD, Proceeding, TaskScheduler::scheduleDelayedTask(), sendACK(), sendINVITE(), UsageEnvironment::setResultMsg(), UsageEnvironment::taskScheduler(), Terminated, timerAFires, timerAHandler(), timerBFires, timerDFires, timerDHandler(), and TaskScheduler::unscheduleDelayedTask().

Referenced by inviteResponseHandler(), timerAHandler(), timerBHandler(), and timerDHandler().

00358                                                           {
00359   // Implement the state transition diagram (RFC 3261, Figure 5)
00360   TaskScheduler& sched = envir().taskScheduler(); // abbrev.
00361   switch (fInviteClientState) {
00362     case Calling: {
00363       if (responseCode == timerAFires) {
00364         // Restart timer A (with double the timeout interval):
00365         fTimerALen *= 2;
00366         fTimerA
00367           = sched.scheduleDelayedTask(fTimerALen, timerAHandler, this);
00368 
00369         fInviteClientState = Calling;
00370         if (!sendINVITE()) doInviteStateTerminated(0);
00371       } else {
00372         // Turn off timers A & B before moving to a new state:
00373         sched.unscheduleDelayedTask(fTimerA);
00374         sched.unscheduleDelayedTask(fTimerB);
00375 
00376         if (responseCode == timerBFires) {
00377           envir().setResultMsg("No response from server");
00378           doInviteStateTerminated(0);
00379         } else if (responseCode >= 100 && responseCode <= 199) {
00380           fInviteClientState = Proceeding;
00381         } else if (responseCode >= 200 && responseCode <= 299) {
00382           doInviteStateTerminated(responseCode);
00383         } else if (responseCode >= 400 && responseCode <= 499) {
00384           doInviteStateTerminated(responseCode);
00385               // this isn't what the spec says, but it seems right...
00386         } else if (responseCode >= 300 && responseCode <= 699) {
00387           fInviteClientState = Completed;
00388           fTimerD
00389             = sched.scheduleDelayedTask(32000000, timerDHandler, this);
00390           if (!sendACK()) doInviteStateTerminated(0);
00391         }
00392       }
00393       break;
00394     }
00395 
00396     case Proceeding: {
00397       if (responseCode >= 100 && responseCode <= 199) {
00398         fInviteClientState = Proceeding;
00399       } else if (responseCode >= 200 && responseCode <= 299) {
00400         doInviteStateTerminated(responseCode);
00401       } else if (responseCode >= 400 && responseCode <= 499) {
00402         doInviteStateTerminated(responseCode);
00403             // this isn't what the spec says, but it seems right...
00404       } else if (responseCode >= 300 && responseCode <= 699) {
00405         fInviteClientState = Completed;
00406         fTimerD = sched.scheduleDelayedTask(32000000, timerDHandler, this);
00407         if (!sendACK()) doInviteStateTerminated(0);
00408       }
00409       break;
00410     }
00411 
00412     case Completed: {
00413       if (responseCode == timerDFires) {
00414         envir().setResultMsg("Transaction terminated");
00415         doInviteStateTerminated(0);
00416       } else if (responseCode >= 300 && responseCode <= 699) {
00417         fInviteClientState = Completed;
00418         if (!sendACK()) doInviteStateTerminated(0);
00419       }
00420       break;
00421     }
00422 
00423     case Terminated: {
00424         doInviteStateTerminated(responseCode);
00425         break;
00426     }
00427   }
00428 }

void SIPClient::doInviteStateTerminated ( unsigned  responseCode  )  [private]

Definition at line 430 of file SIPClient.cpp.

References fEventLoopStopFlag, fInviteClientState, fInviteSDPDescription, NULL, and Terminated.

Referenced by doInviteStateMachine().

00430                                                              {
00431   fInviteClientState = Terminated; // FWIW...
00432   if (responseCode < 200 || responseCode > 299) {
00433     // We failed, so return NULL;
00434     delete[] fInviteSDPDescription; fInviteSDPDescription = NULL;
00435   }
00436 
00437   // Unblock the event loop:
00438   fEventLoopStopFlag = ~0;
00439 }

void SIPClient::timerAHandler ( void *  clientData  )  [static, private]

Definition at line 330 of file SIPClient.cpp.

References doInviteStateMachine(), Medium::envir(), fTimerACount, fTimerALen, fVerbosityLevel, and timerAFires.

Referenced by doInviteStateMachine(), and invite1().

00330                                               {
00331   SIPClient* client = (SIPClient*)clientData;
00332   if (client->fVerbosityLevel >= 1) {
00333     client->envir() << "RETRANSMISSION " << ++client->fTimerACount
00334                     << ", after " << client->fTimerALen/1000000.0
00335                     << " additional seconds\n";
00336   }
00337   client->doInviteStateMachine(timerAFires);
00338 }

void SIPClient::timerBHandler ( void *  clientData  )  [static, private]

Definition at line 340 of file SIPClient.cpp.

References doInviteStateMachine(), Medium::envir(), fT1, fVerbosityLevel, and timerBFires.

Referenced by invite1().

00340                                               {
00341   SIPClient* client = (SIPClient*)clientData;
00342   if (client->fVerbosityLevel >= 1) {
00343     client->envir() << "RETRANSMISSION TIMEOUT, after "
00344                     << 64*client->fT1/1000000.0 << " seconds\n";
00345     fflush(stderr);
00346   }
00347   client->doInviteStateMachine(timerBFires);
00348 }

void SIPClient::timerDHandler ( void *  clientData  )  [static, private]

Definition at line 350 of file SIPClient.cpp.

References doInviteStateMachine(), Medium::envir(), fVerbosityLevel, and timerDFires.

Referenced by doInviteStateMachine().

00350                                               {
00351   SIPClient* client = (SIPClient*)clientData;
00352   if (client->fVerbosityLevel >= 1) {
00353     client->envir() << "TIMER D EXPIRED\n";
00354   }
00355   client->doInviteStateMachine(timerDFires);
00356 }

char * SIPClient::createAuthenticatorString ( Authenticator const *  authenticator,
char const *  cmd,
char const *  url 
) [private]

Definition at line 851 of file SIPClient.cpp.

References Authenticator::computeDigestResponse(), Authenticator::nonce(), NULL, Authenticator::password(), Authenticator::realm(), Authenticator::reclaimDigestResponse(), strDup(), and Authenticator::username().

Referenced by invite1().

00852                                                                         {
00853   if (authenticator != NULL && authenticator->realm() != NULL
00854       && authenticator->nonce() != NULL && authenticator->username() != NULL
00855       && authenticator->password() != NULL) {
00856     // We've been provided a filled-in authenticator, so use it:
00857     char const* const authFmt
00858       = "Proxy-Authorization: Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", response=\"%s\", uri=\"%s\"\r\n";
00859     char const* response = authenticator->computeDigestResponse(cmd, url);
00860     unsigned authBufSize = strlen(authFmt)
00861       + strlen(authenticator->username()) + strlen(authenticator->realm())
00862       + strlen(authenticator->nonce()) + strlen(url) + strlen(response);
00863     char* authenticatorStr = new char[authBufSize];
00864     sprintf(authenticatorStr, authFmt,
00865             authenticator->username(), authenticator->realm(),
00866             authenticator->nonce(), response, url);
00867     authenticator->reclaimDigestResponse(response);
00868 
00869     return authenticatorStr;
00870   }
00871 
00872   return strDup("");
00873 }

Boolean SIPClient::sendRequest ( char const *  requestString,
unsigned  requestLength 
) [private]

Definition at line 875 of file SIPClient.cpp.

References Medium::envir(), fOurSocket, fVerbosityLevel, and Groupsock::output().

Referenced by sendACK(), sendBYE(), and sendINVITE().

00876                                                        {
00877   if (fVerbosityLevel >= 1) {
00878     envir() << "Sending request: " << requestString << "\n";
00879   }
00880   // NOTE: We should really check that "requestLength" is not #####
00881   // too large for UDP (see RFC 3261, section 18.1.1) #####
00882   return fOurSocket->output(envir(), 255, (unsigned char*)requestString,
00883                             requestLength);
00884 }

unsigned SIPClient::getResponseCode (  )  [private]

Definition at line 449 of file SIPClient.cpp.

References Medium::envir(), False, fOurSocket, fToTagStr, fToTagStrSize, fVerbosityLevel, fWorkingAuthenticator, getLine(), getResponse(), Groupsock::handleRead(), NULL, parseResponseCode(), Authenticator::setRealmAndNonce(), UsageEnvironment::setResultMsg(), strDup(), strDupSize(), and True.

Referenced by inviteResponseHandler().

00449                                     {
00450   unsigned responseCode = 0;
00451   do {
00452     // Get the response from the server:
00453     unsigned const readBufSize = 10000;
00454     char readBuffer[readBufSize+1]; char* readBuf = readBuffer;
00455 
00456     char* firstLine = NULL;
00457     char* nextLineStart = NULL;
00458     unsigned bytesRead = getResponse(readBuf, readBufSize);
00459     if (bytesRead == 0) break;
00460     if (fVerbosityLevel >= 1) {
00461       envir() << "Received INVITE response: " << readBuf << "\n";
00462     }
00463 
00464     // Inspect the first line to get the response code:
00465     firstLine = readBuf;
00466     nextLineStart = getLine(firstLine);
00467     if (!parseResponseCode(firstLine, responseCode)) break;
00468 
00469     if (responseCode != 200) {
00470       if (responseCode >= 400 && responseCode <= 499
00471           && fWorkingAuthenticator != NULL) {
00472         // We have an authentication failure, so fill in
00473         // "*fWorkingAuthenticator" using the contents of a following
00474         // "Proxy-Authenticate:" line.  (Once we compute a 'response' for
00475         // "fWorkingAuthenticator", it can be used in a subsequent request
00476         // - that will hopefully succeed.)
00477         char* lineStart;
00478         while (1) {
00479           lineStart = nextLineStart;
00480           if (lineStart == NULL) break;
00481 
00482           nextLineStart = getLine(lineStart);
00483           if (lineStart[0] == '\0') break; // this is a blank line
00484 
00485           char* realm = strDupSize(lineStart);
00486           char* nonce = strDupSize(lineStart);
00487           // ##### Check for the format of "Proxy-Authenticate:" lines from
00488           // ##### known server types.
00489           // ##### This is a crock! We should make the parsing more general
00490           Boolean foundAuthenticateHeader = False;
00491           if (
00492               // Asterisk #####
00493               sscanf(lineStart, "Proxy-Authenticate: Digest realm=\"%[^\"]\", nonce=\"%[^\"]\"",
00494                      realm, nonce) == 2 ||
00495               // Cisco ATA #####
00496               sscanf(lineStart, "Proxy-Authenticate: Digest algorithm=MD5,domain=\"%*[^\"]\",nonce=\"%[^\"]\", realm=\"%[^\"]\"",
00497                      nonce, realm) == 2) {
00498             fWorkingAuthenticator->setRealmAndNonce(realm, nonce);
00499             foundAuthenticateHeader = True;
00500           }
00501           delete[] realm; delete[] nonce;
00502           if (foundAuthenticateHeader) break;
00503         }
00504       }
00505       envir().setResultMsg("cannot handle INVITE response: ", firstLine);
00506       break;
00507     }
00508 
00509     // Skip every subsequent header line, until we see a blank line.
00510     // While doing so, check for "To:" and "Content-Length:" lines.
00511     // The remaining data is assumed to be the SDP descriptor that we want.
00512     // We should really do some more checking on the headers here - e.g., to
00513     // check for "Content-type: application/sdp", "CSeq", etc. #####
00514     int contentLength = -1;
00515     char* lineStart;
00516     while (1) {
00517       lineStart = nextLineStart;
00518       if (lineStart == NULL) break;
00519 
00520       nextLineStart = getLine(lineStart);
00521       if (lineStart[0] == '\0') break; // this is a blank line
00522 
00523       char* toTagStr = strDupSize(lineStart);
00524       if (sscanf(lineStart, "To:%*[^;]; tag=%s", toTagStr) == 1) {
00525         delete[] (char*)fToTagStr; fToTagStr = strDup(toTagStr);
00526         fToTagStrSize = strlen(fToTagStr);
00527       }
00528       delete[] toTagStr;
00529 
00530       if (sscanf(lineStart, "Content-Length: %d", &contentLength) == 1
00531           || sscanf(lineStart, "Content-length: %d", &contentLength) == 1) {
00532         if (contentLength < 0) {
00533           envir().setResultMsg("Bad \"Content-length:\" header: \"",
00534                                lineStart, "\"");
00535           break;
00536         }
00537       }
00538     }
00539 
00540     // We're now at the end of the response header lines
00541     if (lineStart == NULL) {
00542       envir().setResultMsg("no content following header lines: ", readBuf);
00543       break;
00544     }
00545 
00546     // Use the remaining data as the SDP descr, but first, check
00547     // the "Content-length:" header (if any) that we saw.  We may need to
00548     // read more data, or we may have extraneous data in the buffer.
00549     char* bodyStart = nextLineStart;
00550     if (bodyStart != NULL && contentLength >= 0) {
00551       // We saw a "Content-length:" header
00552       unsigned numBodyBytes = &readBuf[bytesRead] - bodyStart;
00553       if (contentLength > (int)numBodyBytes) {
00554         // We need to read more data.  First, make sure we have enough
00555         // space for it:
00556         unsigned numExtraBytesNeeded = contentLength - numBodyBytes;
00557 #ifdef USING_TCP
00558         // THIS CODE WORKS ONLY FOR TCP: #####
00559         unsigned remainingBufferSize
00560           = readBufSize - (bytesRead + (readBuf - readBuffer));
00561         if (numExtraBytesNeeded > remainingBufferSize) {
00562           char tmpBuf[200];
00563           sprintf(tmpBuf, "Read buffer size (%d) is too small for \"Content-length:\" %d (need a buffer size of >= %d bytes\n",
00564                   readBufSize, contentLength,
00565                   readBufSize + numExtraBytesNeeded - remainingBufferSize);
00566           envir().setResultMsg(tmpBuf);
00567           break;
00568         }
00569 
00570         // Keep reading more data until we have enough:
00571         if (fVerbosityLevel >= 1) {
00572           envir() << "Need to read " << numExtraBytesNeeded
00573                   << " extra bytes\n";
00574         }
00575         while (numExtraBytesNeeded > 0) {
00576           char* ptr = &readBuf[bytesRead];
00577           unsigned bytesRead2;
00578           struct sockaddr_in fromAddr;
00579           Boolean readSuccess
00580             = fOurSocket->handleRead((unsigned char*)ptr,
00581                                      numExtraBytesNeeded,
00582                                      bytesRead2, fromAddr);
00583           if (!readSuccess) break;
00584           ptr[bytesRead2] = '\0';
00585           if (fVerbosityLevel >= 1) {
00586             envir() << "Read " << bytesRead2
00587                     << " extra bytes: " << ptr << "\n";
00588           }
00589 
00590           bytesRead += bytesRead2;
00591           numExtraBytesNeeded -= bytesRead2;
00592         }
00593 #endif
00594         if (numExtraBytesNeeded > 0) break; // one of the reads failed
00595       }
00596 
00597       bodyStart[contentLength] = '\0'; // trims any extra data
00598     }
00599   } while (0);
00600 
00601   return responseCode;
00602 }

unsigned SIPClient::getResponse ( char *&  responseBuffer,
unsigned  responseBufferSize 
) [private]

Definition at line 886 of file SIPClient.cpp.

References Medium::envir(), False, fOurSocket, Groupsock::handleRead(), UsageEnvironment::setResultMsg(), and True.

Referenced by getResponseCode().

00887                                                              {
00888   if (responseBufferSize == 0) return 0; // just in case...
00889   responseBuffer[0] = '\0'; // ditto
00890 
00891   // Keep reading data from the socket until we see "\r\n\r\n" (except
00892   // at the start), or until we fill up our buffer.
00893   // Don't read any more than this.
00894   char* p = responseBuffer;
00895   Boolean haveSeenNonCRLF = False;
00896   int bytesRead = 0;
00897   while (bytesRead < (int)responseBufferSize) {
00898     unsigned bytesReadNow;
00899     struct sockaddr_in fromAddr;
00900     unsigned char* toPosn = (unsigned char*)(responseBuffer+bytesRead);
00901     Boolean readSuccess
00902       = fOurSocket->handleRead(toPosn, responseBufferSize-bytesRead,
00903                                bytesReadNow, fromAddr);
00904     if (!readSuccess || bytesReadNow == 0) {
00905       envir().setResultMsg("SIP response was truncated");
00906       break;
00907     }
00908     bytesRead += bytesReadNow;
00909 
00910     // Check whether we have "\r\n\r\n":
00911     char* lastToCheck = responseBuffer+bytesRead-4;
00912     if (lastToCheck < responseBuffer) continue;
00913     for (; p <= lastToCheck; ++p) {
00914       if (haveSeenNonCRLF) {
00915         if (*p == '\r' && *(p+1) == '\n' &&
00916             *(p+2) == '\r' && *(p+3) == '\n') {
00917           responseBuffer[bytesRead] = '\0';
00918 
00919           // Before returning, trim any \r or \n from the start:
00920           while (*responseBuffer == '\r' || *responseBuffer == '\n') {
00921             ++responseBuffer;
00922             --bytesRead;
00923           }
00924           return bytesRead;
00925         }
00926       } else {
00927         if (*p != '\r' && *p != '\n') {
00928           haveSeenNonCRLF = True;
00929         }
00930       }
00931     }
00932   }
00933 
00934   return 0;
00935 }

Boolean SIPClient::parseResponseCode ( char const *  line,
unsigned &  responseCode 
) [private]

Definition at line 937 of file SIPClient.cpp.

References Medium::envir(), False, UsageEnvironment::setResultMsg(), and True.

Referenced by getResponseCode().

00938                                                               {
00939   if (sscanf(line, "%*s%u", &responseCode) != 1) {
00940     envir().setResultMsg("no response code in line: \"", line, "\"");
00941     return False;
00942   }
00943 
00944   return True;
00945 }

Boolean Medium::lookupByName ( UsageEnvironment env,
char const *  mediumName,
Medium *&  resultMedium 
) [static, inherited]

Definition at line 65 of file Media.cpp.

References env, False, MediaLookupTable::lookup(), NULL, MediaLookupTable::ourMedia(), UsageEnvironment::setResultMsg(), and True.

Referenced by ServerMediaSession::lookupByName(), RTSPServer::lookupByName(), RTSPClient::lookupByName(), RTCPInstance::lookupByName(), MediaSource::lookupByName(), MediaSink::lookupByName(), MediaSession::lookupByName(), and DarwinInjector::lookupByName().

00066                                                          {
00067   resultMedium = MediaLookupTable::ourMedia(env)->lookup(mediumName);
00068   if (resultMedium == NULL) {
00069     env.setResultMsg("Medium ", mediumName, " does not exist");
00070     return False;
00071   }
00072 
00073   return True;
00074 }

void Medium::close ( UsageEnvironment env,
char const *  mediumName 
) [static, inherited]

Definition at line 76 of file Media.cpp.

References env, MediaLookupTable::ourMedia(), and MediaLookupTable::remove().

Referenced by afterPlaying(), Medium::close(), closeMediaSinks(), OnDemandServerMediaSubsession::closeStreamSource(), continueAfterTEARDOWN(), WAVAudioFileSource::createNew(), QuickTimeFileSink::createNew(), QCELPAudioRTPSource::createNew(), MP3HTTPSource::createNew(), MP3FileSource::createNew(), AVIFileSink::createNew(), AMRAudioRTPSource::createNew(), WAVAudioFileServerMediaSubsession::createNewStreamSource(), MPEG1or2DemuxedServerMediaSubsession::createNewStreamSource(), MediaSubsession::deInitiate(), MediaSubsession::initiate(), MPEG1or2ProgramStreamFileDuration(), MPEG1or2Demux::noteElementaryStreamDeletion(), ByteStreamMultiFileSource::onSourceClosure1(), StreamState::reclaim(), RTSPServer::removeServerMediaSession(), OnDemandServerMediaSubsession::sdpLines(), H264VideoRTPSink::stopPlaying(), subsessionAfterPlaying(), ClientTrickPlayState::updateStateOnScaleChange(), AMRDeinterleaver::~AMRDeinterleaver(), ByteStreamMultiFileSource::~ByteStreamMultiFileSource(), DarwinInjector::~DarwinInjector(), FramedFilter::~FramedFilter(), H264VideoRTPSink::~H264VideoRTPSink(), InputESSourceRecord::~InputESSourceRecord(), MPEG1or2Demux::~MPEG1or2Demux(), MPEG1or2FileServerDemux::~MPEG1or2FileServerDemux(), MPEG2TransportFileServerMediaSubsession::~MPEG2TransportFileServerMediaSubsession(), MPEG2TransportStreamFromPESSource::~MPEG2TransportStreamFromPESSource(), ServerMediaSession::~ServerMediaSession(), and ServerMediaSubsession::~ServerMediaSubsession().

00076                                                           {
00077   MediaLookupTable::ourMedia(env)->remove(name);
00078 }

void Medium::close ( Medium medium  )  [static, inherited]

Definition at line 80 of file Media.cpp.

References Medium::close(), Medium::envir(), Medium::name(), and NULL.

00080                                  {
00081   if (medium == NULL) return;
00082 
00083   close(medium->envir(), medium->name());
00084 }

UsageEnvironment& Medium::envir (  )  const [inline, inherited]

Definition at line 59 of file Media.hh.

References Medium::fEnviron.

Referenced by QuickTimeFileSink::addArbitraryString(), FileSink::addData(), RTCPInstance::addStreamSocket(), MPEG2IFrameIndexFromTransportStream::addToTail(), StreamParser::afterGettingBytes(), MultiFramedRTPSink::afterGettingFrame1(), InputESSourceRecord::afterGettingFrame1(), MPEG2TransportStreamFramer::afterGettingFrame1(), MPEG2IFrameIndexFromTransportStream::afterGettingFrame1(), HTTPSink::afterGettingFrame1(), BasicUDPSink::afterGettingFrame1(), MPEG4VideoFileServerMediaSubsession::afterPlayingDummy1(), MPEG4VideoStreamParser::analyzeVOLHeader(), announceStream(), MPEG4VideoFileServerMediaSubsession::checkForAuxSDPLine1(), Medium::close(), MPEG2IFrameIndexFromTransportStream::compactParseBuffer(), RTSPClient::connectionHandler1(), RTSPClient::connectToServer(), QuickTimeFileSink::continuePlaying(), HTTPSink::continuePlaying(), H264VideoRTPSink::continuePlaying(), AVIFileSink::continuePlaying(), MPEG4VideoFileServerMediaSubsession::createNewRTPSink(), MPEG2TransportFileServerMediaSubsession::createNewRTPSink(), MPEG1or2VideoFileServerMediaSubsession::createNewRTPSink(), MPEG1or2DemuxedServerMediaSubsession::createNewRTPSink(), H263plusVideoFileServerMediaSubsession::createNewRTPSink(), DVVideoFileServerMediaSubsession::createNewRTPSink(), AMRAudioFileServerMediaSubsession::createNewRTPSink(), ADTSAudioFileServerMediaSubsession::createNewRTPSink(), MPEG4VideoFileServerMediaSubsession::createNewStreamSource(), MPEG2TransportFileServerMediaSubsession::createNewStreamSource(), MPEG1or2VideoFileServerMediaSubsession::createNewStreamSource(), MPEG1or2DemuxedServerMediaSubsession::createNewStreamSource(), H263plusVideoFileServerMediaSubsession::createNewStreamSource(), DVVideoFileServerMediaSubsession::createNewStreamSource(), AMRAudioFileServerMediaSubsession::createNewStreamSource(), ADTSAudioFileServerMediaSubsession::createNewStreamSource(), MPEG2IFrameIndexFromTransportStream::deliverIndexRecord(), SegmentQueue::dequeue(), WAVAudioFileSource::doGetNextFrame(), MPEG2IFrameIndexFromTransportStream::doGetNextFrame(), MP3FileSource::doGetNextFrame(), H264FUAFragmenter::doGetNextFrame(), ByteStreamMultiFileSource::doGetNextFrame(), ByteStreamFileSource::doGetNextFrame(), BasicUDPSource::doGetNextFrame(), AMRAudioFileSource::doGetNextFrame(), ADTSAudioFileSource::doGetNextFrame(), MultiFramedRTPSource::doGetNextFrame1(), MP3FileSource::doGetNextFrame1(), ADUFromMP3Source::doGetNextFrame1(), doInviteStateMachine(), ByteStreamFileSource::doReadFromFile(), MPEG1or2VideoRTPSink::doSpecialFrameHandling(), MP3ADURTPSink::doSpecialFrameHandling(), H263plusVideoRTPSink::doSpecialFrameHandling(), ByteStreamFileSource::doStopGettingFrames(), BasicUDPSource::doStopGettingFrames(), SegmentQueue::enqueueNewSegment(), StreamParser::ensureValidBytes1(), MediaSubsession::env(), SubsessionIOState::envir(), RTSPServer::RTSPClientSession::envir(), RTSPOverHTTPServer::HTTPClientConnection::envir(), RTPInterface::envir(), AVISubsessionIOState::envir(), ServerMediaSession::generateSDPDescription(), RTPSource::getAttributes(), MP3FileSource::getAttributes(), MP3ADUTranscoder::getAttributes(), MediaSource::getAttributes(), MPEG4VideoFileServerMediaSubsession::getAuxSDPLine(), getMPEG1or2TimeCode(), FramedSource::getNextFrame(), getOptions(), DVVideoStreamFramer::getProfile(), getResponse(), getResponseCode(), getSDPDescription(), OnDemandServerMediaSubsession::getStreamParameters(), RTSPClient::handleGET_PARAMETERResponse(), RTSPClient::handleIncomingRequest(), RTSPClient::handlePLAYResponse(), RTSPClient::handleRequestError(), RTSPClient::handleResponseBytes(), RTSPClient::handleSETUPResponse(), RTSPServer::incomingConnectionHandler1(), RTSPOverHTTPServer::incomingConnectionHandler1(), RTSPClient::incomingDataHandler1(), RTCPInstance::incomingReportHandler1(), MP3FileSource::initializeStream(), MediaSession::initializeWithSDP(), MediaSession::initiateByMediaType(), invite1(), DynamicRTSPServer::lookupServerMediaSession(), MPEG4GenericRTPSource::MPEG4GenericRTPSource(), MPEG1or2FileServerDemux::newElementaryStream(), MPEG1or2Demux::newElementaryStream(), MPEG4GenericBufferedPacket::nextEnclosedFrameSize(), AMRBufferedPacket::nextEnclosedFrameSize(), RTSPClient::openConnection(), MPEG2TransportStreamIndexFile::openFid(), MPEG2IFrameIndexFromTransportStream::parseFrame(), AC3AudioStreamParser::parseFrame(), MPEGProgramStreamParser::parsePackHeader(), MPEGProgramStreamParser::parsePESPacket(), parseResponseCode(), MediaSession::parseSDPLine(), MPEG1or2VideoStreamParser::parseSlice(), MPEGProgramStreamParser::parseSystemHeader(), MPEG4VideoStreamParser::parseVideoObjectLayer(), MPEG4VideoStreamParser::parseVideoObjectPlane(), MPEG4VideoStreamParser::parseVisualObject(), AC3AudioRTPSource::processSpecialHeader(), processURL(), AC3AudioStreamParser::readAndSaveAFrame(), MPEG1or2Demux::registerReadInterest(), RTCPInstance::reschedule(), RTSPClient::resendCommand(), RTSPClient::resetTCPSockets(), RTSPClient::responseHandlerForHTTP_GET1(), RTSPServer::rtspURLPrefix(), RTCPInstance::schedule(), OnDemandServerMediaSubsession::sdpLines(), sendACK(), sendBYE(), sendINVITE(), MultiFramedRTPSink::sendPacketIfNecessary(), sendRequest(), RTSPClient::sendRequest(), DarwinInjector::setDestination(), RTSPClient::setupHTTPTunneling1(), QuickTimeFileSink::setWord(), AVIFileSink::setWord(), QuickTimeFileSink::setWord64(), SIPClient(), AMRAudioRTPSink::sourceIsCompatibleWithUs(), QuickTimeFileSink::startPlaying(), StreamState::startPlaying(), MediaSink::startPlaying(), AVIFileSink::startPlaying(), startPlayingSession(), PassiveServerMediaSubsession::startStream(), MediaSink::stopPlaying(), tearDownSession(), timerAHandler(), timerBHandler(), timerDHandler(), ClientTrickPlayState::updateStateOnScaleChange(), MPEG2TransportStreamFramer::updateTSPacketDurationEstimate(), BasicUDPSource::~BasicUDPSource(), ByteStreamFileSource::~ByteStreamFileSource(), RTSPOverHTTPServer::HTTPClientConnection::~HTTPClientConnection(), and RTSPServer::~RTSPServer().

00059 {return fEnviron;}

char const* Medium::name (  )  const [inline, inherited]

Definition at line 61 of file Media.hh.

References Medium::fMediumName.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), Medium::close(), MP3ADUTranscoder::createNew(), MP3FromADUSource::createNew(), ADUFromMP3Source::createNew(), and MP3FileSource::initializeStream().

00061 {return fMediumName;}

Boolean Medium::isSource (  )  const [virtual, inherited]

Reimplemented in MediaSource.

Definition at line 86 of file Media.cpp.

References False.

Referenced by MediaSource::lookupByName().

00086                                {
00087   return False; // default implementation
00088 }

Boolean Medium::isSink (  )  const [virtual, inherited]

Reimplemented in MediaSink.

Definition at line 90 of file Media.cpp.

References False.

Referenced by MediaSink::lookupByName().

00090                              {
00091   return False; // default implementation
00092 }

Boolean Medium::isRTCPInstance (  )  const [virtual, inherited]

Reimplemented in RTCPInstance.

Definition at line 94 of file Media.cpp.

References False.

Referenced by RTCPInstance::lookupByName().

00094                                      {
00095   return False; // default implementation
00096 }

Boolean Medium::isRTSPClient (  )  const [virtual, inherited]

Reimplemented in RTSPClient.

Definition at line 98 of file Media.cpp.

References False.

Referenced by RTSPClient::lookupByName().

00098                                    {
00099   return False; // default implementation
00100 }

Boolean Medium::isRTSPServer (  )  const [virtual, inherited]

Reimplemented in RTSPServer.

Definition at line 102 of file Media.cpp.

References False.

Referenced by RTSPServer::lookupByName().

00102                                    {
00103   return False; // default implementation
00104 }

Boolean Medium::isMediaSession (  )  const [virtual, inherited]

Reimplemented in MediaSession.

Definition at line 106 of file Media.cpp.

References False.

Referenced by MediaSession::lookupByName().

00106                                      {
00107   return False; // default implementation
00108 }

Boolean Medium::isServerMediaSession (  )  const [virtual, inherited]

Reimplemented in ServerMediaSession.

Definition at line 110 of file Media.cpp.

References False.

Referenced by ServerMediaSession::lookupByName().

00110                                            {
00111   return False; // default implementation
00112 }

Boolean Medium::isDarwinInjector (  )  const [virtual, inherited]

Reimplemented in DarwinInjector.

Definition at line 114 of file Media.cpp.

References False.

Referenced by DarwinInjector::lookupByName().

00114                                        {
00115   return False; // default implementation
00116 }

TaskToken& Medium::nextTask (  )  [inline, protected, inherited]

Definition at line 77 of file Media.hh.

References Medium::fNextTask.

Referenced by BasicUDPSink::afterGettingFrame1(), MPEG4VideoFileServerMediaSubsession::afterPlayingDummy1(), MPEG4VideoFileServerMediaSubsession::checkForAuxSDPLine1(), WAVAudioFileSource::doGetNextFrame(), MP3FileSource::doGetNextFrame(), AMRAudioFileSource::doGetNextFrame(), ADTSAudioFileSource::doGetNextFrame(), MultiFramedRTPSource::doGetNextFrame1(), ByteStreamFileSource::doReadFromFile(), RTCPInstance::reschedule(), RTCPInstance::schedule(), MultiFramedRTPSink::sendPacketIfNecessary(), and MediaSink::stopPlaying().

00077                         {
00078         return fNextTask;
00079   }


Field Documentation

TaskToken SIPClient::fTimerA [private]

Definition at line 91 of file SIPClient.hh.

Referenced by doInviteStateMachine(), and invite1().

TaskToken SIPClient::fTimerB [private]

Definition at line 91 of file SIPClient.hh.

Referenced by doInviteStateMachine(), and invite1().

TaskToken SIPClient::fTimerD [private]

Definition at line 91 of file SIPClient.hh.

Referenced by doInviteStateMachine(), and invite1().

unsigned const SIPClient::fT1 [private]

Definition at line 95 of file SIPClient.hh.

Referenced by invite1(), and timerBHandler().

unsigned SIPClient::fTimerALen [private]

Definition at line 96 of file SIPClient.hh.

Referenced by doInviteStateMachine(), invite1(), and timerAHandler().

unsigned SIPClient::fTimerACount [private]

Definition at line 97 of file SIPClient.hh.

Referenced by invite1(), and timerAHandler().

unsigned char SIPClient::fDesiredAudioRTPPayloadFormat [private]

Definition at line 109 of file SIPClient.hh.

Referenced by invite1().

char* SIPClient::fMIMESubtype [private]

Definition at line 110 of file SIPClient.hh.

Referenced by invite1(), SIPClient(), and ~SIPClient().

unsigned SIPClient::fMIMESubtypeSize [private]

Definition at line 111 of file SIPClient.hh.

Referenced by invite1(), and SIPClient().

int SIPClient::fVerbosityLevel [private]

Definition at line 112 of file SIPClient.hh.

Referenced by getResponseCode(), sendRequest(), timerAHandler(), timerBHandler(), and timerDHandler().

unsigned SIPClient::fCSeq [private]

Definition at line 113 of file SIPClient.hh.

Referenced by invite1(), sendACK(), and sendBYE().

char const* SIPClient::fApplicationName [private]

Definition at line 114 of file SIPClient.hh.

Referenced by invite1(), reset(), SIPClient(), and ~SIPClient().

unsigned SIPClient::fApplicationNameSize [private]

Definition at line 115 of file SIPClient.hh.

Referenced by invite1(), and SIPClient().

char const* SIPClient::fOurAddressStr [private]

Definition at line 116 of file SIPClient.hh.

Referenced by invite1(), sendACK(), sendBYE(), SIPClient(), and ~SIPClient().

unsigned SIPClient::fOurAddressStrSize [private]

Definition at line 117 of file SIPClient.hh.

Referenced by invite1(), sendACK(), sendBYE(), and SIPClient().

portNumBits SIPClient::fOurPortNum [private]

Definition at line 118 of file SIPClient.hh.

Referenced by invite1(), sendACK(), sendBYE(), and SIPClient().

Groupsock* SIPClient::fOurSocket [private]

Definition at line 119 of file SIPClient.hh.

Referenced by getResponse(), getResponseCode(), invite1(), processURL(), sendRequest(), setProxyServer(), SIPClient(), and ~SIPClient().

char* SIPClient::fUserAgentHeaderStr [private]

Definition at line 120 of file SIPClient.hh.

Referenced by invite1(), SIPClient(), and ~SIPClient().

unsigned SIPClient::fUserAgentHeaderStrSize [private]

Definition at line 121 of file SIPClient.hh.

Referenced by invite1(), and SIPClient().

char const* SIPClient::fURL [private]

Definition at line 124 of file SIPClient.hh.

Referenced by invite(), invite1(), reset(), sendACK(), and sendBYE().

unsigned SIPClient::fURLSize [private]

Definition at line 125 of file SIPClient.hh.

Referenced by invite(), invite1(), reset(), sendACK(), and sendBYE().

struct in_addr SIPClient::fServerAddress [read, private]

Definition at line 126 of file SIPClient.hh.

Referenced by processURL(), reset(), and setProxyServer().

portNumBits SIPClient::fServerPortNum [private]

Definition at line 127 of file SIPClient.hh.

Referenced by processURL(), reset(), and setProxyServer().

portNumBits SIPClient::fClientStartPortNum [private]

Definition at line 128 of file SIPClient.hh.

Referenced by invite1(), and setClientStartPortNum().

unsigned SIPClient::fCallId [private]

Definition at line 129 of file SIPClient.hh.

Referenced by invite(), invite1(), sendACK(), and sendBYE().

unsigned SIPClient::fFromTag [private]

Definition at line 129 of file SIPClient.hh.

Referenced by invite(), invite1(), sendACK(), and sendBYE().

char const* SIPClient::fToTagStr [private]

Definition at line 130 of file SIPClient.hh.

Referenced by getResponseCode(), reset(), sendACK(), and sendBYE().

unsigned SIPClient::fToTagStrSize [private]

Definition at line 131 of file SIPClient.hh.

Referenced by getResponseCode(), reset(), sendACK(), and sendBYE().

Authenticator SIPClient::fValidAuthenticator [private]

Definition at line 132 of file SIPClient.hh.

Referenced by invite1(), inviteWithPassword(), and reset().

char const* SIPClient::fUserName [private]

Definition at line 133 of file SIPClient.hh.

Referenced by invite1(), inviteWithPassword(), reset(), sendACK(), and sendBYE().

unsigned SIPClient::fUserNameSize [private]

Definition at line 134 of file SIPClient.hh.

Referenced by invite1(), inviteWithPassword(), reset(), sendACK(), and sendBYE().

char* SIPClient::fInviteSDPDescription [private]

Definition at line 136 of file SIPClient.hh.

Referenced by doInviteStateTerminated(), invite1(), and reset().

char* SIPClient::fInviteCmd [private]

Definition at line 137 of file SIPClient.hh.

Referenced by invite1(), reset(), and sendINVITE().

unsigned SIPClient::fInviteCmdSize [private]

Definition at line 138 of file SIPClient.hh.

Referenced by invite1(), reset(), and sendINVITE().

Authenticator* SIPClient::fWorkingAuthenticator [private]

Definition at line 139 of file SIPClient.hh.

Referenced by getResponseCode(), invite1(), and reset().

inviteClientState SIPClient::fInviteClientState [private]

Definition at line 140 of file SIPClient.hh.

Referenced by doInviteStateMachine(), doInviteStateTerminated(), and invite1().

char SIPClient::fEventLoopStopFlag [private]

Definition at line 141 of file SIPClient.hh.

Referenced by doInviteStateTerminated(), and invite1().


The documentation for this class was generated from the following files:
Generated on Fri Sep 3 02:37:49 2010 for live by  doxygen 1.5.2