📄 cdatams.cpp
字号:
/** Copyright (c) 2004,北京邮电大学无线研究中心
* All rights reserved.
*
* 文件名称:CDataMs.cpp
* 文件标识:数据移动台模块类实现
* 摘 要:实现CDataMs类
*
* 当前版本:1.0
* 作 者:陈美娅
* 完成日期:2004年
*/
#include "CServiceArea.h"
#include "CDataMs.h"
#include "CCell.h"
#include "CSector.h"
#include "CMsManager.h"
#include "CLinkPrediction.h"
#include "CChannelModel.h"
#include "systemsim.h"
#include "iostream.h"
const int CDataMs::m_iSlideWindowSize = 10;
const float CDataMs::m_fAlpha = (float)0.75;
const float qq=2;
//by slj 20050413
CDataMs::~CDataMs()
{
HSRateTableDelete();
//by cmy0316
delete m_pSlideWindow;
}
//a初始化相关方法
//////////////////////////////////////////////////////////////////////////
//
// TITLE: 数据移动台初始化函数
//
// PURPOSE: 初始化数据移动台相关属性
//
// SAMPLE CALL: pHttpDataMs->DataMsInitialize()
//
// CALLED BY FUNCTIONS:
//
// CALLING FUNCTIONS:
// HSDSCHInitialize()
// DCHInitialize()
//
// AUTHOR: Chen Meiya
//
// DATE: 04/04(MM/YY)
//
////////////////////////////////////////////////////////////////////////////
void CDataMs::DataMsInitialize(CLinkPrediction *pLinkPrediction, long lTotalSucfulBitNum)
{
//信道状态相关属性初始化
m_bIsInAdmittedList = false;
m_iBestSecTimer = 0;
//数据传输相关属性初始化
m_lDataQueueSize = 0; //数据队列中数据量
m_iDataQueueEmptyTimer = 7500; //数据队列为空计时器
m_bIsTransNow = false; //移动台是否正在传输
m_iTTISucfulBLNum = 0; //当前TTI内传对的块数
m_iTTISucfulBitNum = 0; //当前TTI内传对的比特数
m_iTTIFailedBLNum = 0; //当前TTI内达到最大重传次数的块数
m_iTTIFailedBitNum = 0; //当前TTI内打到最大重传次数传输失败比特数
m_iSlotNumRemained = 0; //当前TTI剩余时隙数
m_fRatePredictC2I = 0.0; //进行速率预测的C2I
m_pLinkPrediction = pLinkPrediction; //指向链路预测对象
m_fTTIBLER = 0.0; //链路级提供的传输块差错率
m_fMeanC2I = 0.0; //TTI内所有时隙C2I的平均值
m_ii=0;
// m_iPowCrtlFailedTimer = 0; //当前功控失败计时器
for( int itemp = 0; itemp < MAXBLNUM ; itemp ++ )
{
m_iaBLTransNum[ itemp ] = 0;
}
for( itemp = 0; itemp < MAXTTISLOTNUM ; itemp ++ )
{
m_fSlotC2IindB [itemp ] = 0.0;
}
for( itemp = 0; itemp < HSDSCHTTISLOTNUM ; itemp ++ )
{
m_fHSDSCHSlotC2IindB [itemp ] = 0.0;
}
// if(m_pMsManager->m_iScheduleAlgorithm==2 || m_pMsManager->m_iScheduleAlgorithm==4 || m_pMsManager->m_iScheduleAlgorithm==6) //20051205 20060111
// {
m_fAverageRate=1.0 ; //初始化平均传输速率
// }
// else
// {
// m_fAverageRate=0.0;
// }
//20051205
if(m_pMsManager->m_iScheduleAlgorithm==4)
{
switch(m_iClassIndex)
{
case 1: m_fWeightedClassPra=(float)1; break;
case 2: m_fWeightedClassPra=(float)qq; break;
case 3: m_fWeightedClassPra=(float)pow(qq,2); break;
case 4: m_fWeightedClassPra=(float)pow(qq,3); break;
default:break;
}
}
else if(m_pMsManager->m_iScheduleAlgorithm==5)
{
m_fWeightedClassPra=(float)1;
}
//20051206
if(m_pMsManager->m_iScheduleAlgorithm==5)
{
switch(m_iClassIndex)
{
case 1: m_fTargetQos=(float)20000; break;
case 2: m_fTargetQos=(float)40000; break;
case 3: m_fTargetQos=(float)60000; break;
case 4: m_fTargetQos=(float)80000; break;
default:break;
}
}
m_fCurrentQos=0;
if(m_pMsManager->m_iScheduleAlgorithm==6) //20060111
{
switch(m_iClassIndex)
{
case 1:m_fBeta=(float)0.001;
m_fTarget=76.8; break;
case 2:m_fBeta=(float)0.001;
m_fTarget=76.8; break;
case 3:m_fBeta=(float)0.001;
m_fTarget=76.8; break;
case 4:m_fBeta=(float)0.001;
m_fTarget=76.8; break;
default:break;
}
}
//zl 20060302 for Video
m_iTotalBitinBuffer=32000*DelayLimit;
m_iBitinBuffer=0;
m_iEmptyBitinBuffer=32000*DelayLimit;
m_iDelayLimitinBuffer=DelayLimit*1000;
m_iBufferDelay=m_iDelayLimitinBuffer;
m_iVideoDropNum=0;
m_iVideoTotalNum=0;
m_fDropRatio=0.0;
m_fAlfa=-0.5;
m_fW=1;
m_iDropTimer=0;
//zl 20060308
m_bIsDroped=false;
m_iTotalDropTime=0;
//zl 20060328
m_iTotalVideoPacketNum=1;
m_iVideoPacketDropNum=0;
m_fVideoPacketDropRatio=0.0;
m_iTotalVideoIFrameNum=0;
m_iVideoIFrameDropNum=0;
m_fVideoIFrameDropRatio=0.0;
m_bIsCurrentPacketOver = false;
m_iCurrentPacketDelay = 0;
m_bIsCurrentPCOver = false;
m_iCurrentPCDelay = 0;
m_lCurrentPCBitNum = 0;
m_iTransPacketNum = 0;
m_iTransPCNum = 0;
m_lSucfulPCBitNum = lTotalSucfulBitNum;
m_lCurrentPCBitNum = 0;
//分组移动台所需要统计量
m_iTTISucfulPacketNum = 0;
m_iTTIFailedPacketNum = 0;
//统计相关属性初始化
m_iTotalSucfulBLNum = 0; //移动台成功接收的块数
m_iTotalFailedBLNum = 0; //移动台接收失败的块数
m_lTotalSucfulBitNum =lTotalSucfulBitNum ;//移动台成功接收比特数
m_lTotalFailedBitNum = 0; //移动台接收失败的比特数 20051206
m_iASTTimer = 0; //移动台数据队列不为空计时器
m_fAST = 0.0; //移动台的Active Session Throughput
m_fServiceThrput = 0.0; //下行链路吞吐量
m_iTotalSucfulPacketNum = 0; //移动台成功接收的分组数
m_iTotalFailedPacketNum = 0; //移动台接收失败的分组数
m_fPacketErrorRate = 0.0; //移动台分组错误率
m_iTotalPacketDelay = 0; //移动台接收分组的总时延
m_fAveragePacketDelay = 0.0; //移动台接收分组的平均时延
m_iPacketCallNum = 0; //HTTP业务分组呼叫数
m_iPacketCallDelay = 0; //HTTP业务分组呼叫总时延
m_fAveragePCDelay = 0; //HTTP业务平均分组呼叫时延
m_lTotalSucfulPCBitNum = 0; //HTTP业务分组呼叫总比特数
m_fPacketCallThrput = 0; //HTTP业务吞吐量
//for compile
m_fPilotStrenThreshold = 0; //根据数值暂时取定为-95
m_fPilotStrenHyst = 0; //暂时不考虑门限滞后
//end of for compile
//确定数据移动台处在DCH信道或HSDSCH信道,并进行信道初始化
float fBestSecPilotStrength = m_aMonitorSector[ m_iBestSectorIndex ].fPilotPower;
//notice 这里扇区导频功率的单位是从mw变成dBm
m_fBestSecPilotStrengthindBm = (float) ( 10*log10(fBestSecPilotStrength) );
//for compile
CStdioFile f;
char buf[50];
// 打开数据文件准备写
if(!f.Open("CDataMsFile.txt",CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite))
{
#ifdef _DEBUG
afxDump<<"Unable to open file"<<"\n"; //异常处理
#endif
}
f.SeekToEnd();
// f.WriteString("移动台\t最佳扇区\t距离\t导频强度\tSNR\n");
_itoa(m_iMsID,buf,10);
f.WriteString(buf);
f.WriteString("\t(");
//by zl20050427
SECTORID_TYPE tempSectorID;
if(m_eUsertype == HSDSCHData)
{
GetLocationSectorIndex();
tempSectorID= m_aMonitorSector[m_iLocationSectorIndex].stSectorID;
}
else
{
tempSectorID= m_aMonitorSector[m_iBestSectorIndex].stSectorID;
}
_itoa(tempSectorID.stCellID.m,buf,10);
f.WriteString(buf);
f.WriteString(",");
_itoa(tempSectorID.stCellID.n,buf,10);
f.WriteString(buf);
f.WriteString(",");
_itoa(tempSectorID.s,buf,10);
f.WriteString(buf);
f.WriteString(")\t");
float fDistance = m_pMsManager->DistanceCaculte(m_stMsLocation,tempSectorID);
_gcvt(fDistance,8,buf);
f.WriteString(buf);
f.WriteString("\t");
//20051205
_itoa(m_iSectorLocationIndex,buf,10);
f.WriteString(buf);
f.WriteString("\t");
_itoa(m_iClassIndex,buf,10);
f.WriteString(buf);
f.WriteString("\t");
_gcvt(m_fBestSecPilotStrengthindBm,8,buf);
f.WriteString(buf);
f.WriteString("\t");
float fPilotSNR = m_aMonitorSector[m_iBestSectorIndex].fPilotSNR;
_gcvt(fPilotSNR,8,buf);
f.WriteString(buf);
f.WriteString("\n");
f.Close();
//end of for compile
//by zl
if( m_eUsertype == DCHData )
{
DCHInitialize();
}
else if( m_eUsertype == HSDSCHData )
{
HSDSCHInitialize();
HSRateTableInitiailize(); //by slj 用于门限调整算法
switch(m_pMsManager->m_iScheduleAlgorithm)
{
case 1:
m_fScheduleAlgorithm = MAXC2I;
break;
case 2:
m_fScheduleAlgorithm = PROPFAIRNESS;
break;
case 3:
m_fScheduleAlgorithm = RANDOMR;
break;
case 4:
m_fScheduleAlgorithm = GradePF; //20051205
break;
case 5:
m_fScheduleAlgorithm = AdaptiveGPF; //20051219
break;
case 6:
m_fScheduleAlgorithm = Utility; //20060111
break;
case 7:
m_fScheduleAlgorithm = M_LWDF;//20060405 by huangfan
break;
case 8:
m_fScheduleAlgorithm = EXP; //20060405 by huangfan
break;
default:
break;
}
switch(m_pMsManager->m_iAlgorithm)
{
case 1:
m_fAlgorithm = AL1;
break;
case 2:
m_fAlgorithm = AL2;
break;
case 3:
m_fAlgorithm = AL3;
break;
case 4:
m_fAlgorithm = AL4;
break;
default:
break;
}
for ( int iloop = 0; iloop < MAXRATENUM;iloop++)
{
m_iCurSuccessfulEPNum[iloop]=0;
m_iCurErrorEPNum[iloop]=0;
}
//by cmy 0316
m_pSlideWindow = new bool[m_iSlideWindowSize];
for ( iloop = 0; iloop< m_iSlideWindowSize; iloop++)
{
m_pSlideWindow[iloop] = false;
}
m_iEPNuminWindow = 0;
}
//long-range Prediction 20051214
for (int i=0;i<orders;i++)
{
m_dweight[i]= (double)2*i/(orders*(orders-1)); //初始化加权
}
for (i=0;i<orders+2*DelayedSlot+1;i++)
{
m_fPreC2I[i]=0;
m_fCurC2I[i]=0;
}
for (i=0;i<DelayedSlot;i++)
{
m_fDelC2I[i]=0.0;
// m_bDelACK[i]=false; //20051228
// m_iDelMCS[i]=0;
}
m_iPreC2INum=0;
m_iDelC2INum=0;
m_fDelayedC2I=0.0;
m_fPredictedC2I=0.0;
/*
m_iDelNum=0;
m_bDelayedACK=false; //20051228
m_iDelayedMCS=0;
*/
////累加归属扇区中数据用户数
CSector *pLocationSec = m_pServiceArea->GetSector(m_stLocationSector);
int iDataMsNum = pLocationSec->GetTotalDataMsNum();
++iDataMsNum;
pLocationSec->SetTotalDataMsNum(iDataMsNum);
}
//b导频强度测量相关方法
//////////////////////////////////////////////////////////////////////////
//
// TITLE: 导频强度测量函数
//
// PURPOSE: 测量导频强度完成信道的切换
//
// SAMPLE CALL: pHttpDataMs->BestSecPilotStrenMonitor()
//
// CALLED BY FUNCTIONS: CMsManager::DataMsListProcess()
//
// CALLING FUNCTIONS:
// ObtainBestSector()
// DCHToDCHProcess()
// AUTHOR: Chen Meiya
//
// DATE: 04/04(MM/YY)
//
// REVISE:zhang lin
// DATE: 04/05
//
////////////////////////////////////////////////////////////////////////////
void CDataMs::BestPilotStrenMonitor(void)
{
if( IsTransmitNow() == true )
{
//移动台正在进行传输,则不进行DCH和DSCH信道之间的切换
}
else if( m_eUsertype == HSDSCHData )
{
//移动台处在扇区已经被调度上的DSCH用户队列中,则不进行DCH和DSCH信道之间的切换
}
else
{
//记录上一时隙最佳导频和用户类型
int iPreviousBestSecIndex = m_iBestSectorIndex ;
int iPreviousUserType = m_eUsertype;
//获取当前时隙最佳导频和导频强度
int iCurrentBestSecIndex = 0;
ObtainBestSector();
iCurrentBestSecIndex = m_iBestSectorIndex;
float fBestSecPilotStrength = m_aMonitorSector[ iCurrentBestSecIndex ].fPilotPower;
//notice 这里导频强度的单位是从mw变成dBm
m_fBestSecPilotStrengthindBm = (float) ( 10*log10(fBestSecPilotStrength) );
if( iPreviousUserType ==DCHData )
{
////处在DCH信道移动台的处理
//比较最佳扇区导频和相对门限
if( m_fBestSecPilotStrengthindBm > m_fPilotStrenThreshold + m_fPilotStrenHyst )
{
}
else
{
DCHToDCHProcess( iPreviousBestSecIndex, iCurrentBestSecIndex );
}
}
else
{
//notice 这里是对于用户类型不符合常规的错误提示
cout<<"用户类型错误!非DCH移动台和非DSCH移动台出现在数据移动台处理中。\n";
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -