/* * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2008 Apple Inc. All Rights Reserved. * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ * */ /* File: RelaySession.cpp Contains: Implementation of object defined in RelaySession.h. */ #include "RelaySession.h" #include "QTSSModuleUtils.h" #include "SocketUtils.h" #include "../../revision.h" static StrPtrLen sUDPSourceStr("udp_source"); static StrPtrLen sRTSPSourceStr("rtsp_source"); static StrPtrLen sAnnouncedSourceStr("announced_source"); static StrPtrLen sEmptyStr(""); static char* sRelaySessionObjectName = "relay_session"; static char* sRelayNameName = "relay_name"; static char* sSourceTypeName = "source_type"; static char* sSourceIPAddrName = "source_ip_addr"; static char* sSourceInIPAddrName = "source_in_ip_addr"; static char* sSourceUDPPortsName = "source_udp_ports"; static char* sSourceRTSPPortName = "source_rtsp_port"; static char* sSourceURLName = "source_url"; static char* sSourceUsernameName = "source_username"; static char* sSourcePasswordName = "source_password"; static char* sSourceTTLName = "source_ttl"; static char* sRelayOutputObjectName = "relay_output"; QTSS_Object RelaySession::relayModuleAttributesObject; QTSS_ObjectType RelaySession::qtssRelaySessionObjectType; QTSS_AttributeID RelaySession::sRelaySessionObjectID = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sRelayName = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceType = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceIPAddr = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceInIPAddr = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceUDPPorts = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceRTSPPort = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceURL = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceUsername = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourcePassword = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sSourceTTL = qtssIllegalAttrID; QTSS_AttributeID RelaySession::sRelayOutputObject = qtssIllegalAttrID; char RelaySession::sRelayUserAgent[20] = ""; void RelaySession::Register() { qtssRelaySessionObjectType = 0; // create relay session object type (void)QTSS_CreateObjectType(&qtssRelaySessionObjectType); // Add the static attributes to the qtssRelaySessionObjectType object (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sRelayNameName, NULL, qtssAttrDataTypeCharArray); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sRelayNameName, &sRelayName); // relay name (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceTypeName, NULL, qtssAttrDataTypeCharArray); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceTypeName, &sSourceType); // source type (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceIPAddrName, NULL, qtssAttrDataTypeCharArray); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceIPAddrName, &sSourceIPAddr); // source addr (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceInIPAddrName, NULL, qtssAttrDataTypeCharArray); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceInIPAddrName, &sSourceInIPAddr); // interface addr (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceUDPPortsName, NULL, qtssAttrDataTypeUInt16); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceUDPPortsName, &sSourceUDPPorts); // udp ports (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceRTSPPortName, NULL, qtssAttrDataTypeUInt16); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceRTSPPortName, &sSourceRTSPPort); // rtsp port (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceURLName, NULL, qtssAttrDataTypeCharArray); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceURLName, &sSourceURL); // url (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceUsernameName, NULL, qtssAttrDataTypeCharArray); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceUsernameName, &sSourceUsername); // username (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourcePasswordName, NULL, qtssAttrDataTypeCharArray); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourcePasswordName, &sSourcePassword); // password (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sSourceTTLName, NULL, qtssAttrDataTypeUInt16); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sSourceTTLName, &sSourceTTL); // ttl (void)QTSS_AddStaticAttribute(qtssRelaySessionObjectType, sRelayOutputObjectName, NULL, qtssAttrDataTypeQTSS_Object); (void)QTSS_IDForAttr(qtssRelaySessionObjectType, sRelayOutputObjectName, &sRelayOutputObject); // relay output //char* strEnd = NULL; char* relayStr = "QTSS_Relay/"; //kVersionString is changed now -- it doesn't contain any spaces or the build number //strEnd = strchr(kVersionString, ' '); //Assert(strEnd != NULL); #ifndef __Win32__ //qtss_snprintf(sRelayUserAgent, ::strlen(relayStr) + (strEnd - kVersionString) + 1, "%s/%s", relayStr, kVersionString); qtss_snprintf(sRelayUserAgent, ::strlen(relayStr) + ::strlen(kVersionString) + 1, "%s%s", relayStr, kVersionString); #else //_snprintf(sRelayUserAgent, ::strlen(relayStr) + (strEnd - kVersionString) + 1, "%s/%s", relayStr, kVersionString); _snprintf(sRelayUserAgent, ::strlen(relayStr) + ::strlen(kVersionString) + 1, "%s%s", relayStr, kVersionString); #endif } void RelaySession::Initialize(QTSS_Object inRelayModuleAttributesObject) { ReflectorSession::Initialize(); if (inRelayModuleAttributesObject != NULL) { relayModuleAttributesObject = inRelayModuleAttributesObject; sRelaySessionObjectID = QTSSModuleUtils::CreateAttribute(inRelayModuleAttributesObject, sRelaySessionObjectName, qtssAttrDataTypeQTSS_Object, NULL, 0); } } QTSS_Error RelaySession::SetupRelaySession(SourceInfo* inInfo) { QTSS_Error theErr = QTSS_NoErr; theErr = this->SetupReflectorSession(inInfo, NULL); if (theErr != QTSS_NoErr) return theErr; // create the reflector session object for this session UInt32 outIndex = 0; fRelaySessionObject = NULL; theErr = QTSS_LockObject(relayModuleAttributesObject); Assert(theErr == QTSS_NoErr); theErr = QTSS_CreateObjectValue (relayModuleAttributesObject , sRelaySessionObjectID, qtssRelaySessionObjectType, &outIndex, &fRelaySessionObject); Assert(theErr == QTSS_NoErr); if (fRelaySessionObject == NULL) return theErr; // set the values for all the static attributes in this session char* relayName = inInfo->Name(); // name of the relay if (relayName != NULL) theErr = QTSS_SetValue (fRelaySessionObject, sRelayName, 0, (void*)relayName, ::strlen(relayName)); else theErr = QTSS_SetValue (fRelaySessionObject, sRelayName, 0, (void*)sEmptyStr.Ptr, sEmptyStr.Len); Assert(theErr == QTSS_NoErr); StrPtrLen sourceStr; // type of source if (inInfo->IsRTSPSourceInfo()) { if (((RTSPSourceInfo*)inInfo)->IsAnnounce()) sourceStr.Set(sAnnouncedSourceStr.Ptr, sAnnouncedSourceStr.Len); else sourceStr.Set(sRTSPSourceStr.Ptr, sRTSPSourceStr.Len); } else sourceStr.Set(sUDPSourceStr.Ptr, sUDPSourceStr.Len); theErr = QTSS_SetValue (fRelaySessionObject, sSourceType, 0, (void*)sourceStr.Ptr, sourceStr.Len); Assert(theErr == QTSS_NoErr); char theIPAddrBuf[20]; StrPtrLen theIPAddr(theIPAddrBuf, 20); struct in_addr theSrcAddr; // source ip address theSrcAddr.s_addr = htonl(inInfo->GetStreamInfo(0)->fSrcIPAddr); SocketUtils::ConvertAddrToString(theSrcAddr, &theIPAddr); theErr = QTSS_SetValue (fRelaySessionObject, sSourceIPAddr, 0, (void*)theIPAddr.Ptr, theIPAddr.Len); Assert(theErr == QTSS_NoErr); struct in_addr theDestAddr; // dest (of source) ip address theDestAddr.s_addr = htonl(inInfo->GetStreamInfo(0)->fDestIPAddr); SocketUtils::ConvertAddrToString(theDestAddr, &theIPAddr); theErr = QTSS_SetValue (fRelaySessionObject, sSourceInIPAddr, 0, (void*)theIPAddr.Ptr, theIPAddr.Len); Assert(theErr == QTSS_NoErr); for (UInt32 index = 0; index < (inInfo->GetNumStreams()); index++) // source udp ports { UInt16 udpPort = inInfo->GetStreamInfo(index)->fPort; theErr = QTSS_SetValue (fRelaySessionObject, sSourceUDPPorts, index, &udpPort, sizeof(udpPort)); Assert(theErr == QTSS_NoErr); } if (inInfo->IsRTSPSourceInfo()) { RTSPSourceInfo* rtspInfo = (RTSPSourceInfo*)inInfo; if (!rtspInfo->IsAnnounce()) { UInt16 rtspPort = (UInt16) rtspInfo->GetHostPort(); char* username = rtspInfo->GetUsername(); char* password = rtspInfo->GetPassword(); theErr = QTSS_SetValue (fRelaySessionObject, sSourceRTSPPort, 0, &rtspPort, sizeof(rtspPort)); // source rtsp port Assert(theErr == QTSS_NoErr); theErr = QTSS_SetValue (fRelaySessionObject, sSourceUsername, 0, username, sizeof(username)); // source username Assert(theErr == QTSS_NoErr); theErr = QTSS_SetValue (fRelaySessionObject, sSourcePassword, 0, password, sizeof(password)); // source password Assert(theErr == QTSS_NoErr); } char* url = rtspInfo->GetSourceURL(); theErr = QTSS_SetValue (fRelaySessionObject, sSourceURL, 0, url, ::strlen(url)); Assert(theErr == QTSS_NoErr); // source url } UInt16 ttl = inInfo->GetStreamInfo(0)->fTimeToLive; theErr = QTSS_SetValue (fRelaySessionObject, sSourceTTL, 0, &ttl, sizeof(ttl)); // source ttl Assert(theErr == QTSS_NoErr); theErr = QTSS_UnlockObject(relayModuleAttributesObject); Assert(theErr == QTSS_NoErr); return QTSS_NoErr; } RelaySession::~RelaySession() { QTSS_Object sessionObject; UInt32 len = sizeof(QTSS_Object); for (int x = 0; QTSS_GetValue(relayModuleAttributesObject, sRelaySessionObjectID, x, &sessionObject, &len) == QTSS_NoErr; x++) { Assert(sessionObject != NULL); Assert(len == sizeof(QTSS_Object)); if (sessionObject == fRelaySessionObject) { (void)QTSS_RemoveValue(relayModuleAttributesObject, sRelaySessionObjectID, x); break; } } }