📄 gbptl.cpp
字号:
#include <malloc.h>
#include <time.h>
#include "gbptl.hpp"
CGBPdu::CGBPdu():CPduBase()
{
Init();
}
void CGBPdu::Init()
{
lpGmm=0;
lpllc=0;
Frame=0;
pNS=0;
Frame=0;
AssembleLeng=0;
pBSSGPMessage=0;
LLCleng=0;
FrameLen=0;
}
unsigned short GetIeLen(unsigned char *ptr)
{
if(!ptr)
return 0;
unsigned short len1;
// if((*ptr)&0x80)//高位为1时表示1个字节,为0时为2个字节TLV格式
len1=(*ptr)&127;
// else
// len1=((*ptr)<<8)|*(ptr+1);
return len1;
}
UINT8 *CGBPdu::SaveIE(UINT8*ptr,UINT8 ID,UINT16 len)
{
UINT16 len1=GetIeLen(ptr+1);
if(len1>len)
return (UINT8*)0;
UINT8*ptemp=ptr;
UINT8 temp=*ptemp;
*ptemp=ID;
ptr=SaveIE(ptr);
*ptemp=temp;
return ptr;
}
char CGBPdu::Decode(UINT8 *ptr,UINT16 len)
{
Frame=ptr;
FrameLen=len;
char r=CGBPdu_ERROR_INVLID;
UINT8 *p=ptr;
ptr++;
UINT8 *pEnd=ptr+4;
while(ptr<pEnd)
{
if((*ptr++)&1)
goto END;
}
return CGBPdu_ERROR_INVLID;
END:
switch(ptr-p)
{
case 0x02:
{
unsigned short Dlci=((((unsigned short)(*p)&0xFc))<<2)|(((*(p+1))&0xF0)>>4);
PutIE(IE_FRAME_DLCI,2,(UINT8*)&Dlci);
}
break;
case 0x04:
break;
}
return NsDecode(ptr,len-(ptr-p));
}
//从网络业务层开始
char CGBPdu::NsDecode(UINT8 *ptr, UINT16 len)
{
pNS=ptr;
if(!ptr)
return CGBPdu_ERROR_NULL;
if(len<2)
return CGBPdu_ERROR_SHORT;
char r=CGBPdu_ERROR_INVLID;
PutIE(IE_NS_PDU_TYPE,1,ptr);
switch(*ptr)
{
case NS_UNITDATA:
r=NsUnitdata(ptr+1,len-1);
break;
case NS_RESET:
r=NsReset(ptr+1,len-1);
break;
case NS_RESET_ACK:
r=NsResetAck(ptr+1,len-1);
r=0;
break;
case NS_BLOCK:
r=NsBlock(ptr+1,len-1);
break;
case NS_BLOCK_ACK:
r=NsBlockAck(ptr+1,len-1);
break;
case NS_ACIVE_ACK:
case NS_ACIVE:
case NS_UNBLOCK_ACK:
case NS_UNBLOCK:
r=NsUnblock(ptr+1,len-1);
break;
case NS_STATUS:
r=NsStatus(ptr+1,len-1);
break;
}
return r;
}
char CGBPdu::NsUnitdata(UINT8 *ptr, UINT16 len)
{
ptr++;
PutIE(IE_NS_BVCI,2,ptr);
ptr+=2;
return BSSGPDecode(ptr,len-4);
}
char CGBPdu::NsReset(UINT8 *ptr,UINT16 len)
{
UINT8*p=ptr;
if(NS_CAUSE!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_CAUSE1,len);//原因Cause
if(!ptr)
return CGBPdu_ERROR_SHORT;
if(NS_VCI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_VCI,len-(ptr-p));//NSVCI
if(!ptr)
return CGBPdu_ERROR_SHORT;
if(NS_NSEI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_NSEI,len-(ptr-p));//NSEI
if(!ptr)
return CGBPdu_ERROR_SHORT;
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
UINT8* CGBPdu::SaveIE(UINT8 *ptr)
{
// if((*(ptr+1))&0x80)//高位为1时表示1个字节,为0时为2个字节TLV格式
// {
unsigned char len1=(*(ptr+1))&127;
PutIE(*ptr,len1,ptr+2);
ptr+=len1+2;
// }
// else
/* {
unsigned short len1=((*(ptr+1))<<8)|*(ptr+2);
PutIE(*ptr,len1,ptr+3);
ptr+=len1+3;
}
*/ return ptr;
}
/*
8 7 6 5 4 3 2 1
0 0 0 0 0 0 0 0 Cause
0 0 0 0 0 0 0 1 NS-VCI
0 0 0 0 0 0 1 0 NS PDU
0 0 0 0 0 0 1 1 BVCI
0 0 0 0 0 1 0 0 NSEI
other values reserved for future use
*/
char CGBPdu::NsResetAck(UINT8 *ptr,UINT16 len)
{
UINT8*p=ptr;
if(NS_VCI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_VCI,len-(ptr-p));//NS-VCI
if(!ptr)
return CGBPdu_ERROR_SHORT;
if(NS_NSEI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_NSEI,len-(ptr-p));//NS_NSEI
if(!ptr)
return CGBPdu_ERROR_SHORT;
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
char CGBPdu::NsBlock(UINT8 *ptr,UINT16 len)
{
UINT8*p=ptr;
if(NS_CAUSE!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_CAUSE1,len-(ptr-p));//原因
if(!ptr)
return CGBPdu_ERROR_SHORT;
if(NS_VCI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_VCI,len-(ptr-p));//NS-VCI
if(!ptr)
return CGBPdu_ERROR_SHORT;
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
char CGBPdu::NsBlockAck(UINT8 *ptr,UINT16 len)
{
if(NS_VCI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_VCI,len);//NS-VCI
if(!ptr)
return CGBPdu_ERROR_SHORT;
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
char CGBPdu::NsUnblock(UINT8 *ptr,UINT16 len)
{
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
char CGBPdu::NsStatus(UINT8 *ptr,UINT16 len)
{
UINT8 *p=ptr;
if(NS_CAUSE!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_NS_CAUSE1,len-(ptr-p));//原因
if(!ptr)
return CGBPdu_ERROR_SHORT;
for(int i=0;i<3;i++)
{
if(LENGTH)
goto END;
switch(*ptr)
{
case NS_BVCI:
ptr=SaveIE(ptr,IE_NS_BVCI,len-(ptr-p));
if(!ptr)
goto END;
break;
case NS_VCI:
ptr=SaveIE(ptr,IE_NS_VCI,len-(ptr-p));
if(!ptr)
goto END;
break;
case NS_PDU:
ptr=SaveIE(ptr,IE_NS_PDU,len-(ptr-p));
default:
goto END;
}
}
END:
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
char CGBPdu::BSSGPDecode(UINT8 *ptr, UINT16 len)
{
pBSSGPMessage=ptr;
PutIE(IE_BSSGP_PDU_TYPE,1,ptr);
char r=CGBPdu_ERROR_INVLID;
switch(*ptr)
{
case DL_UNITDATA:
r=DLUNITDATADecode(ptr+1,len-1);
break;
case UL_UNITDATA:
r=ULUNITDATADecode(ptr+1,len-1);
break;
case RA_CAPABILITY:
r=RACAPABILITYDecode(ptr+1,len-1);
break;
case PAGING_PS:
r=PAGINGPSDecode(ptr+1,len-1);
break;
case PAGING_CS:
r=PAGINGCSDecode(ptr+1,len-1);
break;
case RA_CAPABILITY_UPDATE:
r=RACAPABILITYUPDATEDecode(ptr+1,len-1);
break;
case RA_CAPABILITY_UPDATE_ACK:
r=RACAPABILITYUPDATEACKDecode(ptr+1,len-1);
break;
case RADIO_STATUS:
r=RADIOSTATUSDecode(ptr+1,len-1);
break;
case SUSPEND:
r=SUSPENDDecode(ptr+1,len-1);
break;
case SUSPEND_ACK:
r=SUSPENDACKDecode(ptr+1,len-1);
break;
case SUSPEND_NACK:
r=SUSPENDNACKDecode(ptr+1,len-1);
break;
case RESUME:
r=RESUMEDecode(ptr+1,len-1);
break;
case RESUME_ACK:
r=RESUMEACKDecode(ptr+1,len-1);
break;
case RESUME_NACK:
r=RESUMENACKDecode(ptr+1,len-1);
break;
case FLUSH_LL:
r=FLUSHLLDecode(ptr+1,len-1);
break;
case FLUSH_LL_ACK:
r=FLUSHLLACKDecode(ptr+1,len-1);
break;
case LLC_DISCARDED:
r=LLCDISCARDEDDecode(ptr+1,len-1);
break;
case FLOW_CONTROL_BVC:
r=FLOWCONTROLBVCDecode(ptr+1,len-1);
break;
case FLOW_CONTROL_BVC_ACK:
r=FLOWCONTROLBVCACKDecode(ptr+1,len-1);
break;
case FLOW_CONTROL_MS:
r=FLOWCONTROLMSDecode(ptr+1,len-1);
break;
case FLOW_CONTROL_MS_ACK:
r=FLOWCONTROLMSACKDecode(ptr+1,len-1);
break;
case BVC_BLOCK:
r=BVCBLOCKDecode(ptr+1,len-1);
break;
case BVC_BLOCK_ACK:
r=BVCBLOCKACKDecode(ptr+1,len-1);
break;
case BVC_UNBLOCK:
r=BVCUNBLOCKDecode(ptr+1,len-1);
break;
case BVC_UNBLOCK_ACK:
r=BVCUNBLOCKACKDecode(ptr+1,len-1);
break;
case BVC_RESET:
r=BVCRESETDecode(ptr+1,len-1);
break;
case BVC_RESET_ACK:
r=BVCRESETACKDecode(ptr+1,len-1);
break;
case STATUS:
r=STATUSDecode(ptr+1,len-1);
break;
case SGSN_INVOKE_TRACE:
r=SGSNINVOKETRACEDecode(ptr+1,len-1);
break;
case DOWNLOAD_BSS_PFC:
r=DOWNLOADBSSPFCDecode(ptr+1,len-1);
break;
case CREATE_BSS_PFC:
r=CREATEBSSPFCDecode(ptr+1,len-1);
break;
case CREATE_BSS_PFC_ACK:
r=CREATEBSSPFCACKDecode(ptr+1,len-1);
break;
case CREATE_BSS_PFC_NACK:
r=CREATEBSSPFCNACKDecode(ptr+1,len-1);
break;
case MODIFY_BSS_PFC:
r=MODIFYBSSPFCDecode(ptr+1,len-1);
break;
case MODIFY_BSS_PFC_ACK:
r=MODIFYBSSPFCACKDecode(ptr+1,len-1);
break;
case DELETE_BSS_PFC:
r=DELETEBSSPFCDecode(ptr+1,len-1);
break;
case DELETE_BSS_PFC_ACK:
r=DELETEBSSPFCACKDecode(ptr+1,len-1);
break;
}
return r;
}
char CGBPdu::DLUNITDATADecode(UINT8 *ptr, UINT16 len)
{
UINT8*p=ptr;
PutIE(IE_BSSGP_CUR_TLLI,4,ptr);
ptr+=4;
PutIE(IE_BSSGP_QOS_PROFILE,3,ptr);
ptr+=3;
if(PDU_SURVIVALTIME!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_BSSGP_PDU_LIFETIME,len-(ptr-p));
while(*ptr!=0x0e)
{
if(LENGTH)
return CGBPdu_ERROR_INVLID;
switch(*ptr)
{
case TLLI:
ptr=SaveIE(ptr,IE_BSSGP_OLD_TLLI,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case MSRADIOACCESSCAPABILITY:
ptr=SaveIE(ptr,IE_BSSGP_MS_RADIO_ACCESS,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case PRIORITY:
ptr=SaveIE(ptr,IE_BSSGP_PRIORITY,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case DRX:
ptr=SaveIE(ptr,IE_BSSGP_DRX_PARAMETERS,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case IMSI:
ptr=SaveIE(ptr,IE_BSSGP_IMSI,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case ALIGNMENT:
ptr=SaveIE(ptr,IE_BSSGP_ALIGNMENT_OCTETS,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case LSA:
ptr=SaveIE(ptr,IE_BSSGP_LSA_INFORMATION,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
default:
return CGBPdu_ERROR_INVLID;//LLCDecode(ptr+2,*ptr+1);
}
}
char Len=0;
switch(*(ptr+1)&0x80)
{
case 0x80:
LLCleng=(*(ptr+1))&127;
AssembleLeng=ptr-Frame+LLCleng+2;
Len=2;
break;
case 0:
LLCleng=((*(ptr+1))<<8)+(*(ptr+2));
AssembleLeng=ptr-Frame+LLCleng+3;
Len=3;
}
return LLCDecode(ptr+Len,LLCleng);
}
char CGBPdu::ULUNITDATADecode(UINT8 *ptr, UINT16 len)
{
UINT8*p=ptr;
PutIE(IE_BSSGP_CUR_TLLI,4,ptr);
ptr+=4;
PutIE(IE_BSSGP_QOS_PROFILE,3,ptr);
ptr+=3;
if(CGI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_BSSGP_CGI,len-(ptr-p));//CGI
if(!ptr)
return CGBPdu_ERROR_SHORT;
while(*ptr!=0x0e)
{
if(ptr-p>=len)
return CGBPdu_ERROR_SHORT;
switch(*ptr)
{
case ALIGNMENT:
ptr=SaveIE(ptr,IE_BSSGP_ALIGNMENT_OCTETS,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case LSA:
ptr=SaveIE(ptr,IE_BSSGP_LSA_INFORMATION,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
default:
return CGBPdu_ERROR_INVLID;
}
}
char Len=0;
switch(*(ptr+1)&0x80)
{
case 0x80:
LLCleng=(*(ptr+1))&127;
Len=2;
AssembleLeng=ptr-Frame+LLCleng+2;
break;
case 0:
LLCleng=((*(ptr+1))<<8)+(*(ptr+2));
Len=3;
AssembleLeng=ptr-Frame+LLCleng+3;
}
return LLCDecode(ptr+Len,len-(ptr+Len-p));
}
char CGBPdu::RACAPABILITYDecode(UINT8 *ptr, UINT16 len)
{
UINT8*p=ptr;
if(TLLI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_BSSGP_CUR_TLLI,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
if(MSRADIOACCESSCAPABILITY!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_BSSGP_MS_RADIO_ACCESS,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
char CGBPdu::PAGINGPSDecode(UINT8 *ptr, UINT16 len)
{
UINT8*p=ptr;
if(IMSI!=*ptr)
return CGBPdu_ERROR_INVLID;
ptr=SaveIE(ptr,IE_BSSGP_IMSI,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
UINT8 i=9;
UINT8 QosState=1;
while(i--)
{
if(ptr-p>len&&QosState)
return CGBPdu_ERROR_INVLID;
switch(*ptr)
{
case QOS:
i=1;
QosState=0;
ptr=SaveIE(ptr,IE_BSSGP_QOS_PROFILE,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case DRX:
ptr=SaveIE(ptr,IE_BSSGP_DRX_PARAMETERS,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case BVCIIE:
ptr=SaveIE(ptr,IE_BSSGP_BVCIIE,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case LOCATION:
ptr=SaveIE(ptr,IE_BSSGP_LOCATION_AREA,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case ROUTEING:
ptr=SaveIE(ptr,IE_BSSGP_ROUTEING_AREA,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case BSSAREAINDICATION:
ptr=SaveIE(ptr,IE_BSSGP_BSS_AREA_INDICATION,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case PFI:
ptr=SaveIE(ptr,IE_BSSGP_PFI,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case ABQP:
ptr=SaveIE(ptr,IE_BSSGP_AGGREGATE_BSS_QOS_PROFILE,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
break;
case TMSI:
ptr=SaveIE(ptr,IE_BSSGP_TMSI,len-(ptr-p));
if(!ptr)
return CGBPdu_ERROR_SHORT;
default:
if(QosState)
return CGBPdu_ERROR_INVLID;//必选项没有出现QOS
goto END;
}
}
END:
AssembleLeng=ptr-Frame;
return CGBPdu_SUCCESS;
}
char CGBPdu::PAGINGCSDecode(UINT8 *ptr, UINT16 len)
{
UINT8*p=ptr;
if(IMSI!=*ptr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -