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

Friends

class MediaLookupTable

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(), 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(AddressString(ourAddress).val());
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         << fOurAddressStr << ": "
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           << fOurAddressStr << ", 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_random32(), 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_random32();
00185   fFromTag = our_random32();
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(), and strDup().

Referenced by getSDPDescription(), and invite().

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

Boolean SIPClient::sendACK (  ) 

Definition at line 632 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().

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

Boolean SIPClient::sendBYE (  ) 

Definition at line 672 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().

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

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

Definition at line 734 of file SIPClient.cpp.

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

Referenced by processURL().

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

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

Definition at line 809 of file SIPClient.cpp.

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

Referenced by invite().

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

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 713 of file SIPClient.cpp.

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

Referenced by invite().

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

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 850 of file SIPClient.cpp.

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

Referenced by invite1().

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

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

Definition at line 874 of file SIPClient.cpp.

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

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

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

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 885 of file SIPClient.cpp.

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

Referenced by getResponseCode().

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

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

Definition at line 936 of file SIPClient.cpp.

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

Referenced by getResponseCode().

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

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

Definition at line 41 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().

00042                                                          {
00043   resultMedium = MediaLookupTable::ourMedia(env)->lookup(mediumName);
00044   if (resultMedium == NULL) {
00045     env.setResultMsg("Medium ", mediumName, " does not exist");
00046     return False;
00047   }
00048 
00049   return True;
00050 }

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

Definition at line 52 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(), MP3FileSource::createNew(), AVIFileSink::createNew(), AMRAudioRTPSource::createNew(), WAVAudioFileServerMediaSubsession::createNewStreamSource(), MPEG1or2DemuxedServerMediaSubsession::createNewStreamSource(), MediaSubsession::deInitiate(), RTSPServerSupportingHTTPStreaming::RTSPClientSessionSupportingHTTPStreaming::handleHTTPCmd_StreamingGET(), MediaSubsession::initiate(), MPEG1or2ProgramStreamFileDuration(), MPEG1or2Demux::noteElementaryStreamDeletion(), ByteStreamMultiFileSource::onSourceClosure1(), StreamState::reclaim(), RTSPServer::removeServerMediaSession(), OnDemandServerMediaSubsession::sdpLines(), shutdownStream(), subsessionAfterPlaying(), ClientTrickPlayState::updateStateOnScaleChange(), AMRDeinterleaver::~AMRDeinterleaver(), ByteStreamMultiFileSource::~ByteStreamMultiFileSource(), DarwinInjector::~DarwinInjector(), FramedFilter::~FramedFilter(), H264VideoRTPSink::~H264VideoRTPSink(), InputESSourceRecord::~InputESSourceRecord(), MatroskaFileParser::~MatroskaFileParser(), MatroskaFileServerDemux::~MatroskaFileServerDemux(), MPEG1or2Demux::~MPEG1or2Demux(), MPEG1or2FileServerDemux::~MPEG1or2FileServerDemux(), MPEG2TransportFileServerMediaSubsession::~MPEG2TransportFileServerMediaSubsession(), MPEG2TransportStreamFromPESSource::~MPEG2TransportStreamFromPESSource(), ProxyServerMediaSession::~ProxyServerMediaSession(), RTSPServerSupportingHTTPStreaming::RTSPClientSessionSupportingHTTPStreaming::~RTSPClientSessionSupportingHTTPStreaming(), ServerMediaSession::~ServerMediaSession(), ServerMediaSubsession::~ServerMediaSubsession(), StreamClientState::~StreamClientState(), StreamReplicator::~StreamReplicator(), and T140TextRTPSink::~T140TextRTPSink().

00052                                                           {
00053   MediaLookupTable::ourMedia(env)->remove(name);
00054 }

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

Definition at line 56 of file Media.cpp.

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

00056                                  {
00057   if (medium == NULL) return;
00058 
00059   close(medium->envir(), medium->name());
00060 }

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::afterGettingBytes1(), DummySink::afterGettingFrame(), TCPStreamSink::afterGettingFrame(), T140IdleFilter::afterGettingFrame(), FileSink::afterGettingFrame(), MultiFramedRTPSink::afterGettingFrame1(), InputESSourceRecord::afterGettingFrame1(), MPEG2TransportStreamFramer::afterGettingFrame1(), MPEG2IFrameIndexFromTransportStream::afterGettingFrame1(), H264VideoStreamDiscreteFramer::afterGettingFrame1(), BasicUDPSink::afterGettingFrame1(), MPEG4VideoFileServerMediaSubsession::afterPlayingDummy1(), H264VideoFileServerMediaSubsession::afterPlayingDummy1(), MPEG4VideoStreamParser::analyzeVOLHeader(), announceStream(), RTSPServer::RTSPClientSession::changeClientInputSocket(), MPEG4VideoFileServerMediaSubsession::checkForAuxSDPLine1(), H264VideoFileServerMediaSubsession::checkForAuxSDPLine1(), Medium::close(), ProxyServerMediaSubsession::closeStreamSource(), MPEG2IFrameIndexFromTransportStream::compactParseBuffer(), RTSPClient::connectionHandler1(), RTSPClient::connectToServer(), ProxyServerMediaSession::continueAfterDESCRIBE(), ProxyRTSPClient::continueAfterOPTIONS(), ProxyRTSPClient::continueAfterSETUP(), T140TextRTPSink::continuePlaying(), QuickTimeFileSink::continuePlaying(), H264VideoRTPSink::continuePlaying(), AVIFileSink::continuePlaying(), VP8VideoMatroskaFileServerMediaSubsession::createNewRTPSink(), VorbisAudioMatroskaFileServerMediaSubsession::createNewRTPSink(), T140TextMatroskaFileServerMediaSubsession::createNewRTPSink(), ProxyServerMediaSubsession::createNewRTPSink(), MPEG4VideoFileServerMediaSubsession::createNewRTPSink(), MPEG2TransportUDPServerMediaSubsession::createNewRTPSink(), MPEG2TransportFileServerMediaSubsession::createNewRTPSink(), MPEG1or2VideoFileServerMediaSubsession::createNewRTPSink(), MPEG1or2DemuxedServerMediaSubsession::createNewRTPSink(), MP3AudioFileServerMediaSubsession::createNewRTPSink(), H264VideoFileServerMediaSubsession::createNewRTPSink(), H263plusVideoFileServerMediaSubsession::createNewRTPSink(), DVVideoFileServerMediaSubsession::createNewRTPSink(), AMRAudioFileServerMediaSubsession::createNewRTPSink(), ADTSAudioFileServerMediaSubsession::createNewRTPSink(), AC3AudioMatroskaFileServerMediaSubsession::createNewRTPSink(), AC3AudioFileServerMediaSubsession::createNewRTPSink(), AACAudioMatroskaFileServerMediaSubsession::createNewRTPSink(), ProxyServerMediaSubsession::createNewStreamSource(), MPEG4VideoFileServerMediaSubsession::createNewStreamSource(), MPEG2TransportUDPServerMediaSubsession::createNewStreamSource(), MPEG2TransportFileServerMediaSubsession::createNewStreamSource(), MPEG1or2VideoFileServerMediaSubsession::createNewStreamSource(), MPEG1or2DemuxedServerMediaSubsession::createNewStreamSource(), MP3AudioFileServerMediaSubsession::createNewStreamSource(), H264VideoMatroskaFileServerMediaSubsession::createNewStreamSource(), H264VideoFileServerMediaSubsession::createNewStreamSource(), H263plusVideoFileServerMediaSubsession::createNewStreamSource(), DVVideoFileServerMediaSubsession::createNewStreamSource(), AMRAudioFileServerMediaSubsession::createNewStreamSource(), ADTSAudioFileServerMediaSubsession::createNewStreamSource(), AC3AudioFileServerMediaSubsession::createNewStreamSource(), AMRDeinterleavingBuffer::deliverIncomingFrame(), MPEG2IFrameIndexFromTransportStream::deliverIndexRecord(), SegmentQueue::dequeue(), DeviceSource::DeviceSource(), WAVAudioFileSource::doGetNextFrame(), T140IdleFilter::doGetNextFrame(), MPEG2IFrameIndexFromTransportStream::doGetNextFrame(), MP3FileSource::doGetNextFrame(), H264FUAFragmenter::doGetNextFrame(), ByteStreamMultiFileSource::doGetNextFrame(), ByteStreamFileSource::doGetNextFrame(), BasicUDPSource::doGetNextFrame(), AMRAudioFileSource::doGetNextFrame(), ADTSAudioFileSource::doGetNextFrame(), MultiFramedRTPSource::doGetNextFrame1(), MP3FileSource::doGetNextFrame1(), ADUFromMP3Source::doGetNextFrame1(), doInviteStateMachine(), WAVAudioFileSource::doReadFromFile(), ByteStreamFileSource::doReadFromFile(), MPEG1or2VideoRTPSink::doSpecialFrameHandling(), MP3ADURTPSink::doSpecialFrameHandling(), H263plusVideoRTPSink::doSpecialFrameHandling(), WAVAudioFileSource::doStopGettingFrames(), T140IdleFilter::doStopGettingFrames(), ByteStreamFileSource::doStopGettingFrames(), BasicUDPSource::doStopGettingFrames(), SegmentQueue::enqueueNewSegment(), StreamParser::ensureValidBytes1(), MediaSubsession::env(), SubsessionIOState::envir(), RTSPServer::RTSPClientSession::envir(), RTPInterface::envir(), AVISubsessionIOState::envir(), ServerMediaSession::generateSDPDescription(), RTPSource::getAttributes(), MP3FileSource::getAttributes(), MP3ADUTranscoder::getAttributes(), MediaSource::getAttributes(), MPEG4VideoFileServerMediaSubsession::getAuxSDPLine(), H264VideoFileServerMediaSubsession::getAuxSDPLine(), getMPEG1or2TimeCode(), FramedSource::getNextFrame(), getOptions(), DVVideoStreamFramer::getProfile(), getResponse(), getResponseCode(), getSDPDescription(), OnDemandServerMediaSubsession::getStreamParameters(), RTSPClient::handleGET_PARAMETERResponse(), RTSPServerSupportingHTTPStreaming::RTSPClientSessionSupportingHTTPStreaming::handleHTTPCmd_StreamingGET(), RTSPClient::handleIncomingRequest(), RTSPClient::handlePLAYResponse(), RTSPClient::handleRequestError(), RTSPClient::handleResponseBytes(), RTSPClient::handleSETUPResponse(), RTSPServer::incomingConnectionHandler(), RTSPClient::incomingDataHandler1(), RTCPInstance::incomingReportHandler1(), MP3FileSource::initializeStream(), MediaSession::initializeWithSDP(), MediaSession::initiateByMediaType(), invite1(), DynamicRTSPServer::lookupServerMediaSession(), MatroskaDemux::MatroskaDemux(), MatroskaFile::MatroskaFile(), MPEG4GenericRTPSource::MPEG4GenericRTPSource(), MatroskaDemux::newDemuxedTrack(), MPEG1or2FileServerDemux::newElementaryStream(), MPEG1or2Demux::newElementaryStream(), MPEG4GenericBufferedPacket::nextEnclosedFrameSize(), AMRBufferedPacket::nextEnclosedFrameSize(), T140IdleFilter::onSourceClosure(), RTSPClient::openConnection(), MPEG2TransportStreamIndexFile::openFid(), MPEG2IFrameIndexFromTransportStream::parseFrame(), AC3AudioStreamParser::parseFrame(), MPEGProgramStreamParser::parsePackHeader(), MPEGProgramStreamParser::parsePESPacket(), parseResponseCode(), MediaSession::parseSDPLine(), MPEG1or2VideoStreamParser::parseSlice(), MatroskaFileParser::parseStartOfFile(), MPEGProgramStreamParser::parseSystemHeader(), MPEG4VideoStreamParser::parseVideoObjectLayer(), MPEG4VideoStreamParser::parseVideoObjectPlane(), MPEG4VideoStreamParser::parseVisualObject(), TCPStreamSink::processBuffer(), processURL(), AC3AudioStreamParser::readAndSaveAFrame(), MPEG1or2Demux::registerReadInterest(), RTCPInstance::reschedule(), RTSPClient::resendCommand(), ProxyRTSPClient::reset(), RTSPClient::resetTCPSockets(), RTSPClient::responseHandlerForHTTP_GET1(), RTSPServer::rtspURLPrefix(), RTCPInstance::schedule(), ProxyRTSPClient::scheduleDESCRIBECommand(), ProxyRTSPClient::scheduleLivenessCommand(), OnDemandServerMediaSubsession::sdpLines(), sendACK(), sendBYE(), sendINVITE(), MultiFramedRTPSink::sendPacketIfNecessary(), sendRequest(), RTSPClient::sendRequest(), DarwinInjector::setDestination(), RTSPClient::setupHTTPTunneling1(), setupNextSubsession(), RTSPServer::setUpTunnelingOverHTTP(), QuickTimeFileSink::setWord(), AVIFileSink::setWord(), QuickTimeFileSink::setWord64(), shutdownStream(), SIPClient(), TCPStreamSink::socketWritableHandler1(), AMRAudioRTPSink::sourceIsCompatibleWithUs(), QuickTimeFileSink::startPlaying(), StreamState::startPlaying(), MediaSink::startPlaying(), AVIFileSink::startPlaying(), startPlayingSession(), PassiveServerMediaSubsession::startStream(), MediaSink::stopPlaying(), ProxyServerMediaSubsession::subsessionByeHandler(), tearDownSession(), timerAHandler(), timerBHandler(), timerDHandler(), ClientTrickPlayState::updateStateOnScaleChange(), MPEG2TransportStreamFramer::updateTSPacketDurationEstimate(), BasicUDPSource::~BasicUDPSource(), ByteStreamFileSource::~ByteStreamFileSource(), DeviceSource::~DeviceSource(), RTSPServer::~RTSPServer(), StreamClientState::~StreamClientState(), T140IdleFilter::~T140IdleFilter(), and WAVAudioFileSource::~WAVAudioFileSource().

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 62 of file Media.cpp.

References False.

Referenced by MediaSource::lookupByName().

00062                                {
00063   return False; // default implementation
00064 }

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

Reimplemented in MediaSink.

Definition at line 66 of file Media.cpp.

References False.

Referenced by MediaSink::lookupByName().

00066                              {
00067   return False; // default implementation
00068 }

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

Reimplemented in RTCPInstance.

Definition at line 70 of file Media.cpp.

References False.

Referenced by RTCPInstance::lookupByName().

00070                                      {
00071   return False; // default implementation
00072 }

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

Reimplemented in RTSPClient.

Definition at line 74 of file Media.cpp.

References False.

Referenced by RTSPClient::lookupByName().

00074                                    {
00075   return False; // default implementation
00076 }

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

Reimplemented in RTSPServer.

Definition at line 78 of file Media.cpp.

References False.

Referenced by RTSPServer::lookupByName().

00078                                    {
00079   return False; // default implementation
00080 }

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

Reimplemented in MediaSession.

Definition at line 82 of file Media.cpp.

References False.

Referenced by MediaSession::lookupByName().

00082                                      {
00083   return False; // default implementation
00084 }

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

Reimplemented in ServerMediaSession.

Definition at line 86 of file Media.cpp.

References False.

Referenced by ServerMediaSession::lookupByName().

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

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

Reimplemented in DarwinInjector.

Definition at line 90 of file Media.cpp.

References False.

Referenced by DarwinInjector::lookupByName().

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

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

Definition at line 78 of file Media.hh.

References Medium::fNextTask.

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

00078                         {
00079         return fNextTask;
00080   }


Friends And Related Function Documentation

friend class MediaLookupTable [friend, inherited]

Definition at line 74 of file Media.hh.


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 Thu May 17 07:16:21 2012 for live by  doxygen 1.5.2