⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmsmanager.cpp

📁 此程序为wcdma系统当中ftp/video业务模型的c++程序仿真 通过此程序 能得到此两种业务在多种条件下的吞吐量和无码率的性能
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					         m_iUnsatisfiedUserOfVoice++;
					 }
		                 
		             //进行重撒
					 TotalUserType tt=T_voice;
			         int ID=pVoiceMs->GetMsID();
	                         int nType=0;
			         float fV[10];
			         float fVelocity,pp;
			         fV[0]=m_fFractionOfChannel[0];
			         for (int i=1;i<10;i++)
				         fV[i]=1.0;
			         for (i=1;i<m_iChannelNumber;i++)
				         fV[i]=fV[i-1]+m_fFractionOfChannel[i];

			         //produce a random number between 0 and 1 to
			         //determine the user's channel type and correspondent velocity
			         pp=xUniform(0.,1.);
			         if (pp<fV[0])
					 {fVelocity=3.;nType=1;}
					 else if (pp<fV[1])
					 {fVelocity=10.;nType=2;}
			         else if (pp<fV[2])
					 {fVelocity=30.;nType=3;}
			         else if (pp<fV[3])
					 {fVelocity=120.;nType=4;}
			         else
					 {fVelocity=0.;nType=5;}
			         
			         //call initialization functions
			         pVoiceMs->MobileInitialization(ID,this,m_pServiceArea,
			         	fVelocity,nType,m_fStdSlowFading,tt);
			         pVoiceMs->Clean();  //释放VoiceMs的激活集链表和软切换消息链表
			         pVoiceMs->VoiceInitialization(m_pLinkPrediction);
			         m_iVoiceUserOfCurrentDrop++;
		        }
		   
                /*pVoiceMs->SetVoiceActivity();
                //将原先放在更新激活集函数中的设置话音激活因子改在这里*/
		        
		        if(pVoiceMs->GetSHOMsgNum())//判断切换事件队列是否为空
		        {
			           if(pVoiceMs->SHOMsgProcess())     //判断切换事件是否到时
			           {
			         	 pVoiceMs->ChangeActiveSet();    //到时,变更激活集;否则直接更新激活集				 
			           }
		        }
		         //更新激活集计算激活集内各BTS的业务信道C/I
		        pVoiceMs->UpdateActiveSet();

				//进行软切换开销相关统计 add by slj, Modified by Li Jing,20041115
				if(m_iSlotCurrentNum>INITIALSLOT)
				{
				    for ( int i = 0; i < ActiveSetMaxSize; i++)
					{
					
					    if( i == (( pVoiceMs->GetActiveSetSize() ) - 1) )
						    m_lSlotOfActiveSetSize[i]++;
					}

				    //用于软切换中的统计 add by slj 20041020
				    if( ( pVoiceMs->GetActiveSetSize() ) > 1 )
					{	
					    m_lTotalMsSlotInSHO ++;       
					    m_fTotalMsPowerInSHO += pVoiceMs->ObtainPowerInSHO();
					}
				}
										
		         //计算激活集内各BTS的业务信道C/I
		        pVoiceMs->ObtainC2I();
	
		        //根据实际的C/I与目标C/I,对激活集内各
		        //BTS发出功控信息(考虑PCBER的影响)
		        pVoiceMs->PowerControl();

		        //更新相邻集各个BTS到移动台的
		        //慢衰落和快衰落值
		        //更新移动台接收到的总功率值
		        //根据判断结果和时延特性,创建
		        //切换事件,写入切换事件队列
		        pVoiceMs->SHOMsgGenerator();
		
//		        if(m_iSlotCurrentNum>INITIALSLOT)  //考虑初始化时间
//		        {
		         	m=pVoiceMs->GetServiceLength()+1;
		         	pVoiceMs->SetServiceLength(m);
		        
				    //add up the slots C/I of one TTI time to calculate the TTI mean C/I 
		            sum=pVoiceMs->GetTTIMeanC2I()+(float)pow(10,(pVoiceMs->GetC2I()/10));
		            pVoiceMs->SetTTIMeanC2I(sum);
//				}
		        				
	    }
	    else          //用户还没有接纳成功
	    {
				    if(m_iSlotCurrentNum>INITIALSLOT)  //考虑初始化时间
					{
	                    m=pVoiceMs->GetAdmitTimer()+1;
	                    pVoiceMs->SetAdmitTimer(m);
					}
	                
					m=pVoiceMs->GetAdmitTimer();
					if(m>=BlockTimeThreshold)              //接入失败超时
	                {
	                         m_iBlockUserOfVoice++;        //话音用户接入失败数加一
							 m_iUnsatisfiedUserOfVoice++;
	                        
	                         int ID=pVoiceMs->GetMsID();   //以下为进行重撒,产生一个新的话音用户
			                 TotalUserType tt=T_voice;
			                 int nType=0;
			                 float fV[10];
			                 float fVelocity,pp;
			                 fV[0]=m_fFractionOfChannel[0];
			                 for (int i=1;i<10;i++)
				                    fV[i]=1.;
			                 for (i=1;i<m_iChannelNumber;i++)
				                    fV[i]=fV[i-1]+m_fFractionOfChannel[i];

			                 pp=xUniform(0.,1.);
			                 if (pp<fV[0])
							 {fVelocity=3.;nType=1;}
			                 else if (pp<fV[1])
							 {fVelocity=10.;nType=2;}
			                 else if (pp<fV[2])
							 {fVelocity=30.;nType=3;}
			                 else if (pp<fV[3])
							 {fVelocity=120.;nType=4;}
			                 else
							 {fVelocity=0.;nType=5;}
			                 pVoiceMs->MobileInitialization(ID,this,m_pServiceArea,
			         	             fVelocity,nType,m_fStdSlowFading,tt);
			                 pVoiceMs->Clean();  //释放VoiceMs的激活集链表和软切换消息链表
			                 pVoiceMs->VoiceInitialization(m_pLinkPrediction);
			                 m_iVoiceUserOfCurrentDrop++;
					}
			        else            //接入失败还没有超时
			                 pVoiceMs->InitActiveSet();
	    }
	}
}



//////////////////////////////////////////////////////////////////////////
//TITLE:      TTIBlockCumulate(TTI时间内块累加函数)				        
//
//PARAMETERS:当前话音用户指针
//
//PURPOSE AND ALGORITHMS:
//            每个TTI结束时,累加这个TTI内的误块数至该用户的m_iNumOfErrorBlock
//	          中累加这个TTI内的块数至该用户的m_iNumOfTotalBlock中
//                                               
//AUTHOR:     Li Jing
//
//MODIFIED RECORD: 
//            1. 20041101 错误统计时,一个TTI里只考虑A块的对错
//            2. 20041115
//            
//////////////////////////////////////////////////////////////////////////
void CMsManager::TTIBlockCumulate(CVoiceMs* VoiceMsPointer)
{
        float pp;
//        int BlockNum;
        float TTIMeanC2I;
        float n;
        int m;
		//float Ior2Ioc;
		bool flag;
        
//        BlockNum=VoiceMsPointer->GetTFIPointer()->iTransBLNum;

        TTIMeanC2I=VoiceMsPointer->GetTTIMeanC2I()/TTISize;
		TTIMeanC2I=(float)(10*log10(TTIMeanC2I));
		VoiceMsPointer->SetTTIMeanC2I(0.0);
        
		//Ior2Ioc=VoiceMsPointer->GetIor2Ioc();
		//Ior2Ioc/=TTISize;
        //Ior2Ioc=(float)(10*log10(Ior2Ioc));
        //VoiceMsPointer->SetIor2Ioc(0.0);

		n=VoiceMsPointer->BLERPrediction(TTIMeanC2I);
                		                       
//        for(int i=0;i<BlockNum;i++)
//        {
                m=VoiceMsPointer->GetNumOfTotalBlock()+1;
                VoiceMsPointer->SetNumOfTotalBlock(m);

//				m_lTotalVoiceBLNum++;

				pp=xUniform(0.0,1.0);		//produce a random between 0 and 1
                if(pp<n)
                {        
					    m=VoiceMsPointer->GetNumOfErrorBlock()+1;
                        VoiceMsPointer->SetNumOfErrorBlock(m);
						flag=false;
//						m_lTotalVoiceFailedBLNum++;
                }
				else
					flag=true;
				
				//用于软切换下误块率的统计add by slj 20041020
				if(m_iSlotCurrentNum>INITIALSLOT+TTISize && VoiceMsPointer->GetActiveSetSize()>1)
				{
					m=VoiceMsPointer->GetNumOfSHOBlock()+1;
                    VoiceMsPointer->SetNumOfSHOBlock(m);
					m_lTotalBLNumInSHO ++;
					
                    if(pp<n)
					{        
					    m=VoiceMsPointer->GetNumOfSHOFailedBlock()+1;
                        VoiceMsPointer->SetNumOfSHOFailedBlock(m);
			 			m_lTotalFailedBLNumInSHO ++;
					} 
				}
//        }

		VoiceMsPointer->OuterLoopPowerControl(flag);
        
}



//////////////////////////////////////////////////////////////////////////
//TITLE:      OutageAndDropJudgement(outage及drop判断函数)				        
//
//PARAMETERS:当前话音用户指针
//
//PURPOSE AND ALGORITHMS:
//            每个窗口结束时,计算这个窗口时间内的误块率,若是高于15%,则
//            为outage,若是高于50%,则droptimer++,并进行重撒。
//                                               
//AUTHOR:     Li Jing
//
//CALLING FUNCTIONS:
//
//MODIFIED RECORD: 
//            1. 20041115
//            
//////////////////////////////////////////////////////////////////////////
void CMsManager::OutageAndDropJudgement(CVoiceMs* VoiceMsPointer)
{
        int m,n;
        float BLER;
        float a,b;
        
		if(m_iSlotCurrentNum>INITIALSLOT+WindowSize)
		{
            m=VoiceMsPointer->GetTotalWindow()+1;
            VoiceMsPointer->SetTotalWindow(m);

			m_lTotalVoiceBLNum+=VoiceMsPointer->GetNumOfTotalBlock();
		    m_lTotalVoiceFailedBLNum+=VoiceMsPointer->GetNumOfErrorBlock();
        
            a=(float)(VoiceMsPointer->GetNumOfErrorBlock());
            b=(float)(VoiceMsPointer->GetNumOfTotalBlock());
            BLER=a/b; 
            VoiceMsPointer->SetWindowBLER(BLER);
        
		    if(BLER>OutageThreshold)
			{
                m=VoiceMsPointer->GetTotalOutageWindow()+1;
                VoiceMsPointer->SetTotalOutageWindow(m);
			}        
        
		    if(BLER>DropThreshold)
            {
                n=VoiceMsPointer->GetDropTimer()+1;
				VoiceMsPointer->SetDropTimer(n);
				if(n==3)
				{
			        m_iDropUserOfVoice++;
				    VoiceMsPointer->SetIsDropped(true);
                    m_iUnsatisfiedUserOfVoice++;
                    VoiceMsPointer->SetServiceLength(MeanCallTime*1500);
				    //单位为时隙
                    //这样做是为了等会判断服务结束,以进行重撒

					//Added by Li Jing for debugging,20041104
					//统计掉话用户信息,包括当前时隙,用户ID,基站ID以及用户和基站距离,当前的C2I等
	   	            SECTORID_TYPE SectorID = VoiceMsPointer->m_aMonitorSector[VoiceMsPointer->GetBestSectorIndex()].stSectorID;
		            int iCellm = SectorID.stCellID.m;
		            int iCelln = SectorID.stCellID.n;
		            int iSectorIndex = SectorID.s;
		            float fDistance = DistanceCaculte(VoiceMsPointer->GetMsLocation(),SectorID);

				    CStdioFile f;
		            char buf[50];
		            f.Open("DroppedVoiceUsers.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
		            f.SeekToEnd();

					_itoa(m_iSlotCurrentNum,buf,10);
		            f.WriteString(buf);
		            f.WriteString("\t");
		            
					_itoa(VoiceMsPointer->GetMsID(),buf,10);
		            f.WriteString(buf);
		            f.WriteString("\t(");

		            _itoa(iCellm,buf,10);
		            f.WriteString(buf);
		            f.WriteString(",");
		            _itoa(iCelln,buf,10);
		            f.WriteString(buf);
		            f.WriteString(",");
		            _itoa(iSectorIndex,buf,10);
		            f.WriteString(buf);
		            f.WriteString(")\t");

		            _gcvt(fDistance,10,buf);
		            f.WriteString(buf);
		            f.WriteString("\t");

					_gcvt(VoiceMsPointer->GetC2I(),10,buf);
		            f.WriteString(buf);
		            f.WriteString("\n");
		
		            f.Close();
				}
		    }
		    else
                VoiceMsPointer->SetDropTimer(0);

		}

		VoiceMsPointer->SetNumOfErrorBlock(0);
		VoiceMsPointer->SetNumOfTotalBlock(0);
}



//////////////////////////////////////////////////////////////////////////
//TITLE:      VoiceStatistics(话音统计函数)				        
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
//            在每个Drop结束时由DataStatics调用,计算出话音用户的接入阻塞
//            率、中断率及掉话率,并写入相应的文件中
//                                               
//AUTHOR:     Li Jing
//
//CALLING FUNCTIONS:
//
//NOTES:      增加了DROP结束时,对话音用户链表上还未结束通话的用户的处理,以
//            增加统计的精确性
//            
//////////////////////////////////////////////////////////////////////////                
void CMsManager::VoiceStatistics()   
{
	float a,b,c;
	CStdioFile f;
	char buf[50];
		
	POSITION pos;
	pos=m_VoiceList.GetHeadPosition();
	CVoiceMs* pVoiceMs=NULL;
	
	while(pos!=NULL)                    
	//循环处理此时的话音用户
	{
		pVoiceMs=m_VoiceList.GetNext(pos);
		
		if(pVoiceMs->IsAdmitted())
		//the user who has been admitted successfully
		{
	            if(pVoiceMs->GetTotalWindow()>=1)
	            {        
	                    a=(float)(pVoiceMs->GetTotalOutageWindow());
		                b=(float)(pVoiceMs->GetTotalWindow());
		                c=a/b;
		                pVoiceMs->SetOutageRatio(c);
		                 
		                if(c>UserOutageThreshold)
						{
		                    m_iOutageUserOfVoice++;
					        if(pVoiceMs->IsDropped()==false)
					            m_iUnsatisfiedUserOfVoice++;
						}
		                        //对于已经接纳成功且通话时间已超过一个window的用户,按照现在的
		                        //中断率来判断它是否outage user
		        }
		        else
		                m_iVoiceUserOfCurrentDrop--;
		                //对于通话时间还不到一个window的用户,由于无法计算,就将这个用户排除统计
		}
		else
		                m_iVoiceUserOfCurrentDrop--;
		                //对于还未接纳成功且还没有超时的用户,也将这个用户排除统计
	}
		                
    //calculate the statistics
	m_fBlockRatioOfVoice=float(m_iBlockUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
	m_fOutageRatioOfVoice=float(m_iOutageUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
	m_fDropRatioOfVoice=float(m_iDropUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
	m_fSatisfiedRadioOfVoice=float(m_iVoiceUserOfCurrentDrop-m_iUnsatisfiedUserOfVoice)/float(m_iVoiceUserOfCurrentDrop);
	m_fMeanVoiceBLER=(float)m_lTotalVoiceFailedBLNum/(float)(m_lTotalVoiceBLNum);
	
	//SHO开销 add by slj
	for ( int i = 0; i < ActiveSetMaxSize; i++)
	{
		m_lTotalSlotOfActiveSetSize += m_lSlotOfActiveSetSize[i];    		
	}

	for ( int j = 0; j < ActiveSetMaxSize; j++)
	{
		m_fScaleOfActiveSetSize[j] = float(m_lSlotOfActiveSetSize[j])/float(m_lTotalSlotOfActiveSetSize);  //激活集内不同扇区数所占时间比例
	}
	for ( int k = 0; k < ActiveSetMaxSize; k++)		

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -