📄 layer3infodecode.cpp
字号:
unsigned char elmId = 0;
unsigned char elmLen = 0;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_frequency_redefinition:input parameter error!");
return;
}
//Channel Description 3 bytes
pdu.PutIE(LAYER3INFO_IE_CHANNEL_DESCRIPTION, sizeof(SChannelDescription), (char *)pPdu);
offset += sizeof(SChannelDescription);
//Mobile Allocation
elmLen = msuBuf[offset++];
pdu.PutIE(LAYER3INFO_IE_MOBILE_ALLOCATION, sizeof(SMobileAllocation), (char *)(pPdu+offset));
offset += elmLen;
//Starting time
pdu.PutIE(LAYER3INFO_IE_START_TIME, sizeof(SStartTime), (char *)(pPdu+offset));
offset += sizeof(SStartTime);
if(offset < msu_len)
{
//存在可选参数
elmId = msuBuf[offset];
if(elmId == CELL_CHANNEL_DESCRIPTION)
{
elmLen = 16;
pdu.PutIE(LAYER3INFO_IE_CELL_CHANNEL_DESCRIPT, sizeof(SCellChannelDescrip), (char *)(pPdu+offset));
offset += elmLen;
}
}
}
void layer3_ho_cmd(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
unsigned char elmId = 0;
unsigned char elmLen = 0;
struct SCellDescription cell_descption;
struct SPowerCmdAndAccessType power_cmd;
struct SFrequencyList frequency_list;
struct SFrequencyChannelSeq frequency_channel_seq;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_ho_cmd:input parameter error!");
return;
}
//CELL description
memset(&cell_descption, 0, sizeof(cell_descption));
cell_descption.bcc = msuBuf[offset]&0x0f;
cell_descption.ncc = msuBuf[offset]&0x38 >> 3;
cell_descption.bcch_arfcn_h = msuBuf[offset++]&0xC0 >> 6;
cell_descption.bcch_arfcn_l = msuBuf[offset++];
pdu.PutIE(LAYER3INFO_IE_CELL_DESCRIPTION, sizeof(SCellDescription), (char *)&cell_descption);
pdu.PutIE(LAYER3INFO_IE_FIRST_CHANNEL_DESCRIPT_AFTER_TIME, sizeof(SChannelDescription), (char *)(pPdu+offset));
offset += sizeof(SChannelDescription);
//Handover reference
pdu.PutIE(LAYER3INFO_IE_HANDOVER_REFERENCE, sizeof(SHandoverReference), (char *)(pPdu+offset));
offset += sizeof(SHandoverReference);
//power command and access type
memset(&power_cmd, 0, sizeof(power_cmd));
power_cmd.power_level = msuBuf[offset] &0x1F;
power_cmd.atc = msuBuf[offset]&0x80>>7;
pdu.PutIE(LAYER3INFO_IE_POWER_COMMAND_AND_ACCESS_TYPE, sizeof(SPowerCmdAndAccessType), (char *)&power_cmd);
offset += sizeof(SPowerCmdAndAccessType);
while(offset < msu_len)
{
elmId = msuBuf[offset++];
switch(elmId)
{
case FRENQUENCY_SHORT_LIST_AFTER_TIME:
pdu.PutIE(LAYER3INFO_IE_FREQUENCY_SHORT_LIST_AFTER_TIME, sizeof(SFrequencyShortList), (char *)(pPdu+offset));
offset += sizeof(SFrequencyShortList);
break;
case FREQUENCY_LIST_AFTER_TIME:
memset(&frequency_list, 0, sizeof(frequency_list));
elmLen = msuBuf[offset++];
frequency_list.list_len = elmLen;
if((frequency_list.ptr = new unsigned char [elmLen]) != NULL)
{
memcpy(frequency_list.ptr, &msuBuf[offset], elmLen);
pdu.PutIE(LAYER3INFO_IE_FREQUENCY_LIST_AFTER_TIME, sizeof(SFrequencyList), (char *)&frequency_list);
}
offset += elmLen;
break;
case CELL_CHANNEL_DESCRIPTION:
elmLen = 16;
pdu.PutIE(LAYER3INFO_IE_CELL_CHANNEL_DESCRIPT, sizeof(SCellChannelDescrip), (char *)(pPdu+offset));
offset += elmLen;
break;
case MODE_OF_THE_FIRST_CHANNEL:
pdu.PutIE(LAYER3INFO_IE_CHANNEL_MODE, sizeof(SChannelMode), (char *)(pPdu+offset));
offset += sizeof(SChannelMode);
break;
case SECONDE_CHANNEL_DESCRIPT_AFTER_TIME:
pdu.PutIE(LAYER3INFO_IE_SECOND_CHANNEL_DESCRIPT_AFTER_TIME, sizeof(SChannelDescription), (char *)pPdu);
offset += sizeof(SChannelDescription);
break;
case MODE_OF_THE_SECOND_CHANNEL:
pdu.PutIE(LAYER3INFO_IE_CHANNEL_MODE2, sizeof(SChannelMode2), (char *)(pPdu+offset));
offset += sizeof(SChannelMode2);
break;
case FREQUENCY_CHANNEL_SEQUENCE_AFTER_TIME:
memset(&frequency_channel_seq, 0, sizeof(frequency_channel_seq));
frequency_channel_seq.arfcn_lowest = msuBuf[offset++] & 0x7F;
memcpy(frequency_channel_seq.arfcn, pPdu+offset, 8);
pdu.PutIE(LAYER3INFO_IE_FREQUENCY_CHANNEL_SEQUENCE_AFTER_TIME, sizeof(SFrequencyChannelSeq), (char *)&frequency_channel_seq);
break;
case MOBILE_ALLOCATION://after time
elmLen = msuBuf[offset++];
pdu.PutIE(LAYER3INFO_IE_MOBILE_ALLOCATION, sizeof(SMobileAllocation), (char *)(pPdu+offset));
offset += elmLen;
break;
case STARTING_TIME:
pdu.PutIE(LAYER3INFO_IE_START_TIME, sizeof(SStartTime), (char *)(pPdu+offset));
offset += sizeof(SStartTime);
break;
case REAL_TIME_DIFFERENCE:
elmLen = msuBuf[offset++];
pdu.PutIE(LAYER3INFO_IE_TIME_DIFFERENCE, sizeof(STimeDifference), (char *)(pPdu+offset));
offset += sizeof(STimeDifference);
break;
case TIME_ADVANCE:
struct STimingAdvance timing;
memset(&timing, 0, sizeof(STimingAdvance));
timing.timing_advence_value = msuBuf[offset]&0x3F;
pdu.PutIE(LAYER3INFO_IE_TIMING_ADVANCE, sizeof(STimingAdvance), (char *)&timing);
offset += sizeof(STimingAdvance);
break;
case FREQUENCY_SHORT_LIST_BEFORE_TIME:
struct SFrequencyShortList frequency_short_list;
memcpy(frequency_short_list.value, &msuBuf[offset], 9);
pdu.PutIE(LAYER3INFO_IE_FREQUENCY_SHORT_LIST_BEFORE_TIME, sizeof(SFrequencyShortList), (char *)&frequency_short_list);
offset += sizeof(SFrequencyShortList);
break;
case FREQUENCY_LIST_BEFORE_TIME:
memset(&frequency_list, 0, sizeof(frequency_list));
elmLen = msuBuf[offset++];
frequency_list.list_len = elmLen;
if((frequency_list.ptr = new unsigned char [elmLen]) != NULL)
{
memcpy(frequency_list.ptr, &msuBuf[offset], elmLen);
pdu.PutIE(LAYER3INFO_IE_FREQUENCY_LIST_BEFORE_TIME, sizeof(SFrequencyList), (char *)&frequency_list);
}
offset += elmLen;
break;
case FIRST_CHANNEL_DESCRIPT_BEFORE_TIME:
pdu.PutIE(LAYER3INFO_IE_FIRST_CHANNEL_DESCRIPT_BEFORE_TIME, sizeof(SChannelDescription), (char *)(pPdu+offset));
offset += sizeof(SChannelDescription);
break;
case SECONDE_CHANNEL_DESCRIPT_BEFORE_TIME:
pdu.PutIE(LAYER3INFO_IE_SECOND_CHANNEL_DESCRIPT_BEFORE_TIME, sizeof(SChannelDescription), (char *)(pPdu+offset));
offset += sizeof(SChannelDescription);
break;
case FREQUENCY_CHANNEL_SEQUENCE_BEFORE_TIME:
memset(&frequency_channel_seq, 0, sizeof(frequency_channel_seq));
frequency_channel_seq.arfcn_lowest = msuBuf[offset++] & 0x7F;
memcpy(frequency_channel_seq.arfcn, pPdu+offset, 8);
pdu.PutIE(LAYER3INFO_IE_FREQUENCY_CHANNEL_SEQUENCE_BEFORE_TIME, sizeof(SFrequencyChannelSeq), (char *)&frequency_channel_seq);
offset += sizeof(SFrequencyChannelSeq);
break;
case MOBILE_ALLOCATION_BEFORE_TIME:
struct SMobileAllocation mobile_allocation;
memset(&mobile_allocation, 0, sizeof(mobile_allocation));
elmLen = msuBuf[offset++];
mobile_allocation.len = elmLen;
if((mobile_allocation.ptr = new unsigned char [elmLen]) != NULL)
{
memcpy(mobile_allocation.ptr, &msuBuf[offset], elmLen);
pdu.PutIE(LAYER3INFO_IE_MOBILE_ALLOCATION_BEFORE_TIME, sizeof(SMobileAllocation), (char *)&mobile_allocation);
}
offset += elmLen;
break;
//VGCS target mode Indication 没解析
default:
if(elmId & 0xf0 == SYNCHRONIZATION_INDICATION)
{
struct SSynchronizationIndication indication;
memset(&indication, 0, sizeof(SSynchronizationIndication));
indication.si = msuBuf[offset-1]&0x03;
indication.rot = msuBuf[offset-1]&0x04 >> 2;
indication.nci = msuBuf[offset-1]&0x08 >> 3;
pdu.PutIE(LAYER3INFO_IE_SYNCHRONIZATION_INDICATION, sizeof(SSynchronizationIndication), (char *)&indication);
}else if(elmId & 0xf0 == CIPHER_MODE_SETTING)
{
pdu.PutIE(LAYER3INFO_IE_CIPHER_MODE_SETTING, sizeof(SCipherModeSetting), (char *)(pPdu+offset-1));//1
}
else
{
printf("elmId error:%d\n",elmId);
}
break;
}
}
}
void layer3_ho_complete(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
unsigned char elmId = 0;
unsigned char elmLen = 0;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_ho_complete:input parameter error!");
return;
}
pdu.PutIE(LAYER3INFO_IE_RR_CAUSE, sizeof(SRrCause), (char *)pPdu);
offset += sizeof(SRrCause);
if(offset < msu_len)
{
struct SMobileTimeDifference time_difference;
//存在可选参数
elmId = msuBuf[offset++];
elmLen = msuBuf[offset++];
if(elmId == MOBILE_OBSERVED_TIME_DIFFERENCE)
{
memset(&time_difference, 0, sizeof(SMobileTimeDifference));
time_difference.mobile_time_differ_value_h = msuBuf[offset++];
time_difference.mobile_time_differ_value_cont = msuBuf[offset++];
time_difference.mobile_time_differ_value_l = msuBuf[offset]&0xF8>>3;
pdu.PutIE(LAYER3INFO_IE_TIME_DIFFERENCE, sizeof(SMobileTimeDifference), (char *)&time_difference);
}
}
}
void layer3_ho_failure(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
unsigned char *pPdu = msuBuf;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_ho_failure:input parameter error!");
return;
}
pdu.PutIE(LAYER3INFO_IE_RR_CAUSE, sizeof(SRrCause), (char *)pPdu);
}
void layer3_immediate_assignment(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
unsigned char elmId = 0;
unsigned char elmLen = 0;
struct SRequestReference request_reference;
struct STimingAdvance timing;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_immediate_assignment:input parameter error!");
return;
}
offset++; //skip page mode and spare half octet
pdu.PutIE(LAYER3INFO_IE_CHANNEL_DESCRIPTION, sizeof(SChannelDescription), (char *)pPdu);
offset += sizeof(SChannelDescription);
memset(&request_reference, 0, sizeof(SRequestReference));
request_reference.ra = msuBuf[offset++];
request_reference.t3_h = msuBuf[offset] & 0x07;
request_reference.t1 = msuBuf[offset++]&0xf8 >> 3;
request_reference.t2 = msuBuf[offset]&0x1f;
request_reference.t3_l = msuBuf[offset]&0xE0>>5;
pdu.PutIE(LAYER3IINFO_IE_REQUEST_REFERENCE, sizeof(SRequestReference), (char *)&request_reference);
offset += sizeof(SRequestReference);
memset(&timing, 0, sizeof(STimingAdvance));
timing.timing_advence_value = msuBuf[offset]&0x3F;
pdu.PutIE(LAYER3INFO_IE_TIMING_ADVANCE, sizeof(STimingAdvance), (char *)&timing);
offset += sizeof(STimingAdvance);
elmLen = msuBuf[offset++];
pdu.PutIE(LAYER3INFO_IE_MOBILE_ALLOCATION, sizeof(SMobileAllocation), (char *)(pPdu+offset));
offset += elmLen;
//存在可选参数
elmId = msuBuf[offset];
if(elmId == STARTING_TIME)
{
offset++;
pdu.PutIE(LAYER3INFO_IE_START_TIME, sizeof(SStartTime), (char *)(pPdu+offset));
offset += sizeof(SStartTime);
}
//skip IA Rest Octets
}
void layer3_immediate_assignment_extended(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
unsigned char elmId = 0;
unsigned char elmLen = 0;
struct SRequestReference request_reference;
struct STimingAdvance timing;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_immediate_assignment_extended:input parameter error!");
return;
}
offset++;//skip page mode and spare half octet
pdu.PutIE(LAYER3INFO_IE_CHANNEL_DESCRIPTION1, sizeof(SChannelDescription), (char *)(pPdu+offset));
offset += sizeof(SChannelDescription);
memset(&request_reference, 0, sizeof(SRequestReference));
request_reference.ra = msuBuf[offset++];
request_reference.t3_h = msuBuf[offset] & 0x07;
request_reference.t1 = msuBuf[offset++]&0xf8 >> 3;
request_reference.t2 = msuBuf[offset]&0x1f;
request_reference.t3_l = msuBuf[offset]&0xE0>>5;
pdu.PutIE(LAYER3IINFO_IE_REQUEST_REFERENCE1, sizeof(SRequestReference), (char *)&request_reference);
offset += sizeof(SRequestReference);
memset(&timing, 0, sizeof(STimingAdvance));
timing.timing_advence_value = msuBuf[offset]&0x3F;
pdu.PutIE(LAYER3INFO_IE_TIMING_ADVANCE1, sizeof(STimingAdvance), (char *)&timing);
offset += sizeof(STimingAdvance);
pdu.PutIE(LAYER3INFO_IE_CHANNEL_DESCRIPTION2, sizeof(SChannelDescription), (char *)(pPdu+offset));
offset += sizeof(SChannelDescription);
memset(&request_reference, 0, sizeof(SRequestReference));
request_reference.ra = msuBuf[offset++];
request_reference.t3_h = msuBuf[offset] & 0x07;
request_reference.t1 = msuBuf[offset++]&0xf8 >> 3;
request_reference.t2 = msuBuf[offset]&0x1f;
request_reference.t3_l = msuBuf[offset]&0xE0>>5;
pdu.PutIE(LAYER3IINFO_IE_REQUEST_REFERENCE2, sizeof(SRequestReference), (char *)&request_reference);
offset += sizeof(SRequestReference);
memset(&timing, 0, sizeof(STimingAdvance));
timing.timing_advence_value = msuBuf[offset]&0x3F;
pdu.PutIE(LAYER3INFO_IE_TIMING_ADVANCE2, sizeof(STimingAdvance), (char *)&timing);
offset += sizeof(STimingAdvance);
elmLen = msuBuf[offset++];
pdu.PutIE(LAYER3INFO_IE_MOBILE_ALLOCATION, sizeof(SMobileAllocation), (char *)(pPdu+offset));
offset += elmLen;
//存在可选参数
elmId = msuBuf[offset];
if(elmId == STARTING_TIME)
{
offset++;
pdu.PutIE(LAYER3INFO_IE_START_TIME, sizeof(SStartTime), (char *)(pPdu+offset));
offset += sizeof(SStartTime);
}
//skip IAX Rest Octets
}
void layer3_immediate_assignment_reject(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
struct SRequestReference request_reference;
struct SWaitIndication wait_indication;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_immediate_assignment_reject:input parameter error!");
return;
}
offset++;//skip page mode and spare half octet
memset(&request_reference, 0, sizeof(SRequestReference));
request_reference.ra = msuBuf[offset++];
request_reference.t3_h = msuBuf[offset] & 0x07;
request_reference.t1 = msuBuf[offset++]&0xf8 >> 3;
request_reference.t2 = msuBuf[offset]&0x1f;
request_reference.t3_l = msuBuf[offset]&0xE0>>5;
pdu.PutIE(LAYER3IINFO_IE_REQUEST_REFERENCE1, sizeof(SRequestReference), (char *)&request_reference);
offset += sizeof(SRequestReference);
wait_indication.t3122_timeout = msuBuf[offset];
offset += sizeof(SWaitIndication);
pdu.PutIE(LAYER3INFO_IE_WAIT_INDICATION1, sizeof(SWaitIndication), (char *)&wait_indication);
memset(&request_reference, 0, sizeof(SRequestReference));
request_reference.ra = msuBuf[offset++];
request_reference.t3_h = msuBuf[offset] & 0x07;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -