📄 cmobile.cpp
字号:
//CALLING FUNCTIONS:
//
//NOTES: 软切换的算法与2000时略有不同
//
//////////////////////////////////////////////////////////////////////////
void CMobile::SHOMsgGenerator()
{
/* CStdioFile f;
char buf[50];
char FileName[40];
CString sp;
sp="Exception.txt";
strcpy(FileName,sp);*/
int i,j; //循环变量
int iLogicActiveSize=0; //逻辑激活集长度
int iBestSectorIndex,iWorstSectorIndex=-1,iTempIndex;
//最好基站下标,最差基站下标,临时基站下标(在监测集中的相对位置)
POSITION posTemp; //用于循环的位置指针
float fMaxPilotSNR=-1000.0; //初值设为一个很小的值,单位:dB
float fMinPilotSNR; //fMinC2I初值设为最大值
SOFTHANDOFFMESSAGE_TYPE* pTempSHOMsg=NULL;//临时软切换消息指针
if(m_ActiveSetList.IsEmpty()) //队列为空,返回
return;
else
{
posTemp=m_ActiveSetList.GetHeadPosition();
//取得链表头,并令临时指针指向链表头
while(posTemp!=NULL) //到达链表尾则结束循环
{
iTempIndex=m_ActiveSetList.GetAt(posTemp)->iIndexInMonitor;
//获得当前激活集扇区在监测集中的下标
if(m_aMonitorSector[iTempIndex].fPilotSNR>fMaxPilotSNR)
//找出最佳扇区(导频信噪比最大的那个)
{
fMaxPilotSNR=m_aMonitorSector[iTempIndex].fPilotSNR;
//记录下最大的导频信噪比
iBestSectorIndex=iTempIndex;
//记录下最佳扇区在监测集中的下标
}
m_ActiveSetList.GetNext(posTemp);
//指向链表中下一个扇区
}
m_aMonitorSector[iBestSectorIndex].bIsInActive=true;
//将最佳扇区的激活标志置为true
m_aMonitorSector[iBestSectorIndex].iStatusTimer=0;
//状态改变计数器置为0
fMinPilotSNR=fMaxPilotSNR;
//将最小导频信噪比初值设为最大导频信噪比
posTemp=m_ActiveSetList.GetHeadPosition();
//取得链表头,并令临时指针指向链表头
while(posTemp!=NULL)
//到达链表尾则结束循环
{
iTempIndex=m_ActiveSetList.GetAt(posTemp)->iIndexInMonitor;
//获得当前激活集扇区在监测集中的下标
if(iTempIndex!=iBestSectorIndex)
//找出不同于最佳扇区的扇区(导频信噪比最小的那个)
if(m_aMonitorSector[iTempIndex].bIsInActive=true)
//并且这个扇区的bIsInActive是true
if(m_aMonitorSector[iTempIndex].fPilotSNR<
fMinPilotSNR) //而且是当前最差扇区
{
iWorstSectorIndex=iTempIndex;
//记录当前最差扇区在监测集中的下标
fMinPilotSNR=
m_aMonitorSector[iTempIndex].fPilotSNR;
//记录当前最小的导频信噪比
}
m_ActiveSetList.GetNext(posTemp);
//指向链表中下一个扇区
}//得到的iBestSector,iWorstSector均是激活集中的扇区!都处于激活状态!
posTemp=m_SoftHandoffMessageList.GetHeadPosition();
//取得链表头,并令临时指针指向链表头
while(posTemp!=NULL)
//到达链表尾则结束循环
{
if(m_SoftHandoffMessageList.GetAt(posTemp)->bIsAdd)
//如果软切换消息是加入
iLogicActiveSize++;
//隐含的激活队列长度变化量加一
else //如果软切换消息是去掉
iLogicActiveSize--;
//隐含的激活队列长度变化量减一
m_SoftHandoffMessageList.GetNext(posTemp);
//指向链表中下一个软切换消息
}
iLogicActiveSize=iLogicActiveSize+m_iActiveSetSize;
//逻辑激活队列长度等于隐含的激活队列长度变化量加上原来的激活队列长度
for(i=0;i<19;i++)
for(j=0;j<SectorNumber;j++) //对监测扇区进行循环
{
if((i*SectorNumber+j)==iBestSectorIndex) //跳过最佳扇区
continue;
else
if(m_aMonitorSector[i*SectorNumber+j].bIsInActive)
//如果是否在激活集中的标志为真
{
if(m_aMonitorSector[iBestSectorIndex].fPilotSNR
-m_aMonitorSector[i*SectorNumber+j].fPilotSNR>
m_pMsManager->m_fSHOAs_Th+m_pMsManager->m_fSHOAs_Th_Hyst)
//如果最佳扇区的导频信噪比与当前扇区的导频信噪比之差
//大于软切换去掉的门限值加上门限滞后
{
m_aMonitorSector[i*SectorNumber+j].iStatusTimer++;
//当前循环的监测扇区结构体中的状态改变计数器加一
if(m_aMonitorSector[i*SectorNumber+j].iStatusTimer>
m_pMsManager->m_iSHOTimer)
//如果状态改变计数器大于软切换去掉定时器
//(m_iSHOTimer是以秒为单位的,要转换)
{
pTempSHOMsg=new SOFTHANDOFFMESSAGE_TYPE;
//产生一个新的软切换消息
pTempSHOMsg->iMonitorIndex=i*SectorNumber+j;
//将当前扇区下标赋予iMonitorIndex
pTempSHOMsg->bIsAdd=false;
//bIsAdd置为false(实际上就是去掉)
pTempSHOMsg->iWaitTime=
m_pMsManager->m_iSoftHandoffDelay;
//软切换的时延为0.2s(转换为slot数)
pTempSHOMsg->stTargetSector=
m_aMonitorSector[i*SectorNumber+j].stSectorID;
//目标扇区为当前扇区
m_SoftHandoffMessageList.AddTail(pTempSHOMsg);
//将生成的软切换消息加入软切换消息队列
m_iSHOMsgNum++;
//更新属性中的软切换消息队列长度
iLogicActiveSize--; //逻辑激活队列长度减一
m_aMonitorSector[i*SectorNumber+j].bIsInActive=false;
//当前扇区的是否在激活集中的标志置为false
m_aMonitorSector[i*SectorNumber+j].iStatusTimer=0;
//状态改变计数器清零
}
}
else
//如果最佳扇区的导频信噪比与当前扇区的导频信噪比之差小于门限值
m_aMonitorSector[i*SectorNumber+j].iStatusTimer=0;
//当前循环的候选扇区结构体中的状态改变计数器清零
}
else //如果是否在激活集中的标志为假,即不在激活集中
if((i*SectorNumber+j)!=iWorstSectorIndex)
//如果当前循环的扇区不是激活集中最差扇区
{
if(m_aMonitorSector[iBestSectorIndex].fPilotSNR
-m_aMonitorSector[i*SectorNumber+j].fPilotSNR<
m_pMsManager->m_fSHOAs_Th-m_pMsManager->m_fSHOAs_Th_Hyst)
//如果最佳扇区的导频信噪比与当前扇区的导频信噪比之差小于软切换加入的
//门限值减去门限滞后
{
m_aMonitorSector[i*SectorNumber+j].iStatusTimer++;
//当前扇区的状态改变计数器加一
if(m_aMonitorSector[i*SectorNumber+j].iStatusTimer>
m_pMsManager->m_iSHOTimer)
//如果状态改变计数器大于加入激活集的时间门限
{
if(iLogicActiveSize>=
ActiveSetMaxSize)
//如果逻辑激活集扇区个数大于激活集扇区最大个数
if(m_aMonitorSector[i*SectorNumber+j].fPilotSNR
-m_aMonitorSector[iWorstSectorIndex].fPilotSNR>
m_pMsManager->m_fSHOAs_Rep_Hyst)
//如果当前扇区的导频信噪比与最差激活扇区的导频信噪比之差
//大于替换滞后(1dB)
if(m_aMonitorSector[iWorstSectorIndex].bIsInActive
==false)
//如果激活集中的最差扇区已经发生过去掉或替换操作
//(bIsInActive为false),则此时不能发生替换操作
m_aMonitorSector[i*SectorNumber+j].iStatusTimer--;
//状态改变计数器减一
else //如果还没有发生过去掉或替换操作,
//则可以产生替换操作(先去掉,再加入)
{
pTempSHOMsg=new SOFTHANDOFFMESSAGE_TYPE;
//产生一个新的软切换消息
pTempSHOMsg->bIsAdd=false;
//bIsAdd置为false(实际上就是去掉)
pTempSHOMsg->iMonitorIndex=iWorstSectorIndex;
//将最差扇区下标赋予iMonitorIndex
pTempSHOMsg->stTargetSector=
m_aMonitorSector[iWorstSectorIndex].stSectorID;
//需要去掉的目标扇区为最差扇区
pTempSHOMsg->iWaitTime=
m_pMsManager->m_iSoftHandoffDelay;
//软切换的时延为200ms(转换为slot数)
m_SoftHandoffMessageList.AddTail(pTempSHOMsg);
//将产生的软切换消息加入队列
m_iSHOMsgNum++;
//更新属性中的软切换消息队列长度
m_aMonitorSector[iWorstSectorIndex].iStatusTimer=0;
//状态改变计数器清零
m_aMonitorSector[iWorstSectorIndex].bIsInActive=false;
//是否在激活集中的标志置为false
pTempSHOMsg=new SOFTHANDOFFMESSAGE_TYPE;
//产生一个新的软切换消息
pTempSHOMsg->bIsAdd=true;
//bIsAdd置为true(实际上就是加入)
pTempSHOMsg->iMonitorIndex=i*SectorNumber+j;
//将当前扇区下标赋予iMonitorIndex
pTempSHOMsg->stTargetSector=
m_aMonitorSector[i*SectorNumber+j].stSectorID;
//需要加入的目标扇区为当前扇区
pTempSHOMsg->iWaitTime=
m_pMsManager->m_iSoftHandoffDelay;
//软切换的时延为200ms(转换为slot数)
m_SoftHandoffMessageList.AddTail(pTempSHOMsg);
//将产生的软切换消息加入队列
m_iSHOMsgNum++;
//更新属性中的软切换消息队列长度
m_aMonitorSector[i*SectorNumber+j].iStatusTimer=0;
//状态改变计数器清零
m_aMonitorSector[i*SectorNumber+j].bIsInActive=true;
//是否在激活集中的标志置为true
posTemp=m_ActiveSetList.GetHeadPosition();
//取得链表头,并令临时指针指向链表头
while(posTemp!=NULL)
//到达链表尾则结束循环
{
iTempIndex=
m_ActiveSetList.GetAt(posTemp)->iIndexInMonitor;
//获得当前激活集扇区在监测集中的下标
if(iTempIndex!=iBestSectorIndex)
//找出不同于最佳扇区的扇区
if(m_aMonitorSector[iTempIndex].bIsInActive==true)
//并且这个扇区的bIsInActive是true
if(m_aMonitorSector[iTempIndex].fPilotSNR<
fMinPilotSNR)
//而且是最差扇区
{
iWorstSectorIndex=iTempIndex;
//记录下最差扇区在监测集中的下标
fMinPilotSNR=
m_aMonitorSector[iTempIndex].fPilotSNR;
//记录下最小的导频信噪比
}
m_ActiveSetList.GetNext(posTemp);
//指向链表中下一个扇区
}
}
else
//如果当前扇区的导频信噪比与最差扇区的导频信噪比之差
//小于替换的门限(1dB)
m_aMonitorSector[i*SectorNumber+j].iStatusTimer--;
//状态改变计数器减一
else //如果逻辑激活集扇区个数小于激活集扇区最大个数
//则直接产生将当前扇区加入激活集的软切换消息
{
pTempSHOMsg=new SOFTHANDOFFMESSAGE_TYPE;
//产生一个新的软切换消息
pTempSHOMsg->bIsAdd=true;
//bIsAdd置为true(实际上是加入)
pTempSHOMsg->iMonitorIndex=i*SectorNumber+j;
//将当前扇区下标赋予iMonitorIndex
pTempSHOMsg->iWaitTime=
m_pMsManager->m_iSoftHandoffDelay;
//软切换的时延为0.2s(转换为slot数)
pTempSHOMsg->stTargetSector=
m_aMonitorSector[i*SectorNumber+j].stSectorID;
//需要加入的目标扇区为当前扇区
m_SoftHandoffMessageList.AddTail(pTempSHOMsg);
//将产生的软切换消息加入队列
m_iSHOMsgNum++;
//更新属性中的软切换消息队列长度
m_aMonitorSector[i*SectorNumber+j].bIsInActive=true;
//是否在激活集中的标志置为true
m_aMonitorSector[i*SectorNumber+j].iStatusTimer=0;
//状态改变计数器清零
iLogicActiveSize++;
//逻辑激活集队列长度加一
}
}
}
else
//如果最佳扇区的导频信噪比与当前扇区的导频信噪比之差
//大于软切换加入的门限值
m_aMonitorSector[i*SectorNumber+j].iStatusTimer=0;
//当前扇区的状态改变计数器清零
}
}
}
}
//////////////////////////////////////////////////////////////////////////
//TITLE: SHOMsgProcess(软切换消息队列处理函数)
//
//PARAMETERS:NULL
//
//PURPOSE AND ALGORITHMS:
// 完成每个时隙内软切换消息等待时间递减的功能,并返回到时消息的数量
//
//AUTHOR: Li Jing
//
//CALLING FUNCTIONS:
// NULL
//
//////////////////////////////////////////////////////////////////////////
int CMobi
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -