⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 layer3infodecode.cpp

📁 ABis无线接口全套资料
💻 CPP
📖 第 1 页 / 共 5 页
字号:
#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 + -