testProgs/playSIP.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // Copyright (c) 1996-2014, Live Networks, Inc.  All rights reserved
00017 // A SIP client test program that opens a SIP URL argument,
00018 // and extracts the data from each incoming RTP stream.
00019 
00020 #include "playCommon.hh"
00021 #include "SIPClient.hh"
00022 
00023 static char* getLine(char* startOfLine) {
00024   // returns the start of the next line, or NULL if none
00025   for (char* ptr = startOfLine; *ptr != '\0'; ++ptr) {
00026     if (*ptr == '\r' || *ptr == '\n') {
00027       // We found the end of the line
00028       *ptr++ = '\0';
00029       if (*ptr == '\n') ++ptr;
00030       return ptr;
00031     }
00032   }
00033   
00034   return NULL;
00035 }
00036 
00037 SIPClient* ourSIPClient = NULL;
00038 Medium* createClient(UsageEnvironment& env, char const* /*url*/, int verbosityLevel, char const* applicationName) {
00039   // First, trim any directory prefixes from "applicationName":
00040   char const* suffix = &applicationName[strlen(applicationName)];
00041   while (suffix != applicationName) {
00042     if (*suffix == '/' || *suffix == '\\') {
00043       applicationName = ++suffix;
00044       break;
00045     }
00046     --suffix;
00047   }
00048 
00049   extern unsigned char desiredAudioRTPPayloadFormat;
00050   extern char* mimeSubtype;
00051   return ourSIPClient = SIPClient::createNew(env, desiredAudioRTPPayloadFormat, mimeSubtype, verbosityLevel, applicationName);
00052 }
00053 
00054 // The followign function is implemented, but is not used for "playSIP":
00055 void assignClient(Medium* /*client*/) {
00056 }
00057 
00058 void getOptions(RTSPClient::responseHandler* afterFunc) { 
00059   ourSIPClient->envir().setResultMsg("NOT SUPPORTED IN CLIENT");
00060   afterFunc(NULL, -1, strDup(ourSIPClient->envir().getResultMsg()));
00061 }
00062 
00063 void getSDPDescription(RTSPClient::responseHandler* afterFunc) {
00064   extern char* proxyServerName;
00065   if (proxyServerName != NULL) {
00066     // Tell the SIP client about the proxy:
00067     NetAddressList addresses(proxyServerName);
00068     if (addresses.numAddresses() == 0) {
00069       ourSIPClient->envir() << "Failed to find network address for \"" << proxyServerName << "\"\n";
00070     } else {
00071       NetAddress address = *(addresses.firstAddress());
00072       unsigned proxyServerAddress // later, allow for IPv6 #####
00073         = *(unsigned*)(address.data());
00074       extern unsigned short proxyServerPortNum;
00075       if (proxyServerPortNum == 0) proxyServerPortNum = 5060; // default
00076 
00077       ourSIPClient->setProxyServer(proxyServerAddress, proxyServerPortNum);
00078     }
00079   }
00080 
00081   extern unsigned short desiredPortNum;
00082   unsigned short clientStartPortNum = desiredPortNum;
00083   if (clientStartPortNum == 0) clientStartPortNum = 8000; // default
00084   ourSIPClient->setClientStartPortNum(clientStartPortNum);
00085 
00086   extern char const* streamURL;
00087   char const* username = ourAuthenticator == NULL ? NULL : ourAuthenticator->username();
00088   char const* password = ourAuthenticator == NULL ? NULL : ourAuthenticator->password();
00089   char* result;
00090   if (username != NULL && password != NULL) {
00091     result = ourSIPClient->inviteWithPassword(streamURL, username, password);
00092   } else {
00093     result = ourSIPClient->invite(streamURL);
00094   }
00095 
00096   int resultCode = result == NULL ? -1 : 0;
00097   afterFunc(NULL, resultCode, strDup(result));
00098 }
00099 
00100 void setupSubsession(MediaSubsession* subsession, Boolean /*streamUsingTCP*/, Boolean /*forceMulticastOnUnspecified*/,RTSPClient::responseHandler* afterFunc) {
00101   subsession->setSessionId("mumble"); // anything that's non-NULL will work
00102 
00104   // Parse the "Transport:" header parameters:
00105   // We do not send audio, but we need port for RTCP
00106   char* serverAddressStr;
00107   portNumBits serverPortNum;
00108   unsigned char rtpChannelId, rtcpChannelId;
00109 
00110   rtpChannelId = rtcpChannelId = 0xff;
00111   serverPortNum = 0;
00112   serverAddressStr = NULL;
00113 
00114   char* sdp = strDup(ourSIPClient->getInviteSdpReply());
00115 
00116   char* lineStart;
00117   char* nextLineStart = sdp;
00118   while (1) {
00119     lineStart = nextLineStart;
00120     if (lineStart == NULL) {
00121       break;
00122     }
00123     nextLineStart = getLine(lineStart);
00124 
00125     char* toTagStr = strDupSize(lineStart);
00126 
00127     if (sscanf(lineStart, "m=audio %[^/\r\n]", toTagStr) == 1) {
00128       sscanf(toTagStr, "%hu", &serverPortNum);
00129     } else if (sscanf(lineStart, "c=IN IP4 %[^/\r\n]", toTagStr) == 1) {
00130       serverAddressStr = strDup(toTagStr);
00131     }
00132     delete[] toTagStr;
00133   }
00134 
00135   if(sdp != NULL) {
00136     delete[] sdp;
00137   }
00138 
00139   delete[] subsession->connectionEndpointName();
00140   subsession->connectionEndpointName() = serverAddressStr;
00141   subsession->serverPortNum = serverPortNum;
00142   subsession->rtpChannelId = rtpChannelId;
00143   subsession->rtcpChannelId = rtcpChannelId;
00144 
00145   // Set the RTP and RTCP sockets' destination address and port from the information in the SETUP response (if present):
00146   netAddressBits destAddress = subsession->connectionEndpointAddress();
00147   if (destAddress != 0) {
00148     subsession->setDestinations(destAddress);
00149   }
00151 
00152   afterFunc(NULL, 0, NULL);
00153 }
00154 
00155 void startPlayingSession(MediaSession* /*session*/, double /*start*/, double /*end*/, float /*scale*/, RTSPClient::responseHandler* afterFunc) {
00156   if (ourSIPClient->sendACK()) {
00157     //##### This isn't quite right, because we should really be allowing
00158     //##### for the possibility of this ACK getting lost, by retransmitting
00159     //##### it *each time* we get a 2xx response from the server.
00160     afterFunc(NULL, 0, NULL);
00161   } else {
00162     afterFunc(NULL, -1, strDup(ourSIPClient->envir().getResultMsg()));
00163   }
00164 }
00165 void startPlayingSession(MediaSession* /*session*/, const char* /*start*/, const char* /*end*/, float /*scale*/, RTSPClient::responseHandler* afterFunc) {
00166         startPlayingSession(NULL,(double)0,(double)0,0,afterFunc);
00167 }
00168 
00169 void tearDownSession(MediaSession* /*session*/, RTSPClient::responseHandler* afterFunc) {
00170   if (ourSIPClient == NULL || ourSIPClient->sendBYE()) {
00171     afterFunc(NULL, 0, NULL);
00172   } else {
00173     afterFunc(NULL, -1, strDup(ourSIPClient->envir().getResultMsg()));
00174   }
00175 }
00176 
00177 void setUserAgentString(char const* userAgentString) {
00178   ourSIPClient->setUserAgentString(userAgentString);
00179 }
00180 
00181 Boolean allowProxyServers = True;
00182 Boolean controlConnectionUsesTCP = False;
00183 Boolean supportCodecSelection = True;
00184 char const* clientProtocolName = "SIP";

Generated on Tue Mar 25 14:35:36 2014 for live by  doxygen 1.5.2