// This sends the HTTP response to the server that contains the RTSPtext Ref movie QTSS_Error SendTheResponse(QTSS_RTSPSessionObject theSession, QTSS_StreamRef stream, StrPtrLen& movie) { QTSS_Error err = QTSS_NoErr; char theMovieFile[512]; theMovieFile[sizeof(theMovieFile) -1] = 0; char tmp[600]; tmp[sizeof(tmp) -1] = 0; char tmp2[80]; tmp2[sizeof(tmp2) -1] = 0; UInt8 x1, x2, x3, x4; // send the HTTP reply header to the client err= QTSS_Write(stream, sResponseHeader, ::strlen(sResponseHeader), NULL, qtssWriteFlagsBufferData); if (err != QTSS_NoErr) return QTSS_NoErr; UInt32 ip4address = 0; UInt32 len = sizeof(ip4address); err = QTSS_GetValue(theSession, qtssRTSPSesLocalAddr, 0, &ip4address, &len); // Format the server IP address for building the RTSP address in the reply. x1 = (UInt8)((ip4address >> 24) & 0xff); x2 = (UInt8)((ip4address >> 16) & 0xff); x3 = (UInt8)((ip4address >> 8) & 0xff); x4 = (UInt8)((ip4address) & 0xff); if (movie.Len > sizeof(theMovieFile) -1 ) movie.Len = sizeof(theMovieFile) -1; ::memcpy(theMovieFile, movie.Ptr, movie.Len); theMovieFile[movie.Len] = '\0'; UInt16 port = sRTSPReplyPort; if (0 == port) { len = sizeof(port); err = QTSS_GetValue(theSession, qtssRTSPSesLocalPort, 0, &port, &len); } // construct the RTSP address reply string for the client. qtss_snprintf(tmp,sizeof(tmp) -1, "rtsptext\r\nrtsp://%d.%d.%d.%d:%d%s\r\n", x1,x2,x3,x4, port, theMovieFile); // send the 'Content-Length:' part of the HTTP reply qtss_snprintf(tmp2, sizeof(tmp2) -1, "Content-Length: %d\r\n\r\n", (int) ::strlen(tmp)); err = QTSS_Write(stream, tmp2, ::strlen(tmp2), NULL, qtssWriteFlagsBufferData); if (err != QTSS_NoErr) return QTSS_NoErr; // send the formatted RTSP reference part of the reply err = QTSS_Write(stream, tmp, ::strlen(tmp), NULL, qtssWriteFlagsBufferData); if (err != QTSS_NoErr) return QTSS_NoErr; // flush the pending write to the client. err = QTSS_Flush(stream); return err; }
Bool16 AuthenticateRequest(QTSS_StandardRTSP_Params* inParams, const char* pathBuff, const char* movieRootDir, StrPtrLen* ioRealmName, Bool16* foundUserPtr) { if (foundUserPtr) *foundUserPtr = false; if (ioRealmName) //Set Value to Empty for now use whatever is set by access file or the default { ioRealmName->Ptr[0] = '\0'; ioRealmName->Len = 0; } QTSS_Error theErr = QTSS_NoErr; char passwordBuff[kBuffLen]; StrPtrLen passwordStr(passwordBuff, kBuffLen -1); char nameBuff[kBuffLen]; StrPtrLen nameStr(nameBuff, kBuffLen -1); theErr = QTSS_GetValue (inParams->inRTSPRequest,qtssRTSPReqUserName,0, (void *) nameStr.Ptr, &nameStr.Len); if ( (QTSS_NoErr != theErr) || (nameStr.Len >= kBuffLen) ) { debug_printf("QTSSDSAuthModule:AuthenticateRequest() Username Error - %"_S32BITARG_"\n", theErr); return false; } theErr = QTSS_GetValue (inParams->inRTSPRequest,qtssRTSPReqUserPassword,0, (void *) passwordStr.Ptr, &passwordStr.Len); if ( (QTSS_NoErr != theErr) || (passwordStr.Len >= kBuffLen) ) { debug_printf("QTSSDSAuthModule:AuthenticateRequest() Password Error - %"_S32BITARG_"\n", theErr); return false; } nameBuff[nameStr.Len] = '\0'; passwordBuff[passwordStr.Len] = '\0'; // // Use the name and password to check access DSAccessChecker accessChecker; if ( !accessChecker.CheckPassword( nameBuff, passwordBuff) ) { return false; } if (foundUserPtr) *foundUserPtr = true; return true; }
QTSS_Error ProcessIncomingRTCPPacket(QTSS_RTCPProcess_Params* inParams) { ProxyClientInfo* theClient = NULL; UInt32 theLen = sizeof(theClient); QTSS_Error theErr = QTSS_GetValue(inParams->inClientSession, sProxyClientInfoAttr, 0, &theClient, &theLen); // // This role receives ALL RTCP packets. We are only interested in RTCP packets // sent to proxy sessions. So we figure this out based on whether there // is a ProxyClientInfo object in the client session if (theErr != QTSS_NoErr) return QTSS_NoErr; // // Let's forward this RTCP packet to the right upstream server ProxyDemuxerTask* theTask = theClient->GetDemuxerTaskForStream(inParams->inRTPStream); Assert(theTask != NULL); if (theTask == NULL) return QTSS_NoErr; // // Using the RTCP socket (SocketB) of the pair, send the packet to the origin server's // RTCP port (the port number stored is the RTP port) (void)theTask->GetSockets()->GetSocketB()-> SendTo(theTask->GetRemoteAddr(), theTask->GetOriginServerPort() + 1, inParams->inRTCPPacketData, inParams->inRTCPPacketDataLen); return QTSS_NoErr; }
Bool16 RTPSessionOutput::FilterPacket(QTSS_RTPStreamObject *theStreamPtr, StrPtrLen* inPacket) { UInt32* packetCountPtr = NULL; UInt32 theLen = 0; //see if we started sending and if so then just keep sending (reset on a play) QTSS_Error writeErr = QTSS_GetValuePtr(*theStreamPtr, sStreamPacketCountAttr, 0,(void**) &packetCountPtr,&theLen); if (writeErr == QTSS_NoErr && theLen > 0 && *packetCountPtr > 0) return false; Assert(theStreamPtr); Assert(inPacket); UInt16 seqnum = this->GetPacketSeqNumber(inPacket); UInt16 firstSeqNum = 0; theLen = sizeof(firstSeqNum); if ( QTSS_NoErr != QTSS_GetValue(*theStreamPtr, qtssRTPStrFirstSeqNumber, 0, &firstSeqNum, &theLen) ) return true; if ( seqnum < firstSeqNum ) { //printf("RTPSessionOutput::FilterPacket don't send packet = %u < first=%lu\n", seqnum, firstSeqNum); return true; } //printf("RTPSessionOutput::FilterPacket found first packet = %u \n", firstSeqNum); fPreFilter = false; return fPreFilter; }
HTTPSessionInterface::~HTTPSessionInterface() { // If the input socket is != output socket, the input socket was created dynamically if (fInputSocketP != fOutputSocketP) delete fInputSocketP; char remoteAddress[20] = { 0 }; StrPtrLen theIPAddressStr(remoteAddress, sizeof(remoteAddress)); QTSS_GetValue(this, EasyHTTPSesRemoteAddrStr, 0, static_cast<void*>(theIPAddressStr.Ptr), &theIPAddressStr.Len); char msgStr[2048] = { 0 }; switch (fSessionType) { case EasyCameraSession: this->UnRegDevSession(); qtss_snprintf(msgStr, sizeof(msgStr), "EasyCameraSession offline from ip[%s], device_serial[%s]", remoteAddress, device_->serial_.c_str()); break; case EasyNVRSession: this->UnRegDevSession(); qtss_snprintf(msgStr, sizeof(msgStr), "EasyNVRSession offline from ip[%s]", remoteAddress); break; case EasyHTTPSession: qtss_snprintf(msgStr, sizeof(msgStr), "EasyHTTPSession offline from ip[%s]", remoteAddress); break; default: qtss_snprintf(msgStr, sizeof(msgStr), "Unknown session offline from ip[%s]", remoteAddress); break; } QTSServerInterface::LogError(qtssMessageVerbosity, msgStr); }
UInt32 EasyAdmin_GetReflectBufferSecs() { UInt32 bufferSecs; UInt32 len = sizeof(UInt32); (void) QTSS_GetValue(sReflectorPrefs, easyPrefsHTTPServicePort, 0, (void*)&bufferSecs, &len); return bufferSecs; }
UInt16 EasyAdmin_GetHTTPServicePort() { UInt16 port; UInt32 len = sizeof(UInt16); (void) QTSS_GetValue(sServerPrefs, easyPrefsHTTPServicePort, 0, (void*)&port, &len); return port; }
UInt16 EasyAdmin_GetRTSPort() { UInt16 port; UInt32 len = sizeof(UInt16); (void) QTSS_GetValue(sServerPrefs, qtssPrefsRTSPPorts, 0, (void*)&port, &len); return port; }
Bool16 AcceptSession(QTSS_RTSPSessionObject inRTSPSession) { char remoteAddress[20] = {0}; StrPtrLen theClientIPAddressStr(remoteAddress,sizeof(remoteAddress)); QTSS_Error err = QTSS_GetValue(inRTSPSession, qtssRTSPSesRemoteAddrStr, 0, (void*)theClientIPAddressStr.Ptr, &theClientIPAddressStr.Len); if (err != QTSS_NoErr) return false; return AcceptAddress(&theClientIPAddressStr); }
Bool16 Is3GPPSession(QTSS_RTCPProcess_Params *inParams) { Bool16 is3GPP = false; UInt32 theLen = sizeof(is3GPP); (void)QTSS_GetValue(inParams->inClientSession, qtssCliSessIs3GPPSession, 0, (void*)&is3GPP, &theLen); return is3GPP; }
QTSS_Object QTSSModuleUtils::GetModuleAttributesObject(QTSS_ModuleObject inModObject) { QTSS_Object theAttributesObject = NULL; UInt32 theLen = sizeof(theAttributesObject); QTSS_Error theErr = QTSS_GetValue(inModObject, qtssModAttributes, 0, &theAttributesObject, &theLen); Assert(theErr == QTSS_NoErr); return theAttributesObject; }
kern_return_t GetServerStatusRec(QTSServerStatusRec* outServerStatus) { Assert(outServerStatus != NULL); ::memset(outServerStatus, 0, sizeof(QTSServerStatusRec)); QTSS_ServerState theState = qtssRunningState; UInt32 theSize = sizeof(theState); (void)QTSS_GetValue(sServer, qtssSvrState, 0, &theState, &theSize); //Convert the RTPServerInterface state to the server control's state if (sGracefulShutdownInProgress) outServerStatus->serverState = kSCGoingToShutDown; else if (theState == qtssRefusingConnectionsState) outServerStatus->serverState = kSCRefusingConnections; else if (theState == qtssStartingUpState) outServerStatus->serverState = kSCStartingUp; else if (theState == qtssShuttingDownState) outServerStatus->serverState = kSCShuttingDown; else outServerStatus->serverState = kSCRunning; outServerStatus->numCurrentConnections = 0; outServerStatus->connectionsSinceStartup = 0; outServerStatus->currentBandwidth = 0; outServerStatus->bytesSinceStartup = 0; //get the 4 key stats out of the RTP server theSize = sizeof(outServerStatus->numCurrentConnections); (void)QTSS_GetValue(sServer, qtssRTPSvrCurConn, 0, &outServerStatus->numCurrentConnections, &theSize); theSize = sizeof(outServerStatus->connectionsSinceStartup); (void)QTSS_GetValue(sServer, qtssRTPSvrTotalConn, 0, &outServerStatus->connectionsSinceStartup, &theSize); theSize = sizeof(outServerStatus->currentBandwidth); (void)QTSS_GetValue(sServer, qtssRTPSvrCurBandwidth, 0, &outServerStatus->currentBandwidth, &theSize); theSize = sizeof(outServerStatus->bytesSinceStartup); (void)QTSS_GetValue(sServer, qtssRTPSvrTotalBytes, 0, &outServerStatus->bytesSinceStartup, &theSize); return SCNoError; }
QTSS_Error RTPSessionOutput::RewriteRTCP(QTSS_RTPStreamObject *theStreamPtr, StrPtrLen* inPacketStrPtr, SInt64 *currentTimePtr, UInt32 inFlags, SInt64* packetLatenessInMSec, SInt64* timeToSendThisPacketAgain, UInt64* packetIDPtr, SInt64* arrivalTimeMSecPtr) { UInt32 theLen; SInt64 firstRTPCurrentTime = 0; theLen = sizeof(firstRTPCurrentTime); QTSS_GetValue(*theStreamPtr, sFirstRTPCurrentTimeAttr, 0, (void*)&firstRTPCurrentTime, &theLen); SInt64 firstRTPArrivalTime = 0; theLen = sizeof(firstRTPArrivalTime); QTSS_GetValue(*theStreamPtr, sFirstRTPArrivalTimeAttr, 0, (void*)&firstRTPArrivalTime, &theLen); UInt32 rtpTime = 0; theLen = sizeof(rtpTime); QTSS_GetValue(*theStreamPtr, sFirstRTPTimeStampAttr, 0, (void*)&rtpTime, &theLen); UInt32* theReport = (UInt32*) inPacketStrPtr->Ptr; theReport+=2; // point to the NTP time stamp SInt64* theNTPTimestampP = (SInt64*)theReport; *theNTPTimestampP = OS::HostToNetworkSInt64(OS::TimeMilli_To_1900Fixed64Secs(*currentTimePtr)); // time now UInt32 baseTimeStamp = 0; theLen = sizeof(baseTimeStamp); (void) QTSS_GetValue(*theStreamPtr, sBaseRTPTimeStampAttr, 0, (void*)&baseTimeStamp, &theLen); // we need a starting stream time that is synched UInt32 streamTimeScale = 0; theLen = sizeof(streamTimeScale); QTSS_GetValue(*theStreamPtr, qtssRTPStrTimescale, 0, (void *) &streamTimeScale, &theLen); SInt64 packetOffset = *currentTimePtr - fBaseArrivalTime; // real time that has passed packetOffset -= (firstRTPCurrentTime - firstRTPArrivalTime); // less the initial buffer delay for this stream if (packetOffset < 0) packetOffset = 0; Float64 rtpTimeFromStart = (Float64) packetOffset / (Float64) 1000.0; UInt32 rtpTimeFromStartInScale = (UInt32) (Float64) ((Float64) streamTimeScale * rtpTimeFromStart); //printf("rtptime offset time =%f in scale =%"_U32BITARG_"\n", rtpTimeFromStart, rtpTimeFromStartInScale ); theReport += 2; // point to the rtp time stamp of "now" synched and scaled in stream time *theReport = htonl(baseTimeStamp + rtpTimeFromStartInScale); theLen = sizeof(UInt32); UInt32 packetCount = 0; (void) QTSS_GetValue(*theStreamPtr, sStreamPacketCountAttr, 0, &packetCount,&theLen); theReport += 1; // point to the rtp packets sent *theReport = htonl(ntohl(*theReport) * 2); UInt32 byteCount = 0; (void) QTSS_GetValue(*theStreamPtr, sStreamByteCountAttr, 0, &byteCount,&theLen); theReport += 1; // point to the rtp payload bytes sent *theReport = htonl(ntohl(*theReport) * 2); return QTSS_NoErr; }
inline Bool16 GetRequestFlushState(QTSS_Filter_Params* inParams) { Bool16 result = false; UInt32 paramLen = sizeof(result); QTSS_Error err = QTSS_GetValue(inParams->inRTSPRequest, sFlushingID, 0, (void*)&result, ¶mLen); if (err != QTSS_NoErr) { paramLen = sizeof(result); result = false; //qtss_printf("no flush val so set to false session=%"_U32BITARG_" err =%"_S32BITARG_"\n",sSessID, err); err =QTSS_SetValue(inParams->inRTSPRequest, sFlushingID, 0, (void*)&result, paramLen); //qtss_printf("QTSS_SetValue flush session=%"_U32BITARG_" err =%"_S32BITARG_"\n",sSessID, err); } return result; }
kern_return_t GetRefuseConnections(QTSRefuseConnectionsRec* outRefuseConnections) { QTSS_ServerState theState = qtssRunningState; UInt32 theSize = sizeof(theState); (void)QTSS_GetValue(sServer, qtssSvrState, 0, &theState, &theSize); if (theState == qtssRefusingConnectionsState) outRefuseConnections->refuseConnections = true; else outRefuseConnections->refuseConnections = false; return SCNoError; }
QTSS_Error CountRequest( QTSS_RTSPRequestObject inRTSPRequest, QTSS_ClientSessionObject inClientSession, QTSS_RTSPSessionObject inRTSPSession, QTSS_CliSesClosingReason *inCloseReasonPtr ) { char urlBuf[256] = { 0 }; StrPtrLen url(urlBuf, 256 -1); (void)QTSS_GetValue(inClientSession, qtssCliSesFullURL, 0, url.Ptr, &url.Len); CountHit( url.Ptr ); WriteHitCountToFile(); return QTSS_NoErr; }
inline Bool16 GetRequestAuthenticatedState(QTSS_Filter_Params* inParams) { Bool16 result = false; UInt32 paramLen = sizeof(result); QTSS_Error err = QTSS_GetValue(inParams->inRTSPRequest, sAuthenticatedID, 0, (void*)&result, ¶mLen); if(err != QTSS_NoErr) { paramLen = sizeof(result); result = false; err =QTSS_SetValue(inParams->inRTSPRequest, sAuthenticatedID, 0, (void*)&result, paramLen); } return result; }
void PrintStatus(Bool16 printHeader) { char* thePrefStr = NULL; UInt32 theLen = 0; if ( printHeader ) { qtss_printf(" RTP-Conns RTSP-Conns HTTP-Conns kBits/Sec Pkts/Sec TotConn TotBytes TotPktsLost Time\n"); } (void)QTSS_GetValueAsString(sServer, qtssRTPSvrCurConn, 0, &thePrefStr); qtss_printf( "%11s", thePrefStr); delete [] thePrefStr; thePrefStr = NULL; (void)QTSS_GetValueAsString(sServer, qtssRTSPCurrentSessionCount, 0, &thePrefStr); qtss_printf( "%11s", thePrefStr); delete [] thePrefStr; thePrefStr = NULL; (void)QTSS_GetValueAsString(sServer, qtssRTSPHTTPCurrentSessionCount, 0, &thePrefStr); qtss_printf( "%11s", thePrefStr); delete [] thePrefStr; thePrefStr = NULL; UInt32 curBandwidth = 0; theLen = sizeof(curBandwidth); (void)QTSS_GetValue(sServer, qtssRTPSvrCurBandwidth, 0, &curBandwidth, &theLen); qtss_printf("%11"_U32BITARG_, curBandwidth/1024); (void)QTSS_GetValueAsString(sServer, qtssRTPSvrCurPackets, 0, &thePrefStr); qtss_printf( "%11s", thePrefStr); delete [] thePrefStr; thePrefStr = NULL; (void)QTSS_GetValueAsString(sServer, qtssRTPSvrTotalConn, 0, &thePrefStr); qtss_printf( "%11s", thePrefStr); delete [] thePrefStr; thePrefStr = NULL; UInt64 totalBytes = sServer->GetTotalRTPBytes(); char displayBuff[32] = ""; FormattedTotalBytesBuffer(displayBuff, sizeof(displayBuff),totalBytes); qtss_printf( "%17s", displayBuff); qtss_printf( "%11"_64BITARG_"u", sServer->GetTotalRTPPacketsLost()); char theDateBuffer[QTSSRollingLog::kMaxDateBufferSizeInBytes]; (void) QTSSRollingLog::FormatDate(theDateBuffer, false); qtss_printf( "%25s",theDateBuffer); qtss_printf( "\n"); }
void DoDescribeAddRequiredSDPLines2(QTSS_StandardRTSP_Params* inParams, ReflectorSession* theSession, QTSS_TimeVal modDate, ResizeableStringFormatter *editedSDP, StrPtrLen* theSDPPtr) { SDPContainer checkedSDPContainer; checkedSDPContainer.SetSDPBuffer( theSDPPtr ); if (!checkedSDPContainer.HasReqLines()) { if (!checkedSDPContainer.HasLineType('v')) { // add v line editedSDP->Put("v=0\r\n"); } if (!checkedSDPContainer.HasLineType('s')) { // add s line char* theSDPName = NULL; (void)QTSS_GetValueAsString(inParams->inRTSPRequest, qtssRTSPReqFilePath, 0, &theSDPName); QTSSCharArrayDeleter thePathStrDeleter(theSDPName); editedSDP->Put("s="); editedSDP->Put(theSDPName); editedSDP->PutEOL(); } if (!checkedSDPContainer.HasLineType('t')) { // add t line editedSDP->Put("t=0 0\r\n"); } if (!checkedSDPContainer.HasLineType('o')) { // add o line editedSDP->Put("o=broadcast_sdp "); char tempBuff[256]= ""; tempBuff[255] = 0; qtss_snprintf(tempBuff,sizeof(tempBuff) - 1, "%lu", (UInt64) theSession); editedSDP->Put(tempBuff); editedSDP->Put(" "); // modified date is in milliseconds. Convert to NTP seconds as recommended by rfc 2327 qtss_snprintf(tempBuff, sizeof(tempBuff) - 1, "%"_64BITARG_"d", (SInt64) (modDate/1000) + 2208988800LU); editedSDP->Put(tempBuff); editedSDP->Put(" IN IP4 "); UInt32 buffLen = sizeof(tempBuff) -1; (void)QTSS_GetValue(inParams->inClientSession, qtssCliSesHostName, 0, &tempBuff, &buffLen); editedSDP->Put(tempBuff, buffLen); editedSDP->PutEOL(); } } editedSDP->Put(*theSDPPtr); }
/* Content报文读取与解析 同步进行报文处理,构造回复报文 */ QTSS_Error CServiceSession::SetupRequest() { //解析请求报文 QTSS_Error theErr = fRequest->Parse(); if (theErr != QTSS_NoErr) return QTSS_BadArgument; QTSS_RTSPStatusCode statusCode = qtssSuccessOK; char *body = NULL; UInt32 bodySizeBytes = 0; //获取具体Content json数据部分 //1、获取json部分长度 StrPtrLen* lengthPtr = fRequest->GetHeaderValue(httpContentLengthHeader); StringParser theContentLenParser(lengthPtr); theContentLenParser.ConsumeWhitespace(); UInt32 content_length = theContentLenParser.ConsumeInteger(NULL); qtss_printf("ServiceSession read content-length:%d \n", content_length); if (content_length <= 0) return QTSS_BadArgument; // // Check for the existence of 2 attributes in the request: a pointer to our buffer for // the request body, and the current offset in that buffer. If these attributes exist, // then we've already been here for this request. If they don't exist, add them. UInt32 theBufferOffset = 0; char* theRequestBody = NULL; UInt32 theLen = 0; theLen = sizeof(theRequestBody); theErr = QTSS_GetValue(this, qtssEasySesContentBody, 0, &theRequestBody, &theLen); if (theErr != QTSS_NoErr) { // First time we've been here for this request. Create a buffer for the content body and // shove it in the request. theRequestBody = NEW char[content_length + 1]; memset(theRequestBody,0,content_length + 1); theLen = sizeof(theRequestBody); theErr = QTSS_SetValue(this, qtssEasySesContentBody, 0, &theRequestBody, theLen);// SetValue creates an internal copy. Assert(theErr == QTSS_NoErr); // Also store the offset in the buffer theLen = sizeof(theBufferOffset); theErr = QTSS_SetValue(this, qtssEasySesContentBodyOffset, 0, &theBufferOffset, theLen); Assert(theErr == QTSS_NoErr); }
void AddHistorySample() { // Retrieve the bandwidth & session count parameters from the server UInt32 theCurrentSessions = 0; UInt32 theSize = sizeof(theCurrentSessions); (void)QTSS_GetValue(sServer, qtssRTPSvrCurConn, 0, &theCurrentSessions, &theSize); UInt32 theCurrentBandwidth = 0; theSize = sizeof(theCurrentBandwidth); (void)QTSS_GetValue(sServer, qtssRTPSvrCurBandwidth, 0, &theCurrentBandwidth, &theSize); OSMutexLocker locker(sHistoryMutex); //keep track of maximums. if ((long)theCurrentBandwidth > sBandwidthHi) sBandwidthHi = theCurrentBandwidth; if ((long)theCurrentSessions > sConnectionHi) sConnectionHi = theCurrentSessions; //keep track of minimums. if (((long)theCurrentBandwidth < sBandwidthLo) || (sBandwidthLo == -1)) sBandwidthLo = theCurrentBandwidth; if (((long)theCurrentSessions < sConnectionLo) || (sConnectionLo == -1)) sConnectionLo = theCurrentSessions; //keep track of sum for eventual average //fBandwidthAvg += theCurrentBandwidth; <---this was overflowing at high bitrates //fConnectionAvg += theCurrentSessions; // fBandwidthAvg was overflowing, // so now we do it the ugly way sBandwidthAvg =(theCurrentBandwidth+(sBandwidthAvg*sSampleIndex))/(sSampleIndex+1); sConnectionAvg =(theCurrentSessions+(sConnectionAvg*sSampleIndex))/(sSampleIndex+1); sSampleIndex++; }
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; } } }
/** * For the given rtsp session, will return true if the client is in the configured * bypass list in the prefs, false if they aren't */ static Bool16 IsClientInBypassList(QTSS_RTSPSessionObject* theRTSPSession) { qtss_printf("QTSSIcecastAuthModule::IsClientInBypassList method start\n"); // don't forget to *deref the param! char remoteAddress[20] = {0}; StrPtrLen theClientIPAddressStr(remoteAddress,sizeof(remoteAddress)); QTSS_Error err = QTSS_GetValue(*theRTSPSession, qtssRTSPSesRemoteAddrStr, 0, (void*)theClientIPAddressStr.Ptr, &theClientIPAddressStr.Len); if (err != QTSS_NoErr) return false; if (QTSSModuleUtils::AddressInList(sModulePrefs, sIPBypassListID, &theClientIPAddressStr)) { qtss_printf("QTSSIcecastAuthModule::IsClientInBypassList client is in list\n"); return true; } else { qtss_printf("QTSSIcecastAuthModule::IsClientInBypassList client is NOT in list\n"); return false; } }
QTSS_Error DestroySession(QTSS_ClientSessionClosing_Params* inParams) { ProxyClientInfo* theClient = NULL; UInt32 theLen = sizeof(theClient); QTSS_Error theErr = QTSS_GetValue(inParams->inClientSession, sProxyClientInfoAttr, 0, &theClient, &theLen); if (theErr != QTSS_NoErr) return theErr; delete theClient; // // NULL out the attribute so in case there is a race condition no one will // get this dangling pointer (void)QTSS_SetValue(inParams->inClientSession, sProxyClientInfoAttr, 0, NULL, 0); return QTSS_NoErr; }
void QTSSModuleUtils::GetAttribute(QTSS_Object inObject, char* inAttributeName, QTSS_AttrDataType inType, void* ioBuffer, void* inDefaultValue, UInt32 inBufferLen) { // // Check to make sure this attribute is the right type. If it's not, this will coerce // it to be the right type. This also returns the id of the attribute QTSS_AttributeID theID = QTSSModuleUtils::CheckAttributeDataType(inObject, inAttributeName, inType, inDefaultValue, inBufferLen); // // Get the attribute value. QTSS_Error theErr = QTSS_GetValue(inObject, theID, 0, ioBuffer, &inBufferLen); // // Caller should KNOW how big this attribute is Assert(theErr != QTSS_NotEnoughSpace); if (theErr != QTSS_NoErr) { // // If we couldn't get the attribute value for whatever reason, just use the // default if it was provided. ::memcpy(ioBuffer, inDefaultValue, inBufferLen); if (inBufferLen > 0) { // // Log an error for this pref only if there was a default value provided. char* theValueAsString = NULL; theErr = QTSS_ValueToString(inDefaultValue, inBufferLen, inType, &theValueAsString); Assert(theErr == QTSS_NoErr); OSCharArrayDeleter theValueStr(theValueAsString); QTSSModuleUtils::LogError( sMissingPrefVerbosity, qtssServerPrefMissing, 0, inAttributeName, theValueStr.GetObject()); } // // Create an entry for this attribute QTSSModuleUtils::CreateAttribute(inObject, inAttributeName, inType, inDefaultValue, inBufferLen); } }
static void CallEndSession(QTSS_ClientSessionObject* theClientSession) { // action=listener_remove&server=myserver.com&port=8000&client=1&mount=/live&user=&pass=&duration=3600 // the duration SInt64* connectedTime = NULL; UInt32 connectedTimeLen = sizeof(connectedTime); (void)QTSS_GetValuePtr(*theClientSession, qtssCliSesTimeConnectedInMsec, 0, (void**)&connectedTime, &connectedTimeLen); qtss_printf("QTSSIcecastAuthModule::CallEndSession connected time in seconds %li\n", (*connectedTime / 1000)); long duration = (long)*connectedTime / 1000; // the mount point char mountPoint[128] = {0}; StrPtrLen mountPointStr(mountPoint,sizeof(mountPoint)); (void)QTSS_GetValue(*theClientSession, attrClientSessionMountPoint, 0, (void*)mountPointStr.Ptr, &mountPointStr.Len); printf("QTSSIcecastAuthModule::CallEndSession: mount point: %s\n", mountPoint); // TODO - we don't use this data on the remote end (yet), but implement - will probably need to copy // credentials into the client session from the RTSP session (annoying, but both aren't visible at all times) // // username and password // char* username = NULL; // (void)QTSS_GetValueAsString(theRTSPSession, attrRtspSessionProvidedUsername, 0, &username); // printf("QTSSIcecastAuthModule::CallEndSession: Provided username extracted from client session: %s\n", username); // // char* password = NULL; // (void)QTSS_GetValueAsString(theRTSPSession, attrRtspSessionProvidedPassword, 0, &password); // printf("QTSSIcecastAuthModule::CallEndSession: Provided password extracted from client session: %s\n", password); // ice session id char* iceSessID = NULL; QTSS_Error getSessErr = QTSS_GetValueAsString(*theClientSession, attrClientSessionFullSessionID, 0, &iceSessID); char postdata[512]; qtss_sprintf(postdata, "action=listener_remove&server=%s&port=554&client=%s&mount=%s&user=%s&pass=%s&duration=%li", hostname, iceSessID, mountPoint, "", "", duration); printf("QTSSIcecastAuthModule::CallAuthorizeSession: generated postdata: %s\n", postdata); printf("QTSSIcecastAuthModule::CallAuthorizeSession: i would post this to: %s\n", sEndSessionEndpoint); }
// Handle the QTSS_Initialize role call back. QTSS_Error Initialize(QTSS_Initialize_Params* inParams) { QTSS_Error err = QTSS_NoErr; UInt32 ulen = sizeof(sServerIPAddr); // Setup module utils QTSSModuleUtils::Initialize(inParams->inMessages, inParams->inServer, inParams->inErrorLogStream); // Get prefs object sPrefs = QTSSModuleUtils::GetModulePrefsObject(inParams->inModule); sServerPrefs = inParams->inPrefs; sServer = inParams->inServer; // Get the Server's IP address for later use. err = QTSS_GetValue(sServer, qtssSvrDefaultIPAddr, 0, &sServerIPAddr, &ulen); err = RereadPrefs(); return err; }
Bool16 RTPSessionOutput::FilterPacket(QTSS_RTPStreamObject *theStreamPtr, StrPtrLen* inPacket) { if (fPreFilter == false) return false; Assert(theStreamPtr); Assert(inPacket); UInt16 seqnum = this->GetPacketSeqNumber(inPacket); UInt16 firstSeqNum = 0; UInt32 theLen = sizeof(firstSeqNum); if ( QTSS_NoErr != QTSS_GetValue(*theStreamPtr, qtssRTPStrFirstSeqNumber, 0, &firstSeqNum, &theLen) ) return true; if ( seqnum < firstSeqNum ) return true; fPreFilter = false; return fPreFilter; }
CServiceSession::~CServiceSession() { char remoteAddress[20] = {0}; StrPtrLen theIPAddressStr(remoteAddress,sizeof(remoteAddress)); QTSS_GetValue(this, qtssRTSPSesRemoteAddrStr, 0, (void*)theIPAddressStr.Ptr, &theIPAddressStr.Len); char msgStr[2048] = { 0 }; qtss_snprintf(msgStr, sizeof(msgStr), "session offline from ip[%s]",remoteAddress); QTSServerInterface::LogError(qtssMessageVerbosity, msgStr); // Invoke the session closing modules QTSS_RoleParams theParams; theParams.rtspSessionClosingParams.inRTSPSession = this; //会话断开时,调用模块进行一些停止的工作 for (UInt32 x = 0; x < QTSServerInterface::GetNumModulesInRole(QTSSModule::kRTSPSessionClosingRole); x++) (void)QTSServerInterface::GetModule(QTSSModule::kRTSPSessionClosingRole, x)->CallDispatch(QTSS_RTSPSessionClosing_Role, &theParams); fLiveSession = false; //used in Clean up request to remove the RTP session. this->CleanupRequest();// Make sure that all our objects are deleted //if (fSessionType == qtssServiceSession) // QTSServerInterface::GetServer()->AlterCurrentServiceSessionCount(-1); }
QTSS_Error RereadPrefs() { // // Use the standard GetPref routine to retrieve the correct values for our preferences QTSSModuleUtils::GetAttribute(sPrefs, "loss_thin_tolerance", qtssAttrDataTypeUInt32, &sLossThinTolerance, &sDefaultLossThinTolerance, sizeof(sLossThinTolerance)); QTSSModuleUtils::GetAttribute(sPrefs, "num_losses_to_thin", qtssAttrDataTypeUInt32, &sNumLossesToThin, &sDefaultNumLossesToThin, sizeof(sNumLossesToThin)); QTSSModuleUtils::GetAttribute(sPrefs, "loss_thick_tolerance", qtssAttrDataTypeUInt32, &sLossThickTolerance, &sDefaultLossThickTolerance, sizeof(sLossThickTolerance)); QTSSModuleUtils::GetAttribute(sPrefs, "num_losses_to_thick", qtssAttrDataTypeUInt32, &sLossesToThick, &sDefaultLossesToThick, sizeof(sLossesToThick)); QTSSModuleUtils::GetAttribute(sPrefs, "num_worses_to_thin", qtssAttrDataTypeUInt32, &sWorsesToThin, &sDefaultWorsesToThin, sizeof(sWorsesToThin)); QTSSModuleUtils::GetAttribute(sPrefs, "flow_control_udp_thinning_module_enabled", qtssAttrDataTypeBool16, &sModuleEnabled, &sDefaultModuleEnabled, sizeof(sDefaultModuleEnabled)); UInt32 len = sizeof(sDisableThinning); (void) QTSS_GetValue(sServerPrefs, qtssPrefsDisableThinning, 0, (void*)&sDisableThinning, &len); return QTSS_NoErr; }