/* * * @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: RTSPRequest3GPP.cpp Contains: Implementation of RTSPRequest3GPP class. */ #include "RTSPRequest3GPP.h" #include "RTSPProtocol.h" #include "QTSServerInterface.h" #include "RTSPSession.h" #include "RTSPSessionInterface.h" #include "StringParser.h" #include "StringTranslator.h" #include "OS.h" #include "OSMemory.h" #include "QTSS.h" #include "QTSSModuleUtils.h" #include "base64.h" #include "OSArrayObjectDeleter.h" #include "DateTranslator.h" #include "SocketUtils.h" void RateAdapationStreamDataFields::SetData(StrPtrLen *streamDataStr) { static StrPtrLen sSize("size"); static StrPtrLen sTargetTime("target-time"); static StrPtrLen sURL("url"); StringParser theStreamDataParser(streamDataStr); StrPtrLen url; theStreamDataParser.GetThru(&url, '=');//consume "url=" url.TrimWhitespace(); // fix if it is " url =" instead of "url=" if (false == url.NumEqualIgnoreCase(sURL.Ptr, sURL.Len)) return; //failed to find url= theStreamDataParser.GetThru(&url, ';');//consume "url=/asdlfjasdf/id=12;" { //get the stream id url component StringParser theURLParser(&url); while (theURLParser.GetThru(&url, '/')); //trim to the last path segment } { // get the id value StringParser theIDParser(&url); if (false == theIDParser.GetThru(&url, '='))//consume "id=12;" return; //failed to find '=' theIDParser.ConsumeWhitespace(); fTrackID = theIDParser.ConsumeInteger(); } StrPtrLen theDataStr; while ( theStreamDataParser.GetThru(&theDataStr,'=') ) //get the field name { theDataStr.TrimWhitespace(); if (theDataStr.NumEqualIgnoreCase(sSize.Ptr, sSize.Len)) // size= { theStreamDataParser.ConsumeWhitespace(); fBufferSizeBytes = theStreamDataParser.ConsumeInteger(); } if (theDataStr.NumEqualIgnoreCase(sTargetTime.Ptr, sTargetTime.Len)) // target-time = { theStreamDataParser.ConsumeWhitespace(); fTargetTimeMilli = theStreamDataParser.ConsumeInteger(); } theStreamDataParser.GetThru(&theDataStr,';'); //skip to next field } }; void RateAdapationStreamDataFields::CopyData(RateAdapationStreamDataFields* source) { if (NULL == source) return; fTrackID = source->GetSDPStreamID(); fBufferSizeBytes = source->GetBufferSizeBytes(); fTargetTimeMilli = source->GetTargetTimeMilliSec(); }; //----------- void LinkCharDataFields::ParseData( StrPtrLen &theDataStr, StringParser &theLinkCharDataParser) { static StrPtrLen sGBW("GBW"); static StrPtrLen sMBW("MBW"); static StrPtrLen sMTD("MTD"); if (theDataStr.NumEqualIgnoreCase(sGBW.Ptr, sGBW.Len)) // GBW= { theLinkCharDataParser.ConsumeWhitespace(); fGuaranteedKBitsPerSec = theLinkCharDataParser.ConsumeInteger(); return; } if (theDataStr.NumEqualIgnoreCase(sMBW.Ptr, sMBW.Len)) //MBW= { theLinkCharDataParser.ConsumeWhitespace(); fMaximumKBitsPerSec = theLinkCharDataParser.ConsumeInteger(); return; } if (theDataStr.NumEqualIgnoreCase(sMTD.Ptr, sMTD.Len)) //MBW= { theLinkCharDataParser.ConsumeWhitespace(); fMaximumTransferDelayMilliSec = theLinkCharDataParser.ConsumeInteger(); return; } } void LinkCharDataFields::SetData(StrPtrLen *streamDataStr) { static StrPtrLen sURL("url"); StringParser theLinkCharDataParser(streamDataStr); StrPtrLen url; theLinkCharDataParser.GetThru(&url, '=');//consume "url=" url.TrimWhitespace(); // fix if it is " url =" instead of "url=" if (false == url.NumEqualIgnoreCase(sURL.Ptr, sURL.Len)) return; //failed to find url= theLinkCharDataParser.ConsumeUntil(&url, ';');//consume "url=/asdlfjasdf;" if (!theLinkCharDataParser.Expect(';')) return; // no parameters url.TrimWhitespace(); fURL.Set(url.GetAsCString()); StrPtrLen theDataStr; while ( theLinkCharDataParser.GetThru(&theDataStr,'=') ) //get the field name { theDataStr.TrimWhitespace(); this->ParseData(theDataStr,theLinkCharDataParser); theLinkCharDataParser.GetThru(&theDataStr,';'); //skip to next field } }; void LinkCharDataFields::CopyData(LinkCharDataFields* source) { if (NULL == source) return; fURL.Set(source->GetURL()->GetAsCString()); fGuaranteedKBitsPerSec = source->GetGKbits(); fMaximumKBitsPerSec = source->GetMaxKBits(); fMaximumTransferDelayMilliSec = source->GetMaxDelayMilliSecs(); }; //-------- QTSSAttrInfoDict::AttrInfo RTSPRequest3GPP::sAttributes[] = { /*fields: fAttrName, fFuncPtr, fAttrDataType, fAttrPermission */ /* 0 */ { "qtss3GPPRequestEnabled", NULL, qtssAttrDataTypeBool16, qtssAttrModeRead | qtssAttrModeWrite | qtssAttrModePreempSafe }, /* 1 */ { "qtss3GPPRequestRateAdaptationStreamData", NULL, qtssAttrDataTypeCharArray, qtssAttrModeRead | qtssAttrModePreempSafe } }; void RTSPRequest3GPP::Initialize() { for (UInt32 x = 0; x < qtss3GPPRequestNumParams; x++) QTSSDictionaryMap::GetMap(QTSSDictionaryMap::k3GPPRequestDictIndex)-> SetAttribute(x, sAttributes[x].fAttrName, sAttributes[x].fFuncPtr, sAttributes[x].fAttrDataType, sAttributes[x].fAttrPermission); } RTSPRequest3GPP::RTSPRequest3GPP(Bool16 enabled) : QTSSDictionary(QTSSDictionaryMap::GetMap(QTSSDictionaryMap::k3GPPRequestDictIndex)), fEnabled (enabled),fIs3GPP(false), fHasRateAdaptation(false), fHasLinkChar(false) { this->SetVal(qtss3GPPRequestEnabled, &fEnabled, sizeof(fEnabled)); } QTSS_Error RTSPRequest3GPP::ParseAdpationHeader(QTSSDictionary* headerDictionaryPtr) { if (NULL == headerDictionaryPtr) { Assert(0); return -1; } if (!fEnabled) return QTSS_NoErr; StringParser theRateAdaptHeaderParser(headerDictionaryPtr->GetValue(qtss3GPPAdaptationHeader)); if (theRateAdaptHeaderParser.GetDataRemaining() == 0) return -1; fIs3GPP = true; fHasRateAdaptation = true; StrPtrLen theStreamData; UInt32 numValueIndex = 0; while (theRateAdaptHeaderParser.GetDataRemaining() != 0) { theRateAdaptHeaderParser.GetThru(&theStreamData, ','); theStreamData.TrimWhitespace(); (void) this->SetValuePtr(qtss3GPPRequestRateAdaptationStreamData,theStreamData.Ptr, theStreamData.Len, QTSSDictionary::kDontObeyReadOnly); numValueIndex++; } //this->ParseAdpationHeaderTest(); return QTSS_NoErr; } void RTSPRequest3GPP::ParseAdpationHeaderTest() { StrPtrLen dataStr; UInt32 numValues = this->GetNumValues(qtss3GPPRequestRateAdaptationStreamData); qtss_printf("RTSPRequest3GPP::ParseAdpationHeaderTest numValues =%lu\n", numValues); for (;numValues > 0; numValues --) { if(0 != this->GetValuePtr(qtss3GPPRequestRateAdaptationStreamData, numValues - 1, (void**) &dataStr.Ptr, &dataStr.Len, true)) qtss_printf("RTSPRequest3GPP::ParseAdpationHeaderTest err GetValuePtr(qtss3GPPRequestRateAdaptationStreamData\n"); dataStr.PrintStr("RTSPRequest3GPP::ParseAdpationHeaderTest qtss3GPPRequestRateAdaptationStreamData=[","]\n"); RateAdapationStreamDataFields fieldsParser; fieldsParser.SetData(&dataStr); fieldsParser.PrintData(NULL); } } QTSS_Error RTSPRequest3GPP::ParseLinkCharHeader(QTSSDictionary* headerDictionaryPtr) { if (NULL == headerDictionaryPtr) { Assert(0); return -1; } StrPtrLen* theLinkCharStr = headerDictionaryPtr->GetValue(qtss3GPPLinkCharHeader); if (theLinkCharStr == NULL) return -1; if (theLinkCharStr->Len == 0) return -1; fIs3GPP = true; fHasLinkChar = true; //this->ParseLinkCharHeaderTest(headerDictionaryPtr); return QTSS_NoErr; } void RTSPRequest3GPP::ParseLinkCharHeaderTest(QTSSDictionary* headerDictionaryPtr) { StrPtrLen dataStr; UInt32 numValues = headerDictionaryPtr->GetNumValues(qtss3GPPLinkCharHeader); qtss_printf("RTSPRequest3GPP::ParseLinkCharHeaderTest qtss3GPPLinkCharHeader numValues =%lu\n", numValues); //should be 1 for (;numValues > 0; numValues --) { if(0 != headerDictionaryPtr->GetValuePtr(qtss3GPPLinkCharHeader, numValues - 1, (void**) &dataStr.Ptr, &dataStr.Len, true)) qtss_printf("RTSPRequest3GPP::ParseLinkCharHeaderTest err GetValuePtr(qtss3GPPLinkCharHeader\n"); dataStr.PrintStr("RTSPRequest3GPP::ParseLinkCharHeaderTest qtss3GPPLinkCharHeader=[","]\n"); LinkCharDataFields fieldsParser; fieldsParser.SetData(&dataStr); fieldsParser.PrintData(NULL); } }