void QTSServerInterface::SetValueComplete(UInt32 inAttrIndex, QTSSDictionaryMap* inMap, UInt32 inValueIndex, void* inNewValue, UInt32 inNewValueLen) { if (inAttrIndex == qtssSvrState) { Assert(inNewValueLen == sizeof(QTSS_ServerState)); // // Invoke the server state change role QTSS_RoleParams theParams; theParams.stateChangeParams.inNewState = *(QTSS_ServerState*)inNewValue; static QTSS_ModuleState sStateChangeState = { NULL, 0, NULL, false }; if (OSThread::GetCurrent() == NULL) OSThread::SetMainThreadData(&sStateChangeState); else OSThread::GetCurrent()->SetThreadData(&sStateChangeState); UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStateChangeRole); { for (UInt32 theCurrentModule = 0; theCurrentModule < numModules; theCurrentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStateChangeRole, theCurrentModule); (void)theModule->CallDispatch(QTSS_StateChange_Role, &theParams); } } // // Make sure to clear out the thread data if (OSThread::GetCurrent() == NULL) OSThread::SetMainThreadData(NULL); else OSThread::GetCurrent()->SetThreadData(NULL); } }
void QTSServer::DoInitRole() { QTSS_RoleParams theInitParams; theInitParams.initParams.inServer = this; theInitParams.initParams.inPrefs = fSrvrPrefs; theInitParams.initParams.inMessages = fSrvrMessages; theInitParams.initParams.inErrorLogStream = &sErrorLogStream; QTSS_ModuleState theModuleState; theModuleState.curRole = QTSS_Initialize_Role; theModuleState.curTask = NULL; OSThread::SetMainThreadData(&theModuleState); for (UInt32 x = 0; x < QTSServerInterface::GetNumModulesInRole(QTSSModule::kInitializeRole); x++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kInitializeRole, x); theInitParams.initParams.inModule = theModule; theModuleState.curModule = theModule; QTSS_Error theErr = theModule->CallDispatch(QTSS_Initialize_Role, &theInitParams); if (theErr != QTSS_NoErr) { // If the module reports an error when initializing itself, // delete the module and pretend it was never there. QTSSModuleUtils::LogError(qtssWarningVerbosity, qtssMsgInitFailed, theErr, theModule->GetValue(qtssModName)->Ptr); sModuleQueue.Remove(theModule->GetQueueElem()); delete theModule; } } OSThread::SetMainThreadData(NULL); }
SInt64 ReflectorSessionCheckTask::Run() { OSRefTable* reflectorSessionMap = QTSServerInterface::GetServer()->GetReflectorSessionMap(); OSMutexLocker locker(reflectorSessionMap->GetMutex()); SInt64 sNowTime = OS::Milliseconds(); for (OSRefHashTableIter theIter(reflectorSessionMap->GetHashTable()); !theIter.IsDone(); theIter.Next()) { OSRef* theRef = theIter.GetCurrent(); ReflectorSession* theSession = (ReflectorSession*)theRef->GetObject(); SInt64 sCreateTime = theSession->GetInitTimeMS(); if( (theSession->GetNumOutputs() == 0) && (sNowTime-sCreateTime >= 20*1000) ) { QTSS_RoleParams theParams; theParams.easyFreeStreamParams.inStreamName = theSession->GetStreamName(); UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kEasyCMSFreeStreamRole); for ( UInt32 currentModule=0;currentModule < numModules; currentModule++) { qtss_printf("没有客户端观看当前转发媒体\n"); QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kEasyCMSFreeStreamRole, currentModule); (void)theModule->CallDispatch(Easy_CMSFreeStream_Role, &theParams); } } } return 30*1000;//30s }
void ReflectorSession::DelRedisLive() { QTSS_RoleParams theParams; theParams.easyStreamInfoParams.inStreamName = fSessionName.Ptr; theParams.easyStreamInfoParams.inChannel = fChannelNum; theParams.easyStreamInfoParams.inAction = easyRedisActionDelete; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kRedisUpdateStreamInfoRole); for (UInt32 currentModule = 0; currentModule < numModules; currentModule++) { qtss_printf("从redis中删除推流名称%s\n", fSourceID.Ptr); QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kRedisUpdateStreamInfoRole, currentModule); (void)theModule->CallDispatch(Easy_RedisUpdateStreamInfo_Role, &theParams); } }
Bool16 QTSServer::Initialize(XMLPrefsParser* inPrefsSource, PrefsSource* inMessagesSource, UInt16 inPortOverride, Bool16 createListeners) { fServerState = qtssFatalErrorState; sPrefsSource = inPrefsSource; sMessagesSource = inMessagesSource; this->InitCallbacks(); fMediaSource = NULL; // // DICTIONARY INITIALIZATION QTSSModule::Initialize(); QTSServerPrefs::Initialize(); QTSSMessages::Initialize(); QTSSFile::Initialize(); // // STUB SERVER INITIALIZATION // // Construct stub versions of the prefs and messages dictionaries. We need // both of these to initialize the server, but they have to be stubs because // their QTSSDictionaryMaps will presumably be modified when modules get loaded. fSrvrPrefs = new QTSServerPrefs(inPrefsSource, false); // First time, don't write changes to the prefs file fSrvrMessages = new QTSSMessages(inMessagesSource); QTSSModuleUtils::Initialize(fSrvrMessages, this, QTSServerInterface::GetErrorLogStream()); SetAssertLogger(this->GetErrorLogStream());// the error log stream is our assert logger // Load ERROR LOG module only. This is good in case there is a startup error. QTSSModule* theLoggingModule = new QTSSModule("QTSSErrorLogModule"); (void)theLoggingModule->SetupModule(&sCallbacks, &QTSSErrorLogModule_Main); (void)AddModule(theLoggingModule); this->BuildModuleRoleArrays(); // // STARTUP TIME - record it fStartupTime_UnixMilli = OS::Milliseconds(); fGMTOffset = OS::GetGMTOffset(); if ( fNumListeners == 0 ) { if (createListeners) QTSSModuleUtils::LogError(qtssWarningVerbosity, qtssMsgNoPortsSucceeded, 0); } fServerState = qtssStartingUpState; return true; }
void EasyCMSSession::stopPushStream() { QTSS_RoleParams params; QTSS_Error errCode = QTSS_NoErr; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStopStreamRole); for (; fCurrentModule < numModules; ++fCurrentModule) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStopStreamRole, fCurrentModule); errCode = theModule->CallDispatch(Easy_StopStream_Role, ¶ms); } fCurrentModule = 0; }
SInt64 EasyCameraSource::Run() { QTSS_Error theErr = QTSS_NoErr; EventFlags events = this->GetEvents(); if(events & Task::kTimeoutEvent) { //向设备获取快照数据 //unsigned char *sData = (unsigned char*)malloc(EASY_SNAP_BUFFER_SIZE); unsigned char *sData = new unsigned char[EASY_SNAP_BUFFER_SIZE]; int snapBufLen = 0; do{ //如果获取到摄像机快照数据,Base64编码/发送 if (!getSnapData(sData, EASY_SNAP_BUFFER_SIZE, &snapBufLen)) { //未获取到数据 qtss_printf("EasyCameraSource::Run::GetSnapData() => Get Snap Data Fail \n"); theErr = QTSS_ValueNotFound; break; } QTSS_RoleParams params; params.postSnapParams.snapLen = snapBufLen; params.postSnapParams.snapPtr = sData; params.postSnapParams.snapType = EASY_SNAP_TYPE_JPEG; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kPostSnapRole); for (; fCurrentModule < numModules; fCurrentModule++) { qtss_printf("EasyCameraSource::Run::kPostSnapRole\n"); QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kPostSnapRole, fCurrentModule); (void)theModule->CallDispatch(Easy_PostSnap_Role, ¶ms); break; } break; }while(0); //free((void*)sData); delete []sData; sData = NULL; fTimeoutTask->RefreshTimeout(); } return 0; }
QTSS_Error QTSSCallbacks::Easy_StopHLSession(const char* inSessionName) { QTSS_RoleParams packetParams; packetParams.easyHLSCloseParams.inStreamName = (char*)inSessionName; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kEasyHLSCloseRole); for (; fCurrentModule < numModules; fCurrentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kEasyHLSCloseRole, fCurrentModule); (void)theModule->CallDispatch(Easy_HLSClose_Role, &packetParams); return QTSS_NoErr; } return QTSS_RequestFailed; }
void QTSServer::DoInitRole() { QTSS_RoleParams theInitParams; theInitParams.initParams.inServer = this; theInitParams.initParams.inPrefs = fSrvrPrefs; theInitParams.initParams.inMessages = fSrvrMessages; theInitParams.initParams.inErrorLogStream = &sErrorLogStream; QTSS_ModuleState theModuleState; theModuleState.curRole = QTSS_Initialize_Role; theModuleState.curTask = NULL; OSThread::SetMainThreadData(&theModuleState); // // Add the OPTIONS method as the one method the server handles by default (it handles // it internally). Modules that handle other RTSP methods will add QTSS_RTSPMethod theOptionsMethod = qtssOptionsMethod; (void)this->SetValue(qtssSvrHandledMethods, 0, &theOptionsMethod, sizeof(theOptionsMethod)); // For now just disable the SetParameter to be compatible with Real. It should really be removed only for clients that have problems with their SetParameter implementations like (Real Players). // At the moment it isn't necesary to add the option. // QTSS_RTSPMethod theSetParameterMethod = qtssSetParameterMethod; // (void)this->SetValue(qtssSvrHandledMethods, 0, &theSetParameterMethod, sizeof(theSetParameterMethod)); for (UInt32 x = 0; x < QTSServerInterface::GetNumModulesInRole(QTSSModule::kInitializeRole); x++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kInitializeRole, x); theInitParams.initParams.inModule = theModule; theModuleState.curModule = theModule; QTSS_Error theErr = theModule->CallDispatch(QTSS_Initialize_Role, &theInitParams); if (theErr != QTSS_NoErr) { // If the module reports an error when initializing itself, // delete the module and pretend it was never there. QTSSModuleUtils::LogError(qtssWarningVerbosity, qtssMsgInitFailed, theErr, theModule->GetValue(qtssModName)->Ptr); sModuleQueue.Remove(theModule->GetQueueElem()); delete theModule; } } OSThread::SetMainThreadData(NULL); }
QTSS_Error QTSSCallbacks::Easy_ListRecordFiles(const char* inSessionName, const char* inBeginTime, const char* inEndTime, vector<string> *outRecordFiles) { QTSS_RoleParams packetParams; packetParams.easyRecordListParams.inStreamName = (char*)inSessionName; packetParams.easyRecordListParams.inBeginTime = (char*)inBeginTime; packetParams.easyRecordListParams.inEndTime = (char*)inEndTime; packetParams.easyRecordListParams.outRecords = outRecordFiles; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kRecordListRole); for (; fCurrentModule < numModules; fCurrentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kRecordListRole, fCurrentModule); (void)theModule->CallDispatch(Easy_RecordList_Role, &packetParams); return QTSS_NoErr; } return QTSS_RequestFailed; }
QTSS_Error ReflectorSession::SetSessionName() { if (fSourceID.Len > 0) { QTSS_RoleParams theParams; theParams.easyStreamInfoParams.inStreamName = fSessionName.Ptr; theParams.easyStreamInfoParams.inChannel = fChannelNum; theParams.easyStreamInfoParams.inNumOutputs = fNumOutputs; theParams.easyStreamInfoParams.inAction = easyRedisActionSet; auto numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kRedisUpdateStreamInfoRole); for (UInt32 currentModule = 0; currentModule < numModules; currentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kRedisUpdateStreamInfoRole, currentModule); (void)theModule->CallDispatch(Easy_RedisUpdateStreamInfo_Role, &theParams); } } return QTSS_NoErr; }
QTSS_Error QTSSCallbacks::Easy_StartHLSession(const char* inSessionName, const char* inURL, UInt32 inTimeout, char* outURL) { QTSS_RoleParams params; params.easyHLSOpenParams.inStreamName = (char*)inSessionName; params.easyHLSOpenParams.inRTSPUrl = (char*)inURL; params.easyHLSOpenParams.inTimeout = inTimeout; params.easyHLSOpenParams.outHLSUrl = outURL; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kEasyHLSOpenRole); for (; fCurrentModule < numModules; fCurrentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kEasyHLSOpenRole, fCurrentModule); (void)theModule->CallDispatch(Easy_HLSOpen_Role, ¶ms); return QTSS_NoErr; } return QTSS_RequestFailed; }
QTSS_Error QTSSCallbacks::QTSS_SetIdleRoleTimer(SInt64 inMsecToWait) { QTSS_ModuleState* theState = (QTSS_ModuleState*)OSThread::GetMainThreadData(); if (OSThread::GetCurrent() != NULL) theState = (QTSS_ModuleState*)OSThread::GetCurrent()->GetThreadData(); // This may happen if this callback is occurring on module-created thread if (theState == NULL) return QTSS_RequestFailed; if (theState->curModule == NULL) return QTSS_RequestFailed; QTSSModule* theModule = theState->curModule; QTSS_ModuleState* thePrivateModuleState = theModule->GetModuleState(); thePrivateModuleState->idleTime = inMsecToWait; theModule->Signal(Task::kUpdateEvent); return QTSS_NoErr; }
void HTTPSessionInterface::UnRegDevSession() { if (fAuthenticated) { char msgStr[512]; qtss_snprintf(msgStr, sizeof(msgStr), "Device unregister,Device_serial[%s]\n", fDevice.serial_.c_str()); QTSServerInterface::LogError(qtssMessageVerbosity, msgStr); QTSServerInterface::GetServer()->GetDeviceSessionMap()->UnRegister(fDevice.serial_);//add //在redis上删除设备 //QTSServerInterface::GetServer()->RedisDelDevName(fDevice.serial_.c_str()); QTSS_RoleParams theParams; theParams.StreamNameParams.inStreamName = (char *)(fDevice.serial_.c_str()); UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kDelDevNameRole); for ( UInt32 currentModule=0;currentModule < numModules; currentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kDelDevNameRole, currentModule); (void)theModule->CallDispatch(QTSS_DelDevName_Role, &theParams); } } }
void QTSServer::BuildModuleRoleArrays() { OSQueueIter theIter(&sModuleQueue); QTSSModule* theModule = NULL; // Make sure these variables are cleaned out in case they've already been inited. DestroyModuleRoleArrays(); // Loop through all the roles of all the modules, recording the number of // modules in each role, and also recording which modules are doing what. for (UInt32 x = 0; x < QTSSModule::kNumRoles; x++) { sNumModulesInRole[x] = 0; for (theIter.Reset(); !theIter.IsDone(); theIter.Next()) { theModule = (QTSSModule*)theIter.GetCurrent()->GetEnclosingObject(); if (theModule->RunsInRole(x)) sNumModulesInRole[x] += 1; } if (sNumModulesInRole[x] > 0) { UInt32 moduleIndex = 0; sModuleArray[x] = new QTSSModule*[sNumModulesInRole[x] + 1]; for (theIter.Reset(); !theIter.IsDone(); theIter.Next()) { theModule = (QTSSModule*)theIter.GetCurrent()->GetEnclosingObject(); if (theModule->RunsInRole(x)) { sModuleArray[x][moduleIndex] = theModule; moduleIndex++; } } } } }
void QTSServer::LoadCompiledInModules() { #ifndef DSS_DYNAMIC_MODULES_ONLY // MODULE DEVELOPERS SHOULD ADD THE FOLLOWING THREE LINES OF CODE TO THIS // FUNCTION IF THEIR MODULE IS BEING COMPILED INTO THE SERVER. // // QTSSModule* myModule = new QTSSModule("__MODULE_NAME__"); // (void)myModule->Initialize(&sCallbacks, &__MODULE_MAIN_ROUTINE__); // (void)AddModule(myModule); // // The following modules are all compiled into the server. #endif //DSS_DYNAMIC_MODULES_ONLY QTSSModule* theCMSModule = new QTSSModule("EasyCMSModule"); (void)theCMSModule->SetupModule(&sCallbacks, &EasyCMSModule_Main); (void)AddModule(theCMSModule); QTSSModule* theCameraModule = new QTSSModule("EasyCameraModule"); (void)theCameraModule->SetupModule(&sCallbacks, &EasyCameraModule_Main); (void)AddModule(theCameraModule); }
void HTTPSessionInterface::UnRegDevSession() const { if (fAuthenticated) { char msgStr[512]; qtss_snprintf(msgStr, sizeof(msgStr), "Device unregister£¬Device_serial[%s]\n", device_->serial_.c_str()); QTSServerInterface::LogError(qtssMessageVerbosity, msgStr); QTSServerInterface::GetServer()->GetDeviceSessionMap()->UnRegister(device_->serial_);//add //ÔÚredisÉÏɾ³ýÉ豸 //QTSServerInterface::GetServer()->RedisDelDevice(fDevice.serial_.c_str()); QTSS_RoleParams theParams; theParams.DeviceInfoParams.serial_ = new char[64]; strncpy(theParams.DeviceInfoParams.serial_, device_->serial_.c_str(), device_->serial_.size() + 1); UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kRedisDelDeviceRole); for (UInt32 currentModule = 0; currentModule < numModules; currentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kRedisDelDeviceRole, currentModule); (void)theModule->CallDispatch(Easy_RedisDelDevice_Role, &theParams); } delete[] theParams.DeviceInfoParams.serial_; } }
void RunServer() { Bool16 restartServer = false; UInt32 loopCount = 0; UInt32 debugLevel = 0; Bool16 printHeader = false; Bool16 printStatus = false; UInt32 num=0; //just wait until someone stops the server or a fatal error occurs. QTSS_ServerState theServerState = sServer->GetServerState(); while ((theServerState != qtssShuttingDownState) && (theServerState != qtssFatalErrorState)) { #ifdef __sgi__ OSThread::Sleep(999); #else OSThread::Sleep(1000); #endif //add,redis,¶¨Ê±±£»î num++; if(num%5==0) { num=0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kRedisTTLRole); for ( UInt32 currentModule=0;currentModule < numModules; currentModule++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kRedisTTLRole, currentModule); (void)theModule->CallDispatch(Easy_RedisTTL_Role, NULL); } } // LogStatus(theServerState); if (sStatusUpdateInterval) { debugLevel = sServer->GetDebugLevel(); printHeader = PrintHeader(loopCount); printStatus = PrintLine(loopCount); if (printStatus) { if (DebugOn(sServer) ) // debug level display or logging is on DebugStatus(debugLevel, printHeader); if (!DebugDisplayOn(sServer)) PrintStatus(printHeader); // default status output } loopCount++; } if ((sServer->SigIntSet()) || (sServer->SigTermSet())) { // // start the shutdown process theServerState = qtssShuttingDownState; (void)QTSS_SetValue(QTSServerInterface::GetServer(), qtssSvrState, 0, &theServerState, sizeof(theServerState)); if (sServer->SigIntSet()) restartServer = true; } theServerState = sServer->GetServerState(); if (theServerState == qtssIdleState) sServer->KillAllRTPSessions(); } // // Kill all the sessions and wait for them to die, // but don't wait more than 5 seconds sServer->KillAllRTPSessions(); for (UInt32 shutdownWaitCount = 0; (sServer->GetNumRTPSessions() > 0) && (shutdownWaitCount < 5); shutdownWaitCount++) OSThread::Sleep(1000); //Now, make sure that the server can't do any work TaskThreadPool::RemoveThreads(); //now that the server is definitely stopped, it is safe to initate //the shutdown process delete sServer; CleanPid(false); //ok, we're ready to exit. If we're quitting because of some fatal error //while running the server, make sure to let the parent process know by //exiting with a nonzero status. Otherwise, exit with a 0 status if (theServerState == qtssFatalErrorState || restartServer) ::exit (-2);//-2 signals parent process to restart server }
QTSS_Error EasyCMSSession::processMessage() { if (NULL == fRequest) return QTSS_BadArgument; QTSS_Error theErr = fRequest->Parse(); if (theErr != QTSS_NoErr) return QTSS_BadArgument; //获取具体Content json数据部分 StrPtrLen* lengthPtr = fRequest->GetHeaderValue(httpContentLengthHeader); StringParser theContentLenParser(lengthPtr); theContentLenParser.ConsumeWhitespace(); UInt32 content_length = theContentLenParser.ConsumeInteger(NULL); if (content_length) { qtss_printf("EasyCMSSession::ProcessMessage read content-length:%lu \n", content_length); // 检查content的fContentBuffer和fContentBufferOffset是否有值存在,如果存在,说明我们已经开始 // 进行content请求处理,如果不存在,我们需要创建并初始化fContentBuffer和fContentBufferOffset if (fContentBuffer == NULL) { fContentBuffer = NEW char[content_length + 1]; memset(fContentBuffer, 0, content_length + 1); fContentBufferOffset = 0; } UInt32 theLen = 0; // 读取HTTP Content报文数据 theErr = fInputStream.Read(fContentBuffer + fContentBufferOffset, content_length - fContentBufferOffset, &theLen); Assert(theErr != QTSS_BadArgument); if (theErr == QTSS_RequestFailed) { OSCharArrayDeleter charArrayPathDeleter(fContentBuffer); fContentBufferOffset = 0; fContentBuffer = NULL; return QTSS_RequestFailed; } qtss_printf("EasyCMSSession::ProcessMessage() Add Len:%lu \n", theLen); if ((theErr == QTSS_WouldBlock) || (theLen < (content_length - fContentBufferOffset))) { // // Update our offset in the buffer fContentBufferOffset += theLen; Assert(theErr == QTSS_NoErr); return QTSS_WouldBlock; } Assert(theErr == QTSS_NoErr); // 处理完成报文后会自动进行Delete处理 OSCharArrayDeleter charArrayPathDeleter(fContentBuffer); qtss_printf("EasyCMSSession::ProcessMessage() Get Complete Msg:\n%s", fContentBuffer); fNoneACKMsgCount = 0; EasyProtocol protocol(fContentBuffer); int nNetMsg = protocol.GetMessageType(); switch (nNetMsg) { case MSG_SD_REGISTER_ACK: { EasyMsgSDRegisterACK ack(fContentBuffer); qtss_printf("session id = %s\n", ack.GetBodyValue(EASY_TAG_SESSION_ID).c_str()); qtss_printf("device serial = %s\n", ack.GetBodyValue(EASY_TAG_SERIAL).c_str()); } break; case MSG_SD_POST_SNAP_ACK: { ; } break; case MSG_SD_PUSH_STREAM_REQ: { EasyMsgSDPushStreamREQ startStreamReq(fContentBuffer); string serial = startStreamReq.GetBodyValue(EASY_TAG_SERIAL); string ip = startStreamReq.GetBodyValue(EASY_TAG_SERVER_IP); string port = startStreamReq.GetBodyValue(EASY_TAG_SERVER_PORT); string protocol = startStreamReq.GetBodyValue(EASY_TAG_PROTOCOL); string channel = startStreamReq.GetBodyValue(EASY_TAG_CHANNEL); string streamID = startStreamReq.GetBodyValue(EASY_TAG_STREAM_ID); string reserve = startStreamReq.GetBodyValue(EASY_TAG_RESERVE); qtss_printf("Serial = %s\n", serial.c_str()); qtss_printf("Server_IP = %s\n", ip.c_str()); qtss_printf("Server_Port = %s\n", port.c_str()); //TODO::这里需要对传入的Serial/StreamID/Channel做一下容错处理 if (serial.empty() || ip.empty() || port.empty()) { return QTSS_ValueNotFound; } QTSS_RoleParams params; params.startStreaParams.inIP = ip.c_str(); params.startStreaParams.inPort = atoi(port.c_str()); params.startStreaParams.inSerial = serial.c_str(); params.startStreaParams.inProtocol = protocol.c_str(); params.startStreaParams.inChannel = channel.c_str(); params.startStreaParams.inStreamID = streamID.c_str(); QTSS_Error errCode = QTSS_NoErr; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStartStreamRole); for (; fCurrentModule < numModules; ++fCurrentModule) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStartStreamRole, fCurrentModule); errCode = theModule->CallDispatch(Easy_StartStream_Role, ¶ms); } fCurrentModule = 0; EasyJsonValue body; body[EASY_TAG_SERIAL] = params.startStreaParams.inSerial; body[EASY_TAG_CHANNEL] = params.startStreaParams.inChannel; body[EASY_TAG_PROTOCOL] = params.startStreaParams.inProtocol; body[EASY_TAG_SERVER_IP] = params.startStreaParams.inIP; body[EASY_TAG_SERVER_PORT] = params.startStreaParams.inPort; body[EASY_TAG_RESERVE] = reserve; EasyMsgDSPushSteamACK rsp(body, startStreamReq.GetMsgCSeq(), getStatusNo(errCode)); string msg = rsp.GetMsg(); StrPtrLen jsonContent((char*)msg.data()); HTTPRequest httpAck(&QTSServerInterface::GetServerHeader(), httpResponseType); if (httpAck.CreateResponseHeader()) { if (jsonContent.Len) httpAck.AppendContentLengthHeader(jsonContent.Len); //Push msg to OutputBuffer char respHeader[2048] = { 0 }; StrPtrLen* ackPtr = httpAck.GetCompleteHTTPHeader(); strncpy(respHeader, ackPtr->Ptr, ackPtr->Len); fOutputStream.Put(respHeader); if (jsonContent.Len > 0) fOutputStream.Put(jsonContent.Ptr, jsonContent.Len); } } break; case MSG_SD_STREAM_STOP_REQ: { EasyMsgSDStopStreamREQ stopStreamReq(fContentBuffer); QTSS_RoleParams params; string serial = stopStreamReq.GetBodyValue(EASY_TAG_SERIAL); params.stopStreamParams.inSerial = serial.c_str(); string protocol = stopStreamReq.GetBodyValue(EASY_TAG_PROTOCOL); params.stopStreamParams.inProtocol = protocol.c_str(); string channel = stopStreamReq.GetBodyValue(EASY_TAG_CHANNEL); params.stopStreamParams.inChannel = channel.c_str(); QTSS_Error errCode = QTSS_NoErr; UInt32 fCurrentModule = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kStopStreamRole); for (; fCurrentModule < numModules; ++fCurrentModule) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kStopStreamRole, fCurrentModule); errCode = theModule->CallDispatch(Easy_StopStream_Role, ¶ms); } fCurrentModule = 0; EasyJsonValue body; body[EASY_TAG_SERIAL] = params.stopStreamParams.inSerial; body[EASY_TAG_CHANNEL] = params.stopStreamParams.inChannel; body[EASY_TAG_PROTOCOL] = params.stopStreamParams.inProtocol; EasyMsgDSStopStreamACK rsp(body, stopStreamReq.GetMsgCSeq(), getStatusNo(errCode)); string msg = rsp.GetMsg(); //回应 StrPtrLen jsonContent((char*)msg.data()); HTTPRequest httpAck(&QTSServerInterface::GetServerHeader(), httpResponseType); if (httpAck.CreateResponseHeader()) { if (jsonContent.Len) httpAck.AppendContentLengthHeader(jsonContent.Len); //Push msg to OutputBuffer char respHeader[2048] = { 0 }; StrPtrLen* ackPtr = httpAck.GetCompleteHTTPHeader(); strncpy(respHeader, ackPtr->Ptr, ackPtr->Len); fOutputStream.Put(respHeader); if (jsonContent.Len > 0) fOutputStream.Put(jsonContent.Ptr, jsonContent.Len); } } break; default: break; } }
QTSS_Error QTSSCallbacks::QTSS_Authorize(QTSS_RTSPRequestObject inAuthRequestObject, char** outAuthRealm, Bool16* outAuthUserAllowed) { RTSPRequestInterface* request = (RTSPRequestInterface *) inAuthRequestObject; if (request == NULL) return QTSS_BadArgument; // Because this is a role being executed from inside a callback, we need to // make sure that QTSS_RequestEvent will not work. Task* curTask = NULL; QTSS_ModuleState* theState = (QTSS_ModuleState*)OSThread::GetMainThreadData(); if (OSThread::GetCurrent() != NULL) theState = (QTSS_ModuleState*)OSThread::GetCurrent()->GetThreadData(); if (theState != NULL) curTask = theState->curTask; QTSS_RoleParams theParams; theParams.rtspRequestParams.inRTSPSession = NULL; theParams.rtspRequestParams.inRTSPRequest = request; theParams.rtspRequestParams.inClientSession = NULL; QTSS_Error theErr = QTSS_RequestFailed; UInt32 x = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kRTSPAuthRole); QTSSModule* theModulePtr = NULL; Bool16 allowedDefault = QTSServerInterface::GetServer()->GetPrefs()->GetAllowGuestDefault(); *outAuthUserAllowed = allowedDefault; Bool16 allowed = allowedDefault; //server pref? Bool16 hasUser = false; Bool16 handled = false; // Call all the modules that are registered for the RTSP Authorize Role for ( ; x < numModules; x++) { request->SetAllowed(true); request->SetHasUser(false); request->SetAuthHandled(false); debug_printf(" QTSSCallbacks::QTSS_Authorize calling module module = %lu numModules=%lu\n", x,numModules); theModulePtr = QTSServerInterface::GetModule(QTSSModule::kRTSPAuthRole, x); theErr = QTSS_NoErr; if (theModulePtr) { if (__QTSSCALLBACKS_DEBUG__) theModulePtr->GetValue(qtssModName)->PrintStr("QTSSModule::CallDispatch ENTER module=", "\n"); theErr = theModulePtr->CallDispatch(QTSS_RTSPAuthorize_Role, &theParams); debug_printf(" QTSSCallbacks::QTSS_Authorize calling module module = %lu numModules=%lu ModuleError=%ld\n", x,numModules, theErr); } else { debug_printf(" QTSSCallbacks::QTSS_Authorize calling module module = %lu is NULL! numModules=%lu\n", x,numModules); continue; } allowed = request->GetAllowed(); hasUser = request->GetHasUser(); handled = request->GetAuthHandled(); debug_printf("QTSSCallbacks::QTSS_Authorize allowedDefault =%d allowed= %d hasUser = %d handled=%d \n",allowedDefault, allowed,hasUser, handled); *outAuthUserAllowed = allowed; //notes: //if (allowed && !handled) break; //old module //if (!allowed && handled) /new module handled the request but not authorized keep trying //if (allowed && handled) //new module allowed but keep trying in case someone denies. if (!allowed && !handled) //old module break on !allowed { debug_printf("RTSPSession.cpp::Run(kAuthorizingRequest) skipping other modules fCurrentModule = %lu numModules=%lu\n", x,numModules); break; } } // outAuthRealm is set to the realm that is given by the module that has denied authentication StrPtrLen* realm = request->GetValue(qtssRTSPReqURLRealm); *outAuthRealm = realm->GetAsCString(); return theErr; }
QTSS_Error QTSSCallbacks::QTSS_Authenticate(const char* inAuthUserName, const char* inAuthResourceLocalPath, const char* inAuthMoviesDir, QTSS_ActionFlags inAuthRequestAction, QTSS_AuthScheme inAuthScheme, QTSS_RTSPRequestObject ioAuthRequestObject) { if((inAuthUserName == NULL) || (inAuthResourceLocalPath == NULL) || (inAuthMoviesDir == NULL) || (ioAuthRequestObject == NULL)) return QTSS_BadArgument; if(inAuthRequestAction == qtssActionFlagsNoFlags) return QTSS_BadArgument; if(inAuthScheme == qtssAuthNone) return QTSS_BadArgument; // First create a RTSPRequestInterface object // There is no session attached to it, so just pass in NULL for the RTSPSession RTSPRequestInterface *request = (RTSPRequestInterface *) ioAuthRequestObject; // Set all the attributes required by the authentication module, using the input values (void) request->SetValue(qtssRTSPReqUserName, 0, inAuthUserName , ::strlen(inAuthUserName), QTSSDictionary::kDontObeyReadOnly); (void) request->SetValue(qtssRTSPReqLocalPath, 0, inAuthResourceLocalPath , ::strlen(inAuthResourceLocalPath), QTSSDictionary::kDontObeyReadOnly); (void) request->SetValue(qtssRTSPReqRootDir, 0, inAuthMoviesDir , ::strlen(inAuthMoviesDir), QTSSDictionary::kNoFlags); (void) request->SetValue(qtssRTSPReqAction, 0, (const void *)&inAuthRequestAction , sizeof(QTSS_ActionFlags), QTSSDictionary::kNoFlags); (void) request->SetValue(qtssRTSPReqAuthScheme, 0, (const void *)&inAuthScheme , sizeof(QTSS_AuthScheme), QTSSDictionary::kDontObeyReadOnly); QTSSUserProfile *profile = request->GetUserProfile(); (void) profile->SetValue(qtssUserName, 0, inAuthUserName, ::strlen(inAuthUserName), QTSSDictionary::kDontObeyReadOnly); // Because this is a role being executed from inside a callback, we need to // make sure that QTSS_RequestEvent will not work. Task* curTask = NULL; QTSS_ModuleState* theState = (QTSS_ModuleState*)OSThread::GetMainThreadData(); if (OSThread::GetCurrent() != NULL) theState = (QTSS_ModuleState*)OSThread::GetCurrent()->GetThreadData(); if (theState != NULL) curTask = theState->curTask; // Setup the authentication param block QTSS_RoleParams theAuthenticationParams; theAuthenticationParams.rtspAthnParams.inRTSPRequest = request; QTSS_Error theErr = QTSS_RequestFailed; UInt32 x = 0; UInt32 numModules = QTSServerInterface::GetNumModulesInRole(QTSSModule::kRTSPAthnRole); QTSSModule* theModulePtr = NULL; Bool16 allowedDefault = QTSServerInterface::GetServer()->GetPrefs()->GetAllowGuestDefault(); Bool16 allowed = allowedDefault; //server pref? Bool16 hasUser = false; Bool16 handled = false; // Call all the modules that are registered for the RTSP Authorize Role for ( ; x < numModules; x++) { request->SetAllowed(allowedDefault); request->SetHasUser(false); request->SetAuthHandled(false); debug_printf(" QTSSCallbacks::QTSS_Authenticate calling module module = %lu numModules=%lu\n", x,numModules); theModulePtr = QTSServerInterface::GetModule(QTSSModule::kRTSPAthnRole, x); theErr = QTSS_NoErr; if (theModulePtr) { theErr = theModulePtr->CallDispatch(QTSS_RTSPAuthenticate_Role, &theAuthenticationParams); debug_printf(" QTSSCallbacks::QTSS_Authorize calling module module = %lu numModules=%lu ModuleError=%ld\n", x,numModules, theErr); } else { debug_printf(" QTSSCallbacks::QTSS_Authorize calling module module = %lu is NULL! numModules=%lu\n", x,numModules); continue; } allowed = request->GetAllowed(); hasUser = request->GetHasUser(); handled = request->GetAuthHandled(); debug_printf("QTSSCallbacks::QTSS_Authenticate allowedDefault =%d allowed= %d hasUser = %d handled=%d \n",allowedDefault, allowed,hasUser, handled); if (hasUser || handled ) //See RTSPSession.cpp::Run state=kAuthenticatingRequest { debug_printf(" QTSSCallbacks::QTSS_Authenticate skipping other modules fCurrentModule = %lu numModules=%lu\n", x,numModules); break; } } // Reset the curTask to what it was before this role started if (theState != NULL) theState->curTask = curTask; return theErr; }
QTSS_Error QTSServer::RereadPrefsService(QTSS_ServiceFunctionArgsPtr /*inArgs*/) { // // This function can only be called safely when the server is completely running. // Ensuring this is a bit complicated because of preemption. Here's how it's done... QTSServerInterface* theServer = QTSServerInterface::GetServer(); // This is to make sure this function isn't being called before the server is // completely started up. if ((theServer == NULL) || (theServer->GetServerState() != qtssRunningState)) return QTSS_OutOfState; // Because the server must have started up, and because this object always stays // around (until the process dies), we can now safely get this object. QTSServerPrefs* thePrefs = theServer->GetPrefs(); // Grab the prefs mutex. We want to make sure that calls to RereadPrefsService // are serialized. This also prevents the server from shutting down while in // this function, because the QTSServer destructor grabs this mutex as well. OSMutexLocker locker(thePrefs->GetMutex()); // Finally, check the server state again. The state may have changed // to qtssShuttingDownState or qtssFatalErrorState in this time, though // at this point we have the prefs mutex, so we are guarenteed that the // server can't actually shut down anymore if (theServer->GetServerState() != qtssRunningState) return QTSS_OutOfState; // Ok, we're ready to reread preferences now. // // Reread preferences sPrefsSource->Parse(); thePrefs->RereadServerPreferences(true); // Delete all the streams QTSSModule** theModule = NULL; UInt32 theLen = 0; for (int y = 0; QTSServerInterface::GetServer()->GetValuePtr(qtssSvrModuleObjects, y, (void**)&theModule, &theLen) == QTSS_NoErr; y++) { Assert(theModule != NULL); Assert(theLen == sizeof(QTSSModule*)); (*theModule)->GetPrefsDict()->RereadPreferences(); #if DEBUG theModule = NULL; theLen = 0; #endif } // // Go through each module's prefs object and have those reread as well // // Now that we are done rereading the prefs, invoke all modules in the RereadPrefs // role so they can update their internal prefs caches. for (UInt32 x = 0; x < QTSServerInterface::GetNumModulesInRole(QTSSModule::kRereadPrefsRole); x++) { QTSSModule* theModule = QTSServerInterface::GetModule(QTSSModule::kRereadPrefsRole, x); (void)theModule->CallDispatch(QTSS_RereadPrefs_Role, NULL); } return QTSS_NoErr; }