📄 layer3infodecode.cpp
字号:
#include "util.hpp"
#include "ptlbase.hpp"
#include "layer3infoPtl.hpp"
#include "abisptl.hpp"
#include "abisfmt.hpp"
#include <map>
#include <string>
#include <iostream>
using namespace std;
struct STeiCgi link_array[MAX_LINK_NUMBER][MAX_LINK_TEI];
struct SMsgCnt msg_array[8][3];
extern UINT8 BtsTrx2Cell(UINT8 pcm, UINT8 trx);
/**************************************************************************
Purpose:从Mobile Identity 中获取IMSI或者TMSI号码,gsm 0408 10.5.1
Return:返回号码个数
Author:chirs
Date: 2008-06-23
**************************************************************************/
unsigned char GetIMSITMSI(unsigned char *no, unsigned char len, unsigned char *string_buff)
{
unsigned char isOdd;
unsigned char i, j;
isOdd=(no[0]&0x08);//奇偶标志
j=0;
string_buff[j++] = (no[0]>>4) & 0x0f;//取出Identity digit 1
for(i = 1; i < len; i++)
{
string_buff[j] = no[i] & 0x0f;
j++;
string_buff[j] = (no[i]>>4) & 0x0f;
j++;
}
if(isOdd == 0)//号码的个数为偶数
{
j--;
}
return j;
}
void layer3_additional_assignment(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
//Channel Description 3 bytes
pdu.PutIE(LAYER3INFO_IE_CHANNEL_DESCRIPTION, sizeof(SChannelDescription), (char *)pPdu);
offset += sizeof(SChannelDescription);
while(offset < msu_len)
{
unsigned char elmId = msuBuf[offset++];
unsigned char elmLen = 0;
switch(elmId)
{
case MOBILE_ALLOCATION: //TLV
elmLen = msuBuf[offset++];
pdu.PutIE(LAYER3INFO_IE_MOBILE_ALLOCATION, sizeof(SMobileAllocation), (char *)(pPdu+offset));
offset += elmLen;
break;
case STARTING_TIME://TV
pdu.PutIE(LAYER3INFO_IE_START_TIME, sizeof(SStartTime), (char *)(pPdu+offset));
offset += sizeof(SStartTime);
break;
default:
printf("layer3_additional_assignment:error lemId:%d\n",elmId);
break;
}
}
}
void layer3_assignment_cmd(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
struct SFrequencyList frequency_list;
//Channel Description 3 bytes
pdu.PutIE(LAYER3INFO_IE_FIRST_CHANNEL_DESCRIPT_AFTER_TIME, sizeof(SChannelDescription), (char *)pPdu);
offset += sizeof(SChannelDescription);
//power command
pdu.PutIE(LAYER3INFO_IE_POWER_CMD, sizeof(SPowerCmd), (char *)(pPdu+offset));
offset += sizeof(SPowerCmd);
while(offset < msu_len)
{
unsigned char elmId = msuBuf[offset++];
unsigned char elmLen = 0;
switch(elmId)
{
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://gsm 0408 10.5.2.1b ,TV, 17 bytes
elmLen = 16;
pdu.PutIE(LAYER3INFO_IE_CELL_CHANNEL_DESCRIPT, sizeof(SCellChannelDescrip), (char *)(pPdu+offset));
offset += elmLen;
break;
case MODE_OF_THE_FIRST_CHANNEL://10.5.2.6
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));
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 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 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:
struct SFrequencyChannelSeq frequency_channel_seq;
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 == CIPHER_MODE_SETTING)){ // 1 byte
pdu.PutIE(LAYER3INFO_IE_CIPHER_MODE_SETTING, sizeof(SCipherModeSetting),(char *) (pPdu+offset-1));//1
}
else
{
printf("layer3_assignment_cmd:error elmId:%d\n",elmId);
}
break;
}
}
}
void layer3_assignment_complete(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
unsigned char *pPdu = msuBuf;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_assignment_complete:input parameter error!");
return;
}
//RR cause
pdu.PutIE(LAYER3INFO_IE_RR_CAUSE, sizeof(SRrCause), (char *)pPdu);
}
void layer3_assignment_failure(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
unsigned char *pPdu = msuBuf;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_assignment_complete:input parameter error!");
return;
}
//RR cause
pdu.PutIE(LAYER3INFO_IE_RR_CAUSE, sizeof(SRrCause), (char *)pPdu);
}
void layer3_channel_mode_modify(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_channel_mode_modify:input parameter error!");
return;
}
//Channel Description
pdu.PutIE(LAYER3INFO_IE_FIRST_CHANNEL_DESCRIPT_AFTER_TIME, sizeof(SChannelDescription), (char *)pPdu);
offset += sizeof(SChannelDescription);
pdu.PutIE(LAYER3INFO_IE_CHANNEL_MODE, sizeof(SChannelMode), (char *)(pPdu+offset));
offset += sizeof(SChannelMode);
//VGCS target mode Indication not parse yet
}
void layer3_channel_mode_modify_ack(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_channel_mode_modify_ack:input parameter error!");
return;
}
pdu.PutIE(LAYER3INFO_IE_CELL_CHANNEL_DESCRIPT, sizeof(SChannelDescription), (char *)pPdu);
offset += sizeof(SChannelDescription);
pdu.PutIE(LAYER3INFO_IE_CHANNEL_MODE, sizeof(SChannelMode), (char *)(pPdu+offset));
offset += sizeof(SChannelMode);
}
void layer3_channel_release(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_channel_release:input parameter error!");
return;
}
pdu.PutIE(LAYER3INFO_IE_RR_CAUSE, sizeof(SRrCause), (char *)pPdu);
offset += sizeof(SRrCause);
//skip BA Range,Group Channel Description,Group Cipher Key Number
}
void layer3_ciphering_mode_cmd(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_ciphering_mode_cmd:input parameter error!");
return;
}
//这两个IE取了1 byte,但规范上是1/2 bytes
pdu.PutIE(LAYER3INFO_IE_CIPHER_MODE_SETTING, sizeof(SCipherModeSetting), (char *)pPdu);
offset += sizeof(SCipherModeSetting);
if(offset < msu_len)
{
pdu.PutIE(LAYER3INFO_IE_CIPHER_RESPONSE, sizeof(SCipherResponse), (char *)(pPdu+offset));
offset += sizeof(SCipherResponse);
}
}
void layer3_ciphering_mode_complete(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_ciphering_mode_complete:input parameter error!");
return;
}
if(offset < msu_len)
{
//存在可选参数
unsigned char elmId = msuBuf[offset++];
unsigned char elmLen = 0;
unsigned char imsi[15];
unsigned char imsi_len = 0;
unsigned char tmsi_len = 0;
unsigned char tmsi[4];
unsigned char imei_len = 0;
unsigned char imei[4];
if(elmId == MOBILE_IDENTITY)
{
unsigned char msiInd = 0;
elmLen = msuBuf[offset++];
msiInd = msuBuf[offset];
if ((msiInd & 0x7) == 0x1) {
// [:7] IMSI
imsi_len = GetIMSITMSI(&msuBuf[offset], elmLen, imsi);
pdu.PutIE(LAYER3INFO_IE_IMSI, imsi_len, (char *)imsi);
}
else if ((msiInd & 0x7) == 0x4)
{
// [:4] TMSI
offset++;
tmsi_len = elmLen -1;
memcpy(tmsi, &msuBuf[offset], tmsi_len);
pdu.PutIE(LAYER3INFO_IE_TMSI, tmsi_len, (char *)tmsi);
}
else if((msiInd & 0x7) == 0x2)
{
//IMEI
imei_len = GetIMSITMSI(&msuBuf[offset], elmLen, imei);
pdu.PutIE(LAYER3INFO_IE_IMEI, imei_len, (char *)imei);
}
}
}
}
void layer3_classmark_change(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char elmId = 0;
unsigned char elmLen = 0;
struct SMobileStationClassmark2 station_classmark2;
if((msuBuf == NULL) || (msu_len <= 0)){
//Print("layer3_classmark_change:input parameter error!");
return;
}
//Mobile station classmark, LV
elmLen = msuBuf[offset++];
memset(&station_classmark2, 0, sizeof(station_classmark2));
station_classmark2.rf_power_capability = msuBuf[offset] & 0x07;
station_classmark2.a5_1 = msuBuf[offset] & 0x08 >> 3;
station_classmark2.es_ind = msuBuf[offset] & 0x10 >> 4;
station_classmark2.revision_level = msuBuf[offset++] & 0x60 >> 5;
station_classmark2.fc = msuBuf[offset]& 0x01;
station_classmark2.vgcs = msuBuf[offset] & 0x02 >> 1;
station_classmark2.vbs = msuBuf[offset] & 0x04 >> 2;
station_classmark2.sm_capabi = msuBuf[offset]&0x08 >> 3;
station_classmark2.ss_screen_indicator = msuBuf[offset]&0x30 >> 4;
station_classmark2.ps_capa = msuBuf[offset++]&0x40 >>6;
station_classmark2.a5_2 = msuBuf[offset] & 0x01;
station_classmark2.a5_3 = msuBuf[offset] & 0x02 >> 1;
station_classmark2.cm3 = msuBuf[offset++] & 0x80 >> 7;
pdu.PutIE(LAYER3INFO_IE_MOBILE_STATION_CLASSMARK2, sizeof(SMobileStationClassmark2), (char *)&station_classmark2);
if(offset < msu_len)
{
//存在可选参数
elmId = msuBuf[offset++];
if(elmId == ADDITIONAL_MOBILE_STATION_CLASSMARK_INFORMATION)
{
SMobileStationClassmark3 station_classmark3;
memset(&station_classmark3, 0, sizeof(SMobileStationClassmark3));
elmLen = msuBuf[offset++];
station_classmark3.a5_4 = msuBuf[offset]&0x01;
station_classmark3.a5_5 = msuBuf[offset]&0x02>>1;
station_classmark3.a5_6 = msuBuf[offset]&0x04>>2;
station_classmark3.a5_7 = msuBuf[offset]&0x08>>3;
station_classmark3.band1 = msuBuf[offset]&0x10>>4;
station_classmark3.band2 = msuBuf[offset]&0x20>>5;
station_classmark3.band3 = msuBuf[offset]&0x40>>6;
station_classmark3.e_bit = msuBuf[offset++]&0x80>>7;
station_classmark3.assco_radio_capab1 = msuBuf[offset]&0x0f;
station_classmark3.assco_radio_capab2 = msuBuf[offset]&0xf0 >> 4;
pdu.PutIE(LAYER3INFO_IE_MOBILE_STATION_CLASSMARK3, sizeof(SMobileStationClassmark3), (char *)&station_classmark3);
}
}
}
void layer3_frequency_redefinition(unsigned char *msuBuf, short msu_len, CPduBase &pdu)
{
short offset = 0;
unsigned char *pPdu = msuBuf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -