/********************************************************************
Copyright ?2007 LGC Wireless, Inc. All rights reserved
File Name: 		aifg_ie.h
Description:	Implementation of IE encode/decode functions
Version:		v9.0.0
Author:			Roy Jiang
Create Date:	2007-3-21

History:
2007-3-21		v9.0.0	Create
*********************************************************************/
#include "./include/aifg_var_ext.h"

/*
Name: 	aifg_get_iei
Purpose:Convert local IE ID to protocol IEI
Input:	aifg_msg_protocol protocol: BSSMAP or DTAP
		aifg_pre_decoded_ie *pre_decoded: pre-decoded IE structure
		aifg_ie *dst: pointer to a aifg_ie structure object in which the decoded message will be stored.
Output:	Total length of decoded IE
*/
int aifg_get_iei(int localId)
{
	switch(localId){
		case AIFG_IE_ID_BM_CIC:
			return AIFG_IEI_BM_CIC;
		break;
		case AIFG_IE_ID_BM_CHANNELTYPE:
			return AIFG_IEI_BM_CHANNELTYPE;
		break;
		case AIFG_IE_ID_BM_FORWARDIND:
			return AIFG_IEI_BM_FORWARDIND;
		break;
		case AIFG_IE_ID_BM_RESOURCEAVAIL:
			return AIFG_IEI_BM_RESOURCEAVAIL;
		break;
		case AIFG_IE_ID_BM_CAUSE:
			return AIFG_IEI_BM_CAUSE;
		break;
		case AIFG_IE_ID_BM_CELLID:
			return AIFG_IEI_BM_CELLID;
		break;
		case AIFG_IE_ID_BM_PRIORITY:
			return AIFG_IEI_BM_PRIORITY;
		break;
		case AIFG_IE_ID_BM_L3HEADERINFO:
			return AIFG_IEI_BM_L3HEADERINFO;
		break;
		case AIFG_IE_ID_BM_IMSI:
			return AIFG_IEI_BM_IMSI;
		break;
		case AIFG_IE_ID_BM_TMSI:
			return AIFG_IEI_BM_TMSI;
		break;
		case AIFG_IE_ID_BM_ENCRYPTINFO:
			return AIFG_IEI_BM_ENCRYPTINFO;
		break;
		case AIFG_IE_ID_BM_PERIODICITY:
			return AIFG_IEI_BM_PERIODICITY;
		break;
		case AIFG_IE_ID_BM_EXTRESOURCEIND:
			return AIFG_IEI_BM_EXTRESOURCEIND;
		break;
		case AIFG_IE_ID_BM_MSNUM:
			return AIFG_IEI_BM_MSNUM;
		break;
		case AIFG_IE_ID_BM_CLASSMARKINFO2:
			return AIFG_IEI_BM_CLASSMARKINFO2;
		break;
		case AIFG_IE_ID_BM_CLASSMARKINFO3:
			return AIFG_IEI_BM_CLASSMARKINFO3;
		break;
		case AIFG_IE_ID_BM_BANDUSED:
			return AIFG_IEI_BM_BANDUSED;
		break;
		case AIFG_IE_ID_BM_RRCAUSE:
			return AIFG_IEI_BM_RRCAUSE;
		break;
		case AIFG_IE_ID_BM_L3INFO:
			return AIFG_IEI_BM_L3INFO;
		break;
		case AIFG_IE_ID_BM_DLCI:
			return AIFG_IEI_BM_DLCI;
		break;
		case AIFG_IE_ID_BM_DTXFLAG:
			return AIFG_IEI_BM_DTXFLAG;
		break;
		case AIFG_IE_ID_BM_CELLIDLIST:
			return AIFG_IEI_BM_CELLIDLIST;
		break;
		case AIFG_IE_ID_BM_RESPREQ:
			return AIFG_IEI_BM_RESPREQ;
		break;
		case AIFG_IE_ID_BM_RESOURCEINDMEHTOD:
			return AIFG_IEI_BM_RESOURCEINDMEHTOD;
		break;
		case AIFG_IE_ID_BM_CLASSMARKINFO1:
			return AIFG_IEI_BM_CLASSMARKINFO1;
		break;
		case AIFG_IE_ID_BM_CICLIST:
			return AIFG_IEI_BM_CICLIST;
		break;
		case AIFG_IE_ID_BM_DIGNOSTIC:
			return AIFG_IEI_BM_DIGNOSTIC;
		break;
		case AIFG_IE_ID_BM_L3MSGCONTENT:
			return AIFG_IEI_BM_L3MSGCONTENT;
		break;
		case AIFG_IE_ID_BM_CHOSENCHANNEL:
			return AIFG_IEI_BM_CHOSENCHANNEL;
		break;
		case AIFG_IE_ID_BM_TOTALRESOURCE:
			return AIFG_IEI_BM_TOTALRESOURCE;
		break;
		case AIFG_IE_ID_BM_CIPHERRESPMODE:
			return AIFG_IEI_BM_CIPHERRESPMODE;
		break;
		case AIFG_IE_ID_BM_CHANNELNEEDED:
			return AIFG_IEI_BM_CHANNELNEEDED;
		break;
		case AIFG_IE_ID_BM_TRACETYPE:
			return AIFG_IEI_BM_TRACETYPE;
		break;
		case AIFG_IE_ID_BM_TRIGGERID:
			return AIFG_IEI_BM_TRIGGERID;
		break;
		case AIFG_IE_ID_BM_TRACEREF:
			return AIFG_IEI_BM_TRACEREF;
		break;
		case AIFG_IE_ID_BM_TRANSACTIONID:
			return AIFG_IEI_BM_TRANSACTIONID;
		break;
		case AIFG_IE_ID_BM_MOBILEID:
			return AIFG_IEI_BM_MOBILEID;
		break;
		case AIFG_IE_ID_BM_OMCID:
			return AIFG_IEI_BM_OMCID;
		break;
		case AIFG_IE_ID_BM_CHOSENENCRYPT:
			return AIFG_IEI_BM_CHOSENENCRYPT;
		break;
		case AIFG_IE_ID_BM_CIRCUITPOOL:
			return AIFG_IEI_BM_CIRCUITPOOL;
		break;
		case AIFG_IE_ID_BM_CIRCUITPOOLLIST:
			return AIFG_IEI_BM_CIRCUITPOOLLIST;
		break;
		case AIFG_IE_ID_BM_TIMEIND:
			return AIFG_IEI_BM_TIMEIND;
		break;
		case AIFG_IE_ID_BM_RESOURCESITUATION:
			return AIFG_IEI_BM_RESOURCESITUATION;
		break;
		case AIFG_IE_ID_BM_CURCHANNELTYPE1:
			return AIFG_IEI_BM_CURCHANNELTYPE1;
		break;
		case AIFG_IE_ID_BM_QUEUEIND:
			return AIFG_IEI_BM_QUEUEIND;
		break;
		case AIFG_IE_ID_BM_SPEECHVER:
			return AIFG_IEI_BM_SPEECHVER;
		break;
		case AIFG_IE_ID_BM_ASSIGNREQUIREMENT:
			return AIFG_IEI_BM_ASSIGNREQUIREMENT;
		break;
		case AIFG_IE_ID_BM_TALKERFLAG:
			return AIFG_IEI_BM_TALKERFLAG;
		break;
		case AIFG_IE_ID_BM_CONNRELREQ:
			return AIFG_IEI_BM_CONNRELREQ;
		break;
		case AIFG_IE_ID_BM_GROUPCALLREF:
			return AIFG_IEI_BM_GROUPCALLREF;
		break;
		case AIFG_IE_ID_BM_EMLPP:
			return AIFG_IEI_BM_EMLPP;
		break;
		case AIFG_IE_ID_BM_CFGEVOIND:
			return AIFG_IEI_BM_CFGEVOIND;
		break;
		case AIFG_IE_ID_BM_BSSOLDTONEW:
			return AIFG_IEI_BM_BSSOLDTONEW;
		break;
		case AIFG_IE_ID_BM_LSAID:
			return AIFG_IEI_BM_LSAID;
		break;
		case AIFG_IE_ID_BM_LSAIDLIST:
			return AIFG_IEI_BM_LSAIDLIST;
		break;
		case AIFG_IE_ID_BM_LSAINFO:
			return AIFG_IEI_BM_LSAINFO;
		break;
		case AIFG_IE_ID_BM_LOCATIONINFO:
			return AIFG_IEI_BM_LOCATIONINFO;
		break;
/////////dtap//////////
        //common
		case AIFG_IE_ID_DT_LAI:
			return AIFG_IEI_DT_LAI;
		break;
		case AIFG_IE_ID_DT_MOBILEID:
			return AIFG_IEI_DT_MOBILEID;
		break;
		case AIFG_IE_ID_DT_MSCM3:
			return AIFG_IEI_DT_MSCM3;
		break;
		case AIFG_IE_ID_DT_PRIORITYLEVEL:
			return AIFG_IEI_DT_PRIORITYLEVEL;
		break;
			
		//mm
		case AIFG_IE_ID_DT_FULL_NWNAME:
			return AIFG_IEI_DT_FULL_NWNAME;
		break;
		case AIFG_IE_ID_DT_SHORT_NWNAME:
			return AIFG_IEI_DT_SHORT_NWNAME;
		break;
		case AIFG_IE_ID_DT_FLONPROCEED:
			return AIFG_IEI_DT_FLONPROCEED;
		break;
		case AIFG_IE_ID_DT_TIMEZONE:
			return AIFG_IEI_DT_TIMEZONE;
		break;
		case AIFG_IE_ID_DT_TZTIME:
			return AIFG_IEI_DT_TZTIME;
		break;
		case AIFG_IE_ID_DT_CTS:
			return AIFG_IEI_DT_CTS;
		break;
		case AIFG_IE_ID_DT_LSAID:
			return AIFG_IEI_DT_LSAID;
		break;
		//cc
		case AIFG_IE_ID_DT_AUXSTAT:
			return AIFG_IEI_DT_AUXSTAT;
		break;
		case AIFG_IE_ID_DT_BEARERCAP:
			return AIFG_IEI_DT_BEARERCAP;
		break;
		case AIFG_IE_ID_DT_CCCAP:
			return AIFG_IEI_DT_CCCAP;
		break;
		case AIFG_IE_ID_DT_CALLEDBCD:
			return AIFG_IEI_DT_CALLEDBCD;
		break;
		case AIFG_IE_ID_DT_CALLEDSUBADDR:
			return AIFG_IEI_DT_CALLEDSUBADDR;
		break;
		case AIFG_IE_ID_DT_CALLERBCD:
			return AIFG_IEI_DT_CALLERBCD;
		break;
		case AIFG_IE_ID_DT_CALLERSUBADDR:
			return AIFG_IEI_DT_CALLERSUBADDR;
		break;
		case AIFG_IE_ID_DT_CAUSE:
			return AIFG_IEI_DT_CAUSE;
		break;
		case AIFG_IE_ID_DT_CLIRSUP:
			return AIFG_IEI_DT_CLIRSUP;
		break;
		case AIFG_IE_ID_DT_CLIRIVO:
			return AIFG_IEI_DT_CLIRIVO;
		break;
		case AIFG_IE_ID_DT_CONNNUM:
			return AIFG_IEI_DT_CONNNUM;
		break;
		case AIFG_IE_ID_DT_CONNSUBADDR:
			return AIFG_IEI_DT_CONNSUBADDR;
		break;
		case AIFG_IE_ID_DT_FACILITY:
			return AIFG_IEI_DT_FACILITY;
		break;
		case AIFG_IE_ID_DT_HIGHCOM:
			return AIFG_IEI_DT_HIGHCOM;
		break;
		case AIFG_IE_ID_DT_KEYPAD:
			return AIFG_IEI_DT_KEYPAD;
		break;
		case AIFG_IE_ID_DT_LOWCOM:
			return AIFG_IEI_DT_LOWCOM;
		break;
		case AIFG_IE_ID_DT_MOREDATA:
			return AIFG_IEI_DT_MOREDATA;
		break;
		case AIFG_IE_ID_DT_PROGIND:
			return AIFG_IEI_DT_PROGIND;
		break;
		case AIFG_IE_ID_DT_REDIRBCD:
			return AIFG_IEI_DT_REDIRBCD;
		break;
		case AIFG_IE_ID_DT_REDIRSUBADDR:
			return AIFG_IEI_DT_REDIRSUBADDR;
		break;
		case AIFG_IE_ID_DT_REPEATIND:
			return AIFG_IEI_DT_REPEATIND;
		break;
		case AIFG_IE_ID_DT_REVCALLDIR:
			return AIFG_IEI_DT_REVCALLDIR;
		break;
		case AIFG_IE_ID_DT_SIGNAL:
			return AIFG_IEI_DT_SIGNAL;
		break;
		case AIFG_IE_ID_DT_SSVER:
			return AIFG_IEI_DT_SSVER;
		break;
		case AIFG_IE_ID_DT_USERUSER:
			return AIFG_IEI_DT_USERUSER;
		break;
		case AIFG_IE_ID_DT_ALERTPATTERN://zhugq
			return AIFG_IEI_DT_ALERTPATTERN;
		break;
		case AIFG_IE_ID_DT_RP_UD:
			return AIFG_IEI_DT_RP_UD;
		break;
		case AIFG_IE_ID_DT_RP_CAUSE:
			return AIFG_IEI_DT_RP_CAUSE;
		break;
		default:
			assert(0);
			return AIFG_ERROR;
		break;
	}	
}

//Information element process functions definition------------------------------------
/*
Name: 	aifg_ie_decode
Purpose:	Information element decode function
Input:	aifg_msg_protocol protocol: BSSMAP or DTAP
		aifg_pre_decoded_ie *pre_decoded: pre-decoded IE structure
		aifg_ie *dst: pointer to a aifg_ie structure object in which the decoded message will be stored.
Output:	Total length of decoded IE
*/
int aifg_ie_decode(aifg_ie_ptr *pre_decoded, aifg_ie *dst)
{
	int i, j;
	int ie_len = 0, offset = 0;
	BYTE hi_lo_flag;
	BYTE *src;

	memset(dst, 0, sizeof(aifg_ie));

	//checking parameter
	if (pre_decoded == NULL || pre_decoded->ptr == NULL || dst == NULL){
		assert(0);
		goto ERR_PROC;
	}

	src = pre_decoded->ptr;
	hi_lo_flag = pre_decoded->hi_lo_flag;
	dst->iei = pre_decoded->iei;

	switch(dst->iei){
		/*the usage of these IEs are uncertain yet
		case AIFG_IE_ID_DT_CODESETEXT:
			//TODO
		break;
		case AIFG_IE_ID_DT_SHIFT:
			//TODO
		break;
		*/
		case AIFG_IE_ID_DT_CLIRSUP:
			//TODO
		break;
		case AIFG_IE_ID_DT_CLIRIVO:
			//TODO
		break;
		case AIFG_IE_ID_DT_FACILITY:
			dst->param.dt_facility.component_len = src[offset];
			ie_len = src[offset++]+1;

			memcpy(dst->param.dt_facility.component, src + offset, dst->param.dt_facility.component_len);
/*
			ie_len = src[offset++]+1;
			
			if(src[offset] == 0xa1)//invoke
			{	
				dst->param.dt_facility.components.invoke.tag = src[offset++];
				dst->param.dt_facility.components.invoke.len = src[offset++];
				
				//invoke_id - M
				dst->param.dt_facility.components.invoke.invoke_id.tag = src[offset++];
				assert(src[offset++] == 1);
				dst->param.dt_facility.components.invoke.invoke_id.len = 1;
				dst->param.dt_facility.components.invoke.invoke_id.id = src[offset++];
				
				if(src[offset] == 0x80)//linked_id - O
				{	
					dst->param.dt_facility.components.invoke.linked_id.flag = 1;
					dst->param.dt_facility.components.invoke.linked_id.tag = src[offset++];
					assert(src[offset++] == 1);
					dst->param.dt_facility.components.invoke.linked_id.len = 1;
					dst->param.dt_facility.components.invoke.linked_id.id = src[offset++];
					i = 3;
				}
				
				//operation code -M
				dst->param.dt_facility.components.invoke.opCode.tag = src[offset++];
				dst->param.dt_facility.components.invoke.opCode.len = src[offset++];
				memcpy(dst->param.dt_facility.components.invoke.opCode.op,&src[offset],dst->param.dt_facility.components.invoke.opCode.len);
				offset += dst->param.dt_facility.components.invoke.opCode.len;
				
				//parameters - O
				j = dst->param.dt_facility.components.invoke.len - (3+i+2+dst->param.dt_facility.components.invoke.opCode.len);
				assert(j == 1 || j == 0);	
				if(j == 1)
				{	
					dst->param.dt_facility.components.invoke.param.flag = 1;
					dst->param.dt_facility.components.invoke.param.param = src[offset++];
				}	
			}
			//retrun result
			if((offset < ie_len) && (src[offset] == 0xa2))
			{				
				dst->param.dt_facility.components.return_result.tag = src[offset++];
				dst->param.dt_facility.components.return_result.len = src[offset++];
				
				//invoke_id - M
				dst->param.dt_facility.components.return_result.invoke_id.tag = src[offset++];
				assert(src[offset++] == 1);
				dst->param.dt_facility.components.return_result.invoke_id.len = 1;
				dst->param.dt_facility.components.return_result.invoke_id.id = src[offset++];

				//sequence - O
				if(src[offset] == 0x30)
				{
					dst->param.dt_facility.components.return_result.sequence.flag = 1;
					dst->param.dt_facility.components.return_result.sequence.tag = src[offset++];
					dst->param.dt_facility.components.return_result.sequence.len = src[offset++];
				}
				
				//operation code - O
				if(src[offset] == 0x02)
				{
					dst->param.dt_facility.components.return_result.opCode.flag = 1;
					dst->param.dt_facility.components.return_result.opCode.tag = src[offset++];
					dst->param.dt_facility.components.return_result.opCode.len = src[offset++];
					memcpy(dst->param.dt_facility.components.return_result.opCode.op,&src[offset]
						,dst->param.dt_facility.components.invoke.opCode.len);
					offset += dst->param.dt_facility.components.return_result.opCode.len;
				}
				//parameters - O
				j = dst->param.dt_facility.components.return_result.len - 
					(3+2+dst->param.dt_facility.components.return_result.opCode.len);
				if(1 == dst->param.dt_facility.components.return_result.sequence.flag)
				{
					dst->param.dt_facility.components.return_result.param.flag = 1;
					memcpy(&dst->param.dt_facility.components.return_result.param.param,&src[offset],
							dst->param.dt_facility.components.return_result.sequence.len);
					offset += dst->param.dt_facility.components.return_result.sequence.len;
				}
				else if(j == 1)
				{	
					dst->param.dt_facility.components.return_result.param.flag = 1;
					dst->param.dt_facility.components.return_result.param.param[0] = src[offset++];
				}	
			}
			//return error
			if((offset < ie_len) && (src[offset] == 0xa3))
			{
				dst->param.dt_facility.components.return_error.tag = src[offset++];
				dst->param.dt_facility.components.return_error.len = src[offset++];
				
				//invoke_id - M
				dst->param.dt_facility.components.return_error.invoke_id.tag = src[offset++];
				assert(src[offset++] == 1);
				dst->param.dt_facility.components.return_error.invoke_id.len = 1;
				dst->param.dt_facility.components.return_error.invoke_id.id = src[offset++];
				
				//error code -M
				dst->param.dt_facility.components.return_error.error.tag = src[offset++];
				dst->param.dt_facility.components.return_error.error.len = src[offset++];
				memcpy(dst->param.dt_facility.components.return_error.error.er,&src[offset],dst->param.dt_facility.components.return_error.error.len);
				offset += dst->param.dt_facility.components.return_error.error.len;
				
				//parameters - O
				j = dst->param.dt_facility.components.return_error.len - (3+2+dst->param.dt_facility.components.return_error.error.len);
				assert(j == 1 || j == 0);	
				if(j == 1)
				{
					dst->param.dt_facility.components.return_error.param.flag = 1;
					dst->param.dt_facility.components.return_error.param.param = src[offset++];
				}
			}
			// reject
			if((offset < ie_len) && (src[offset] == 0xa4))
			{
				
				dst->param.dt_facility.components.reject.tag = src[offset++];
				dst->param.dt_facility.components.reject.len = src[offset++];
				
				//invoke_id - M
				dst->param.dt_facility.components.reject.invoke_id.tag = src[offset++];
				assert(src[offset++] == 1);
				dst->param.dt_facility.components.reject.invoke_id.len = 1;
				dst->param.dt_facility.components.reject.invoke_id.id = src[offset++];
				
				//problem code -M
				dst->param.dt_facility.components.reject.problem.tag = src[offset++];
				dst->param.dt_facility.components.reject.problem.len = src[offset++];
				memcpy(dst->param.dt_facility.components.reject.problem.pro,&src[offset],dst->param.dt_facility.components.reject.problem.len);
				offset += dst->param.dt_facility.components.reject.problem.len;	
			}			
*/
		break;
		case AIFG_IE_ID_DT_BEARERCAP:
			ie_len = src[offset++] + 1;
			//octet 3						
			dst->param.dt_bc.channel_require = (src[offset] & 0x60) >> 5;
			dst->param.dt_bc.coding_std = (src[offset] & 0x10) >> 4;
			dst->param.dt_bc.trans_mode = (src[offset] & 0x08) >> 3;
			dst->param.dt_bc.info_trans_cap= src[offset] & 0x07;
			if((0 == dst->param.dt_bc.info_trans_cap)){
				if(0 == (src[offset++] & 0x80)){
					//extended - octet 3a optional
					aifg_set_field(dst->param.dt_bc.coding, (src[offset] & 0x40) >> 6);
					aifg_set_field(dst->param.dt_bc.speech_ver, src[offset] & 0x0F);
				}
			}
			else{
				if((offset < ie_len) && (0 != dst->param.dt_bc.info_trans_cap)){
					//not speech
					//octet 4
					offset++;
					aifg_set_field(dst->param.dt_bc.compress, (src[offset] & 0x40) >> 6);
					aifg_set_field(dst->param.dt_bc.structure, (src[offset] & 0x30) >> 4);
					aifg_set_field(dst->param.dt_bc.dupl_mode, (src[offset] & 0x08) >> 3);
					aifg_set_field(dst->param.dt_bc.confiure, (src[offset] & 0x04) >> 2);
					aifg_set_field(dst->param.dt_bc.nirr, (src[offset] & 0x02) >> 1);
					aifg_set_field(dst->param.dt_bc.establishment, src[offset++]&0x01);

					//octet 5
					aifg_set_field(dst->param.dt_bc.rate_adaption, (src[offset] & 0x18) >> 3);
					aifg_set_field(dst->param.dt_bc.signal_protocol, src[offset] & 0x07);
					if(0 == (src[offset++] & 0x80)){
						//extended - octet 5a optional
						aifg_set_field(dst->param.dt_bc.o_itc, (src[offset] & 0x60) >> 5);
						aifg_set_field(dst->param.dt_bc.o_rate_adaption, (src[offset] & 0x18) >> 3);

						if(0 == (src[offset++] & 0x80)){
							//extended - octet 5b optional
							aifg_set_field(dst->param.dt_bc.hdr_nohdr, (src[offset] & 0x40) >> 6);
							aifg_set_field(dst->param.dt_bc.multi_frame, (src[offset] & 0x20) >> 5);
							aifg_set_field(dst->param.dt_bc.mode, (src[offset] & 0x10) >> 4);
							aifg_set_field(dst->param.dt_bc.lli, (src[offset] & 0x08) >> 3);
							aifg_set_field(dst->param.dt_bc.assign_or_e, (src[offset] & 0x04) >> 2);
							aifg_set_field(dst->param.dt_bc.inb_neg, (src[offset++] & 0x02) >> 1);
						}
					}

					//octet 6
					aifg_set_field(dst->param.dt_bc.layer1_id, 1);
					aifg_set_field(dst->param.dt_bc.user_info1_protocol, (src[offset] & 0x1E) >> 1);
					aifg_set_field(dst->param.dt_bc.sync_async, src[offset++] & 0x01);

					//extended - octet 6a mandatory
					aifg_set_field(dst->param.dt_bc.num_stop_bits, (src[offset] & 0x40) >> 6);
					aifg_set_field(dst->param.dt_bc.negotiation, (src[offset] & 0x20) >> 5);
					aifg_set_field(dst->param.dt_bc.num_data_bits, (src[offset] & 0x10) >> 4);
					aifg_set_field(dst->param.dt_bc.user_rate, src[offset++] & 0x0F);

					//extended - octet 6b mandatory
					aifg_set_field(dst->param.dt_bc.intermed_rate, (src[offset] & 0x60) >> 5);
					aifg_set_field(dst->param.dt_bc.nic_on_tx, (src[offset] & 0x10) >> 4);
					aifg_set_field(dst->param.dt_bc.nic_on_rx, (src[offset] & 0x08) >> 3);
					aifg_set_field(dst->param.dt_bc.parity, src[offset++] & 0x07);

					//extended - octet 6c mandatory
					aifg_set_field(dst->param.dt_bc.connection_element, (src[offset] & 0x60) >> 5);
					aifg_set_field(dst->param.dt_bc.modem_type, src[offset] & 0x1F);

					if(0 == (src[offset++] & 0x80)){
						//extended - octet 6d optional
						aifg_set_field(dst->param.dt_bc.o_modem_type, (src[offset] & 0x60) >> 5);
						aifg_set_field(dst->param.dt_bc.fixed_nw_user_rate, src[offset] & 0x1F);

						if(0 == (src[offset++] & 0x80)){
							//extended - octet 6e optional
							aifg_set_field(dst->param.dt_bc.acceptable_chennel_code, (src[offset] & 0xF8) >> 3);
							aifg_set_field(dst->param.dt_bc.max_traffic_channel, src[offset] & 0x07);

							if(0 == (src[offset++] & 0x80)){
								//extended - octet 6f optional
								aifg_set_field(dst->param.dt_bc.uimi, (src[offset] & 0x70) >> 4);
								aifg_set_field(dst->param.dt_bc.wanted_air_if_user_rate, src[offset] & 0x0F);
							}
						}
					}

					if(++offset < ie_len){
						//extended - octet 7 optional
						aifg_set_field(dst->param.dt_bc.layer2_id, 2);
						aifg_set_field(dst->param.dt_bc.user_info2_protocol, src[offset] & 0x1F);
					}
				}
			}	
		break;
		case AIFG_IE_ID_DT_CIPHERKEY:
			if(hi_lo_flag == AIFG_LOW_BITS)	//At low 4 bits
				dst->param.dt_cipherKey.value = src[offset] & 0x0F;
			else	//At high 4 bits
				dst->param.dt_cipherKey.value = (src[offset] & 0xF0) >> 4;
		break;
		case AIFG_IE_ID_DT_LAI:
			dst->param.dt_lai.mcc[0] = src[offset] & 0x0F;
			dst->param.dt_lai.mcc[1] = (src[offset++] & 0xF0) >> 4;
			dst->param.dt_lai.mcc[2] = src[offset] & 0x0F;
			dst->param.dt_lai.mnc[2] = (src[offset++] & 0xF0) >> 4;
			dst->param.dt_lai.mnc[1] = (src[offset] & 0xF0) >> 4;
			dst->param.dt_lai.mnc[0] = src[offset++] & 0x0F;
			dst->param.dt_lai.LAC = (src[offset] << 8) | src[offset+1];
		break;
		case AIFG_IE_ID_DT_MOBILEID:
			MOBILE_ID:
			ie_len = src[offset++] + 1;
			dst->param.mobileId.type = src[offset] & 0x07;
			dst->param.mobileId.odd_even_flag = (src[offset] & 0x08) >> 3;
			i = 0;
			if(dst->param.mobileId.type == 4)//TMSI
				offset++;
			else
				dst->param.mobileId.id[i++] = (src[offset++] & 0xf0)>>4;

			while(offset < ie_len){
				dst->param.mobileId.id[i++] = src[offset] & 0x0F;
				dst->param.mobileId.id[i++] = (src[offset] & 0xF0) >> 4;		
				offset++;
			}
			if(0 == dst->param.mobileId.odd_even_flag)
				dst->param.mobileId.id_len = i-1;
			else
				dst->param.mobileId.id_len = i;
		break;
		case AIFG_IE_ID_DT_MSCM1:
			CLASSMARK_TYPE_1:
			dst->param.dt_cmInfo2.rev_level = (src[offset] & 0x60) >> 5;
			dst->param.dt_cmInfo2.es_ind = (src[offset] & 0x10) >> 4;
			dst->param.dt_cmInfo2.a5_1 = (src[offset] & 0x08) >> 3;
			dst->param.dt_cmInfo2.rf_power_cap = src[offset] & 0x07;
		break;
		case AIFG_IE_ID_DT_MSCM2:
			CLASSMARK_TYPE_2:
				offset++;
			dst->param.dt_cmInfo2.rev_level = (src[offset] & 0x60) >> 5;
			dst->param.dt_cmInfo2.es_ind = (src[offset] & 0x10) >> 4;
			dst->param.dt_cmInfo2.a5_1 = (src[offset] & 0x08) >> 3;
			dst->param.dt_cmInfo2.rf_power_cap = src[offset++] & 0x07;
			dst->param.dt_cmInfo2.ps_cap = (src[offset] & 0x40) >> 6;
			dst->param.dt_cmInfo2.ss_screen_ind = (src[offset] & 0x30) >> 4;
			dst->param.dt_cmInfo2.sm_cap = (src[offset] & 0x08) >> 3;
			dst->param.dt_cmInfo2.vbs = (src[offset] & 0x04) >> 2;
			dst->param.dt_cmInfo2.vgcs = (src[offset] & 0x02) >> 1;
			dst->param.dt_cmInfo2.fc = src[offset++] & 0x01;
			dst->param.dt_cmInfo2.cm3 = (src[offset] & 0x80) >> 7;
			dst->param.dt_cmInfo2.lcsva_cap = (src[offset] & 0x20) >> 5;
			dst->param.dt_cmInfo2.so_lsa = (src[offset] & 0x08) >> 3;
			dst->param.dt_cmInfo2.cmsp = (src[offset] & 0x04) >> 2;
			dst->param.dt_cmInfo2.a5_3= (src[offset] & 0x02) >> 1;
			dst->param.dt_cmInfo2.a5_2= src[offset++] & 0x01;
		break;
		case AIFG_IE_ID_DT_MSCM3:
			//Not implemented yet
			CLASSMARK_TYPE_3:
		break;
		case AIFG_IE_ID_DT_GROUPREF:
			GROUP_CALL_REF:
				
			i = src[offset++];
			i = (i << 8) | src[offset++];
			i = (i << 8) | src[offset++];
			i = (i << 3) | ((src[offset] & 0xE0) >> 5);
			dst->param.dt_broadcastRef.binary_code = i;
			dst->param.dt_broadcastRef.sf = (src[offset] & 0x10) >> 4;
			dst->param.dt_broadcastRef.af = (src[offset] & 0x08) >> 3;
			dst->param.dt_broadcastRef.call_priority = src[offset++] & 0x07;
			dst->param.dt_broadcastRef.cipher_info = (src[offset] & 0xF0) >> 4;
		break;
		case AIFG_IE_ID_DT_PRIORITYLEVEL:
			if(hi_lo_flag == AIFG_LOW_BITS)	//At low 4 bits
				dst->param.dt_priority.value = src[offset] & 0x07;
			else	//At high 4 bits
				dst->param.dt_priority.value = (src[offset] & 0x70) >> 4;
		break;
		case AIFG_IE_ID_DT_AUTHRAND:
			memcpy(dst->param.dt_authRAND.value, &(src[offset]), 16);
		break;
		case AIFG_IE_ID_DT_AUTHSRES:
			memcpy(dst->param.dt_authSRES.value, &(src[offset]), 4);
		break;
		case AIFG_IE_ID_DT_CMTYPE:
			if(hi_lo_flag == AIFG_LOW_BITS)	//At low 4 bits
				dst->param.dt_cmType.value = src[offset] & 0x0F;
			else	//At high 4 bits
				dst->param.dt_cmType.value = (src[offset] & 0xF0) >> 4;
		break;
		case AIFG_IE_ID_DT_IDTYPE:
			if(hi_lo_flag == AIFG_LOW_BITS)	//At low 4 bits
				dst->param.dt_idType.value = src[offset] & 0x07;
			else	//At high 4 bits
				dst->param.dt_idType.value = (src[offset] & 0x70) >> 4;
		break;
		case AIFG_IE_ID_DT_LUTYPE:
			if(hi_lo_flag == AIFG_LOW_BITS){
				//at low 4 bits
				dst->param.dt_luType.fo_req = (src[offset] & 0x08) >> 3;
				dst->param.dt_luType.lut = src[offset] & 0x03;
			}
			else{
				//at high 4 bits
				dst->param.dt_luType.fo_req = (src[offset] & 0x80) >> 7;
				dst->param.dt_luType.lut = (src[offset] & 0x30) >> 4;
			}
		break;
		case AIFG_IE_ID_DT_FULL_NWNAME:
		case AIFG_IE_ID_DT_SHORT_NWNAME:
			ie_len = src[offset++] + 1;
			dst->param.dt_nwName.code_scheme = (src[offset] & 0x70) >> 4;
			dst->param.dt_nwName.add_ci = (src[offset] & 0x08) >> 4;
			dst->param.dt_nwName.spare_num = src[offset++] & 0x07;
			dst->param.dt_nwName.text_len = ie_len - offset;
			memcpy(dst->param.dt_nwName.text, &(src[offset]), dst->param.dt_nwName.text_len);
		break;
		case AIFG_IE_ID_DT_REJCAUSE:
			dst->param.dt_rejectCause.value = src[offset];
		break;
		case AIFG_IE_ID_DT_FLONPROCEED:
//					dst->param.dt_followOnProceed.value = 1;
		break;
		case AIFG_IE_ID_DT_TIMEZONE:
			dst->param.dt_timeZone.value = src[offset];
		break;
		case AIFG_IE_ID_DT_TZTIME:
			dst->param.dt_tzTime.year = src[offset++];
			dst->param.dt_tzTime.month = src[offset++];
			dst->param.dt_tzTime.day = src[offset++];
			dst->param.dt_tzTime.hour = src[offset++];
			dst->param.dt_tzTime.minute = src[offset++];
			dst->param.dt_tzTime.second= src[offset++];
			dst->param.dt_tzTime.time_zone = src[offset++];
		break;
		case AIFG_IE_ID_DT_CTS:
//					dst->param.dt_CTSPermission.value = 1;
		break;
		case AIFG_IE_ID_DT_LSAID:
			LSAID:
				offset++;
			dst->param.dt_lsaId.value[0] = src[offset++];
			dst->param.dt_lsaId.value[1] = src[offset++];
			dst->param.dt_lsaId.value[2] = src[offset++];					
		break;
		case AIFG_IE_ID_DT_AUXSTAT:
			offset++;
			dst->param.dt_auxStat.hold_stat = (src[offset] & 0x0C) >> 2;
			dst->param.dt_auxStat.mpty_stat = src[offset] & 0x03;
		break;
		case AIFG_IE_ID_DT_CCCAP:
			offset++;
			dst->param.dt_ccCap.pcp = (src[offset] & 0x02) >> 1;
			dst->param.dt_ccCap.dtmf = src[offset] & 0x01;					
		break;
		case AIFG_IE_ID_DT_CALLSTAT:
			dst->param.dt_callStat.coding_std = (src[offset] & 0xC0) >> 6;
			dst->param.dt_callStat.value = src[offset] & 0x3F;
		break;
		case AIFG_IE_ID_DT_CALLEDBCD:
		case AIFG_IE_ID_DT_CALLERBCD:
		case AIFG_IE_ID_DT_CONNNUM:
		case AIFG_IE_ID_DT_REDIRBCD:
			ie_len = src[offset++] + 1;
			dst->param.dt_callingNum.type = (src[offset] & 0x70) >> 4;
			dst->param.dt_callingNum.num_plan= src[offset] & 0x0F;
			if(0x00 == (src[offset++] & 0x80)){
				//ext == 0
				dst->param.dt_callingNum.presentation_ind.flag = 1;
				dst->param.dt_callingNum.presentation_ind.value = (src[offset] & 0x60) >> 5;
				dst->param.dt_callingNum.screen_ind.flag = 1;
				dst->param.dt_callingNum.screen_ind.value = src[offset++] & 0x03;
			}
			i = 0;
			while(offset < ie_len){
				int j;
				assert(offset < 43);	//43 is the max length
				dst->param.dt_callingNum.number[i] = src[offset] & 0x0F;
				if (dst->param.dt_callingNum.number[i] == 10 || dst->param.dt_callingNum.number[i] == 11){
					//convert '*' & '#' to the ISUP code standard
					dst->param.dt_callingNum.number[i]++;
				}
				i++;
				
				j = (src[offset++] & 0xF0) >> 4;
				if(j != 0x0F){
					dst->param.dt_callingNum.number[i] = j;
					if (dst->param.dt_callingNum.number[i] == 10 || dst->param.dt_callingNum.number[i] == 11){
						//convert '*' & '#' to the ISUP code standard
						dst->param.dt_callingNum.number[i]++;
					}
					i++;
				}				
			}
			dst->param.dt_callingNum.num_len = i;
		break;
		case AIFG_IE_ID_DT_CALLEDSUBADDR:
		case AIFG_IE_ID_DT_CALLERSUBADDR:
		case AIFG_IE_ID_DT_CONNSUBADDR:
		case AIFG_IE_ID_DT_REDIRSUBADDR:
			ie_len = src[offset++] + 1;
			dst->param.dt_callingSubAddr.type = (src[offset] & 0x70) >> 4;
			dst->param.dt_callingSubAddr.odd_even_ind = (src[offset++] & 0x08) >> 3;
			dst->param.dt_callingSubAddr.info_len = ie_len - offset;
			memcpy(dst->param.dt_callingSubAddr.info, &(src[offset]), dst->param.dt_callingSubAddr.info_len);
		break;
		case AIFG_IE_ID_DT_CAUSE:
			ie_len = src[offset++] + 1;
			dst->param.dt_cause.coding_std = (src[offset] & 0x60) >> 5;
			dst->param.dt_cause.location = src[offset] & 0x0F;
			if(0x00 == (src[offset++] & 0x80)){
				//ext == 0
				dst->param.dt_cause.recommendation.flag = 1;
				dst->param.dt_cause.recommendation.value = src[offset++];
			}
			dst->param.dt_cause.cause_value = src[offset++] & 0x7F;
			dst->param.dt_cause.diag_len = ie_len - offset;
			memcpy(dst->param.dt_cause.diagnostic, &(src[offset]), dst->param.dt_cause.diag_len);
		break;
		case AIFG_IE_ID_DT_CONGESTLEVEL:
			if(hi_lo_flag == AIFG_LOW_BITS)	//At low 4 bits
				dst->param.dt_congestLevel.value = src[offset] & 0x0F;
			else	//At high 4 bits
				dst->param.dt_congestLevel.value = (src[offset] & 0xF0) >> 4;
		break;
		case AIFG_IE_ID_DT_HIGHCOM:
			ie_len = src[offset++] + 1;
			if(offset < ie_len){						
				aifg_set_field(dst->param.dt_hiComp.coding_std, (src[offset] & 0x60) >> 5);
				aifg_set_field(dst->param.dt_hiComp.interpret, (src[offset] & 0x1C) >> 2);
				aifg_set_field(dst->param.dt_hiComp.presentat_method, src[offset++] & 0x03);
				aifg_set_field(dst->param.dt_hiComp.high_layer_id, src[offset]&0x7f);
				if(0x00 == (src[offset++] & 0x80)){
					//ext == 0							
					aifg_set_field(dst->param.dt_hiComp.ext_high_layer_id, src[offset]&0x7f);
				}
			}
		break;
		case AIFG_IE_ID_DT_KEYPAD:
			dst->param.dt_keypad.value = src[offset] & 0x7F;
		break;
		case AIFG_IE_ID_DT_LOWCOM:
			ie_len = src[offset++] + 1;
			dst->param.dt_loComp.data_len = ie_len - offset;
			memcpy(dst->param.dt_loComp.data, &(src[offset]), dst->param.dt_loComp.data_len);
		break;
		case AIFG_IE_ID_DT_MOREDATA:
//					dst->param.dt_moreData.value = 1;
		break;
		case AIFG_IE_ID_DT_NOTIIND:
			dst->param.dt_notificationInd.value = src[offset] & 0x7F;
		break;
		case AIFG_IE_ID_DT_PROGIND:
			offset++;		//skip length
			dst->param.dt_progInd.coding_standard = (src[offset] & 0x60) >> 5;
			dst->param.dt_progInd.location = src[offset++] & 0x0F;
			dst->param.dt_progInd.desc = src[offset] & 0x7F;
		break;
		case AIFG_IE_ID_DT_REPEATIND:
			if(hi_lo_flag == AIFG_LOW_BITS)
				//low 4 bits
				dst->param.dt_rpInd.value = src[offset] & 0x0F;
			else
				//high 4 bits
				dst->param.dt_rpInd.value = (src[offset] & 0xF0) >> 4;
		break;
		case AIFG_IE_ID_DT_REVCALLDIR:
//					dst->param.dt_revCallDir.value = 1;
		break;
		case AIFG_IE_ID_DT_SIGNAL:
			dst->param.dt_signal.value = src[offset];
		break;
		case AIFG_IE_ID_DT_SSVER:
			ie_len = src[offset++] + 1;
			dst->param.dt_ssVer.info_len = ie_len - offset;
			memcpy(dst->param.dt_ssVer.info, &(src[offset]), dst->param.dt_ssVer.info_len);
		break;
		case AIFG_IE_ID_DT_USERUSER:
			ie_len = src[offset++] + 1;
			dst->param.dt_uu.pd = src[offset++];
			dst->param.dt_uu.info_len = ie_len - offset;
			memcpy(dst->param.dt_uu.info, &(src[offset]), dst->param.dt_uu.info_len);
		break;
		case AIFG_IE_ID_DT_ALERTPATTERN:
			offset++;
			dst->param.dt_alertPattern.value = src[offset] & 0x0F;
		break;
		case AIFG_IE_ID_DT_RP_MO_ADDR:
		case AIFG_IE_ID_DT_RP_MT_ADDR:
			ie_len = src[offset++] + 1;
			if (0 != ie_len){
				dst->param.dt_rpAddr.flag = 1;
				dst->param.dt_rpAddr.number_type = (src[offset] & 0x70) >> 4;
				dst->param.dt_rpAddr.number_plan = src[offset++] & 0x0F;
				dst->param.dt_rpAddr.number_len = ie_len - offset;
				memcpy(dst->param.dt_rpAddr.number, src+offset, dst->param.dt_rpAddr.number_len);
			}
		break;
		case AIFG_IE_ID_DT_RP_UD:
			dst->param.dt_rpUD.len = src[offset];
			ie_len = src[offset++] + 1 ;
			memcpy(dst->param.dt_rpUD.content, src+offset, dst->param.dt_rpUD.len);
		break;
		case AIFG_IE_ID_DT_RP_CAUSE:
			ie_len = src[offset++] + 1;
			dst->param.dt_rpCause.cause = src[offset++] & 0x7F;
			if(ie_len - offset > 0){
				dst->param.dt_rpCause.diag_len = ie_len - offset;
				memcpy(dst->param.dt_rpCause.diagnostic, src+offset, dst->param.dt_rpCause.diag_len);
			}
		break ;

		//BSSMAP
		case AIFG_IE_ID_BM_BSSOLDTONEW:
			ie_len = src[offset++] + 1;
			dst->param.bm_bssOldtoNew.len = ie_len - offset;
			memcpy(dst->param.bm_bssOldtoNew.content, &(src[offset]), dst->param.bm_bssOldtoNew.len);
		break;
		case AIFG_IE_ID_BM_OMCID:
			ie_len = src[offset++] + 1;
			dst->param.bm_omcId.len = ie_len - offset;
			memcpy(dst->param.bm_omcId.id, &(src[offset]), dst->param.bm_omcId.len);
		break;
		case AIFG_IE_ID_BM_CIC:
			dst->param.bm_cic.pcm = (src[offset] << 3) | ((src[offset+1] & 0xE0) >> 5);
			dst->param.bm_cic.timeslot = src[++offset] & 0x1F;
		break;
		case AIFG_IE_ID_BM_RESOURCEAVAIL:
			i = 0;
			while(i < 5){
				dst->param.bm_resrcAvail.full_rate_channel[i] = (src[offset] << 8) | src[offset+1];
				offset += 2;
				dst->param.bm_resrcAvail.half_rate_channel[i] = (src[offset] << 8) | src[offset+1];
				offset += 2;
				i++;
			}
		break;
		case AIFG_IE_ID_BM_CAUSE:
			offset++;		//skip length
			dst->param.bm_cause.value = src[offset] & 0x7F;
			if(0x80 == (src[offset] & 0x80)){
				//has ext value
				aifg_set_field(dst->param.bm_cause.ext_value, src[++offset]);
			}
		break;
		case AIFG_IE_ID_BM_CELLID:
			offset++;		//skip length
			dst->param.bm_cellId.discriminator = src[offset++] & 0x0F;
			switch(dst->param.bm_cellId.discriminator){
				case 0x00:	//The whole Cell Global Identification, CGI, is used to identify the cell
					dst->param.bm_cellId.mcc[0] = src[offset] & 0x0F;
					dst->param.bm_cellId.mcc[1] = (src[offset++] & 0xF0) >> 4;
					dst->param.bm_cellId.mcc[2] = src[offset] & 0x0F;
					dst->param.bm_cellId.mnc[2] = (src[offset++] & 0xF0) >> 4;
					dst->param.bm_cellId.mnc[1] = (src[offset] & 0xF0) >> 4;
					dst->param.bm_cellId.mnc[0] = src[offset++]& 0x0F;
					dst->param.bm_cellId.LAC = (src[offset] << 8) | src[offset+1];
					offset += 2;
					dst->param.bm_cellId.CI =  (src[offset] << 8) | src[offset+1];
					offset += 2;
				break;
				case 0x01:	//Location Area Code, LAC, and Cell Identity, CI, is used to identify the cell
					dst->param.bm_cellId.LAC = (src[offset] << 8) | src[offset+1];
					offset += 2;
					dst->param.bm_cellId.CI = (src[offset] << 8) | src[offset+1];
					offset += 2;
				break;
				case 0x02:	//Cell Identity, CI, is used to identify the cell
					dst->param.bm_cellId.CI = (src[offset] << 8) | src[offset+1];
					offset += 2;
				break;
				case 0x03:	//No cell is associated with the transaction
				break;
				default:	//Error IE
					aifg_event = AIFG_ERR_ERROR_IE;
					goto ERR_PROC;
				break;
			}
		break;
		case AIFG_IE_ID_BM_PRIORITY:
			offset++;
			dst->param.bm_priority.pci = (src[offset] & 0x40) >> 6;
			dst->param.bm_priority.level = (src[offset] & 0x3C) >> 2;
			dst->param.bm_priority.qa = (src[offset] & 0x02) >> 1; 
			dst->param.bm_priority.pvi = src[offset] & 0x01; 
		break;
		case AIFG_IE_ID_BM_L3HEADERINFO:
			offset++;
			dst->param.bm_L3HeaderInfo.pd = src[offset++];
			dst->param.bm_L3HeaderInfo.ti = src[offset];
		break;
		case AIFG_IE_ID_BM_IMSI:				
		case AIFG_IE_ID_BM_MOBILEID:
			goto MOBILE_ID; //The same as Mobile ID of DTAP
		break;
		case AIFG_IE_ID_BM_TMSI:
			offset++;		//skip length
			memcpy(dst->param.bm_tmsi.value, &(src[offset]), 4);
		break;
		case AIFG_IE_ID_BM_ENCRYPTINFO:
			offset++;		//skip length
			dst->param.bm_encryptInfo.algorithm = src[offset++];
			if(dst->param.bm_encryptInfo.algorithm > 1){
				//at least one of the A5 encryption algorithms is permitted
				memcpy(dst->param.bm_encryptInfo.key, &(src[offset]), 8);
			}
		break;
		case AIFG_IE_ID_BM_CHANNELTYPE:
			offset++;		//skip length
			dst->param.bm_channelType.speech_data_ind = src[offset++] & 0x0F;
			dst->param.bm_channelType.channel_rate_type = src[offset++];
			if(0x01 == dst->param.bm_channelType.speech_data_ind){	
				//Speech
				j = 0;
				do{
					i = src[offset] & 0x80;	//ext flag
					dst->param.bm_channelType.ext.speech.ver[j++] = src[offset++] & 0x7F;
				}while(0x80 == i && j < 6);
				dst->param.bm_channelType.ext.speech.len = j;
			}
			else if(0x02 == dst->param.bm_channelType.speech_data_ind){
				//data
				dst->param.bm_channelType.ext.data_cfg.t_nt = src[offset] & 0x40 >> 6;
				dst->param.bm_channelType.ext.data_cfg.rate = src[offset] & 0x3F;
				if(0x80==(src[offset++]&0x80))
					aifg_set_field(dst->param.bm_channelType.ext.data_cfg.allowed_data_rate,src[offset] & 0x0F);
			}
		break;
		case AIFG_IE_ID_BM_PERIODICITY:
			dst->param.bm_periodicity.value = src[offset];
		break;
		case AIFG_IE_ID_BM_EXTRESOURCEIND:
			dst->param.bm_extResrcInd.sm = (src[offset] & 0x02) >> 1;
			dst->param.bm_extResrcInd.tarr = src[offset] & 0x01;
		break;
		case AIFG_IE_ID_BM_MSNUM:
			dst->param.bm_msNum.value = src[offset];
		break;
		case AIFG_IE_ID_BM_CLASSMARKINFO1:
			goto CLASSMARK_TYPE_1;
		break;
		case AIFG_IE_ID_BM_CLASSMARKINFO2:
			goto CLASSMARK_TYPE_2;
		break;
		case AIFG_IE_ID_BM_CLASSMARKINFO3:
			goto CLASSMARK_TYPE_3;
		break;
		case AIFG_IE_ID_BM_BANDUSED:
			dst->param.bm_bandUsed.value = src[offset];
		break;
		case AIFG_IE_ID_BM_RRCAUSE:
			dst->param.bm_rrCause.value = src[offset];
		break;
		case AIFG_IE_ID_BM_L3INFO:
		case AIFG_IE_ID_BM_L3MSGCONTENT:
			//Nothing to do
		break;
		case AIFG_IE_ID_BM_DLCI:
			dst->param.bm_dlci.value = src[offset];
		break;
		case AIFG_IE_ID_BM_DTXFLAG:
			dst->param.bm_dtx.value = src[offset];
		break;
		case AIFG_IE_ID_BM_CELLIDLIST:
			ie_len = src[offset++] + 2;	
			dst->param.bm_cellIdList.discriminator = src[offset++] & 0x0F;
			i = 0;
			while(offset < ie_len){
				switch(dst->param.bm_cellId.discriminator){
					case 0x00:	//The whole Cell Global Identification, CGI, is used to identify the cell
						dst->param.bm_cellIdList.cell_id[i].mcc[0] = src[offset] & 0x0F;
						dst->param.bm_cellIdList.cell_id[i].mcc[1] = (src[offset++] & 0xF0) >> 4;
						dst->param.bm_cellIdList.cell_id[i].mcc[2] = src[offset] & 0x0F;
						dst->param.bm_cellIdList.cell_id[i].mnc[2] = (src[offset++] & 0xF0) >> 4;
						dst->param.bm_cellIdList.cell_id[i].mnc[1] = (src[offset] & 0xF0) >> 4;
						dst->param.bm_cellIdList.cell_id[i].mnc[0] = src[offset++] & 0x0F;
						dst->param.bm_cellIdList.cell_id[i].LAC = (src[offset] << 8) | src[offset+1];
						offset += 2;
						dst->param.bm_cellIdList.cell_id[i].CI = (src[offset] << 8) | src[offset+1];
						offset += 2;
						dst->param.bm_cellIdList.cid_num=(ie_len-3)/7;
					break;
					case 0x01:	//Location Area Code, LAC, and Cell Identity, CI, is used to identify the cell
						dst->param.bm_cellIdList.cell_id[i].LAC = (src[offset] << 8) | src[offset+1];
						offset += 2;
						dst->param.bm_cellIdList.cell_id[i].CI = (src[offset] << 8) | src[offset+1];
						offset += 2;
						dst->param.bm_cellIdList.cid_num=(ie_len-3)/4;
					break;
					case 0x02:	//Cell Identity, CI, is used to identify the cell
						dst->param.bm_cellIdList.cell_id[i].CI = (src[offset] << 8) | src[offset+1];
						offset += 2;
						dst->param.bm_cellIdList.cid_num=(ie_len-3)/2;
					break;
					case 0x04:
						dst->param.bm_cellIdList.cell_id[i].mcc[0] = src[offset] & 0x0F;
						dst->param.bm_cellIdList.cell_id[i].mcc[1] = (src[offset++] & 0xF0) >> 4;
						dst->param.bm_cellIdList.cell_id[i].mcc[2] = src[offset] & 0x0F;
						dst->param.bm_cellIdList.cell_id[i].mnc[2] = (src[offset++] & 0xF0) >> 4;
						dst->param.bm_cellIdList.cell_id[i].mnc[1] = (src[offset] & 0xF0) >> 4;
						dst->param.bm_cellIdList.cell_id[i].mnc[0] = src[offset++] & 0x0F;
						dst->param.bm_cellIdList.cell_id[i].LAC = (src[offset] << 8) | src[offset+1];
						offset += 2;
						dst->param.bm_cellIdList.cid_num=(ie_len-3)/5;
					break;
					case 0x05:
						dst->param.bm_cellIdList.cell_id[i].LAC = (src[offset] << 8) | src[offset+1];
						offset += 2;
						dst->param.bm_cellIdList.cid_num=(ie_len-3)/2;
					break;
					case 0x03:	//No cell is associated with the transaction
						//Should never get into this while loop, fatal error if the program gets here
						assert(0);
					break;
					default:		//Error IE
						aifg_event = AIFG_ERR_ERROR_IE;
						goto ERR_PROC;
					break;
				}
				i++;
			}
		break;
		case AIFG_IE_ID_BM_RESPREQ:
//					dst->param.bm_respReq.value = 1;
		break;
		case AIFG_IE_ID_BM_RESOURCEINDMEHTOD:
			dst->param.bm_resrcIndMethod.value = src[offset] & 0x0F;
		break;
		case AIFG_IE_ID_BM_CICLIST:
			ie_len = src[offset++] + 1;
			dst->param.bm_cicList.range = src[offset++];
			dst->param.bm_cicList.status.len = ie_len - offset;
			memcpy(dst->param.bm_cicList.status.content, &(src[offset]), dst->param.bm_cicList.status.len);
		break;
		case AIFG_IE_ID_BM_DIGNOSTIC:
			ie_len = src[offset++] + 1;
			dst->param.bm_diagnostics.err_pointer = src[offset++];
			dst->param.bm_diagnostics.bit_pointer = src[offset++] & 0x0F;
			dst->param.bm_diagnostics.err_msg.len = ie_len - offset;
			memcpy(dst->param.bm_diagnostics.err_msg.msg, &(src[offset]), dst->param.bm_diagnostics.err_msg.len);
		break;
		case AIFG_IE_ID_BM_CHOSENCHANNEL:
			dst->param.bm_chosenChannel.mode = (src[offset] & 0xF0) >> 4;
			dst->param.bm_chosenChannel.channel = src[offset] & 0x0F;
		break;
		case AIFG_IE_ID_BM_TOTALRESOURCE:
			dst->param.bm_totalResrc.full_rate_channel = (src[0] << 8) | src[1];
			dst->param.bm_totalResrc.half_rate_channel = (src[2] << 8) | src[3];
		break;
		case AIFG_IE_ID_BM_CIPHERRESPMODE:
			dst->param.bm_cipherRespMode.value = src[offset];
		break;
		case AIFG_IE_ID_BM_CHANNELNEEDED:
			dst->param.bm_channelNeeded.value = src[offset] & 0x03;
		break;
		case AIFG_IE_ID_BM_TRACETYPE:
			dst->param.bm_traceType.value = src[offset];
		break;
		case AIFG_IE_ID_BM_TRIGGERID:
			ie_len = src[offset++] + 1;
			dst->param.bm_triggerId.len = ie_len - offset;
			memcpy(dst->param.bm_triggerId.content, &(src[offset]), dst->param.bm_triggerId.len);
		break;
		case AIFG_IE_ID_BM_TRACEREF:
			dst->param.bm_traceRef.value = (src[0] << 8) | src[1];
		break;
		case AIFG_IE_ID_BM_TRANSACTIONID:
			ie_len = src[offset++] + 1;
			dst->param.bm_transId.value = src[offset++];
			dst->param.bm_transId.value = (dst->param.bm_transId.value << 8) | src[offset];
		break;
		case AIFG_IE_ID_BM_FORWARDIND:
			dst->param.bm_fowardInd.value = src[offset] & 0x0F;
		break;
		case AIFG_IE_ID_BM_CHOSENENCRYPT:
			dst->param.bm_chosenEncrypt.value = src[offset];
		break;
		case AIFG_IE_ID_BM_CIRCUITPOOL:
			dst->param.bm_circuitPool.value = src[offset];
		break;
		case AIFG_IE_ID_BM_CIRCUITPOOLLIST:
			ie_len = src[offset++] + 1;
			dst->param.bm_circuitPoolList.num = ie_len - offset;
			memcpy(dst->param.bm_circuitPoolList.circuit, &(src[offset]), 
				dst->param.bm_circuitPoolList.num);
		break;
		case AIFG_IE_ID_BM_TIMEIND:
			dst->param.bm_timeId.value = src[offset];
		break;
		case AIFG_IE_ID_BM_RESOURCESITUATION:
			ie_len = src[offset++] + 1;
			i = 0;
			while(offset < ie_len){
				dst->param.bm_resrcSit.band[i].band_ind = (src[offset] & 0xF0) >> 4;
				dst->param.bm_resrcSit.band[i].channel_type = src[offset++] & 0x0F;
				dst->param.bm_resrcSit.band[i].channel_num = src[offset] & 0x7F;
				if(0x80 == (src[offset] & 0x80)){
					//two octets
					dst->param.bm_resrcSit.band[i].channel_num = 
						(dst->param.bm_resrcSit.band[i].channel_num << 8) | src[++offset];
				}
				i++;
				offset++;
			}
			dst->param.bm_resrcSit.band_num = i;
		break;
		case AIFG_IE_ID_BM_CURCHANNELTYPE1:
			dst->param.bm_curChannelType1.channel_mode = (src[offset] & 0xF0) >> 4;
			dst->param.bm_curChannelType1.channel = src[offset] & 0x0F;
		break;
		case AIFG_IE_ID_BM_QUEUEIND:
			dst->param.bm_queuingInd.value = (src[offset] & 0x02) >> 1;
		break;
		case AIFG_IE_ID_BM_SPEECHVER:
			dst->param.bm_speechVer.value = src[offset] & 0x7F;
		break;
		case AIFG_IE_ID_BM_ASSIGNREQUIREMENT:
			dst->param.bm_assignReq.value = src[offset];					
		break;
		case AIFG_IE_ID_BM_TALKERFLAG:
//					dst->param.bm_talkerFlag.value = 1;
		break;
		case AIFG_IE_ID_BM_CONNRELREQ:
//					dst->param.bm_connRelReq.value = 1;
		break;
		case AIFG_IE_ID_BM_GROUPCALLREF:
			offset++;
			goto GROUP_CALL_REF;	//The same as Group call refernce of DTAP
		break;
		case AIFG_IE_ID_BM_EMLPP:
			dst->param.bm_eMLPP.value = src[offset] & 0x07;
		break;
		case AIFG_IE_ID_BM_CFGEVOIND:
			dst->param.bm_cfgEvoInd.value = src[offset] & 0x0F;
		break;
		case AIFG_IE_ID_BM_LSAID:
			goto LSAID;
		break;
		case AIFG_IE_ID_BM_LSAIDLIST:
			ie_len = src[offset++] + 1;
			dst->param.bm_lsaIdList.ep = src[offset++] & 0x01;
			i = 0;
			while(offset < ie_len){
				dst->param.bm_lsaIdList.list[i].id[0] = src[offset++];
				dst->param.bm_lsaIdList.list[i].id[1] = src[offset++];
				dst->param.bm_lsaIdList.list[i++].id[2] = src[offset++];
			}
			dst->param.bm_lsaIdList.lsa_num = i;
		break;
		case AIFG_IE_ID_BM_LSAINFO:
			ie_len = src[offset++] + 1;
			dst->param.bm_lsaInfo.lsa_only= src[offset++] & 0x01;
			i = 0;
			while(offset < ie_len){
				dst->param.bm_lsaInfo.info[i].priority = src[offset++] & 0x0F;
				dst->param.bm_lsaInfo.info[i].id[0] = src[offset++];
				dst->param.bm_lsaInfo.info[i].id[1] = src[offset++];
				dst->param.bm_lsaInfo.info[i++].id[2] = src[offset++];
			}
			dst->param.bm_lsaInfo.lsa_num = i;
		break;
		case AIFG_IE_ID_BM_LOCATIONINFO:
			ie_len = src[offset++] + 1;
			dst->param.bm_locInfo.len = ie_len - offset;
			memcpy(dst->param.bm_locInfo.info, &(src[offset]), dst->param.bm_locInfo.len);
		break;
		default:	//Unknow IE
			aifg_event = AIFG_ERR_UNKNOW_IE;
			goto ERR_PROC;
		break;
	}
	
	return AIFG_SUCCEED;

ERR_PROC:
//	aifg_debug_print(aifg_event, (void*)src, NULL);
	return AIFG_ERROR;
}

/*
Name: 	aifg_ie_encode
Purpose:	Information element encode function
Input:	aifg_msg_protocol protocol: BSSMAP or DTAP
		aifg_ie *src: pointer to a aifg_ie structure object in which the decoded message will be encoded.
		BYTE *dst: pointer to the first byte of encode buffer
		int m_o_flag: flag used when encode DTAP IEs that indicates whether the ie is mandatory or optional, 
			and if mandatory, the value part presents at high 4bits or low 4bits or not care.
			0 - BSSMAP IE or Mandatory DTAP IE, low bits or whole byte
			1 - Mandatory, high bits
			2 - Optional
Output:	Total length of decoded IE
*/
int aifg_ie_encode(aifg_msg_protocol protocol, int ie_id, ie_u *src, BYTE *dst, int m_o_flag)
{
	int i, j, k, offset = 0;
	int length_position;
	//checking parameter
	if((protocol != AIFG_MSG_BSSMAP && protocol != AIFG_MSG_DTAP)
		|| src == NULL || dst == NULL)
	{
		assert(0);
		goto ERR_PROC;
	}

	switch(protocol){
		case AIFG_MSG_DTAP:
			if(m_o_flag == 2){
				//Optional ie, iei must present
				//convert program ie_id to protocol iei
				dst[offset++] = aifg_get_iei(ie_id);
			}

			switch(ie_id){
				case AIFG_IE_ID_DT_MOBILEID:
					MOBILE_ID:
						src->mobileId.odd_even_flag = src->mobileId.id_len & 0x01; //set odd/even flag
						dst[offset++]=(src->mobileId.id_len/2)+1;
						if (src->mobileId.type == 4)//TMSI
						{
							dst[offset++]= 0xf0|(src->mobileId.odd_even_flag<<3)|(src->mobileId.type);
							i=0;
						}
						else
						{
							dst[offset++]=(src->mobileId.id[0]<<4)|(src->mobileId.odd_even_flag<<3)|(src->mobileId.type);
							i=1;
						}

						if(src->mobileId.odd_even_flag==0){
							while(i<src->mobileId.id_len-1){
								dst[offset++] = (src->mobileId.id[i+1]<<4)|src->mobileId.id[i];
								i += 2;
							}
						    dst[offset++] = 0xf0|src->mobileId.id[i];
						}
						else{
							while(i<src->mobileId.id_len){
								dst[offset++] = (src->mobileId.id[i+1]<<4)|src->mobileId.id[i];
								i += 2;
							}
						}
				break;
			    case AIFG_IE_ID_DT_LAI:
					dst[offset++] = (src->dt_lai.mcc[1] << 4) | src->dt_lai.mcc[0];
					dst[offset++] = (src->dt_lai.mnc[2] << 4) | src->dt_lai.mcc[2];
					dst[offset++] = (src->dt_lai.mnc[1] << 4) | src->dt_lai.mnc[0];
					dst[offset++] = src->dt_lai.LAC >> 8;
					dst[offset++] = src->dt_lai.LAC;
				break;
				case AIFG_IE_ID_DT_CIPHERKEY:
				case AIFG_IE_ID_DT_PRIORITYLEVEL:
				case AIFG_IE_ID_DT_CMTYPE:
				case AIFG_IE_ID_DT_IDTYPE:
				case AIFG_IE_ID_DT_REPEATIND:
					if(m_o_flag == 2){
						offset--;	//the iei of this ie has only half-octet
						dst[offset] = dst[offset] | src->dt_cipherKey.value;
						offset++;
					}
					else if(m_o_flag == 0)
						dst[offset] = src->dt_cipherKey.value;
					else if(m_o_flag == 1){
						dst[offset] = (dst[offset] & 0x0F) | src->dt_cipherKey.value << 4;
						offset++;
					}
				break;
				case AIFG_IE_ID_DT_MSCM1:
					dst[offset++] = (src->dt_cmInfo1.rev_level<<5)|(src->dt_cmInfo1.es_ind<<4)|(src->dt_cmInfo1.a5_1<<3)|(src->dt_cmInfo1.rf_power_cap);	
				break;
				case AIFG_IE_ID_DT_MSCM2:
					goto classmarkinfo2;
				break;
				case AIFG_IE_ID_DT_GROUPREF:
					goto groupref;
				break;
//				case AIFG_IE_ID_DT_PRIORITYLEVEL:
//					dst[offset++]=src->dt_priority.value;//iei half octet lost
//				break;
				case AIFG_IE_ID_DT_AUTHRAND:
					memcpy(&dst[offset],src->dt_authRAND.value,16);
					offset+=16;
				break;
				case AIFG_IE_ID_DT_AUTHSRES:
					memcpy(&dst[offset],src->dt_authSRES.value,4);
					offset+=4;
				break;
//				case AIFG_IE_ID_DT_CMTYPE:
//					dst[offset++]=src->dt_cmType.value;//iei half octet lost
//				break;
//				case AIFG_IE_ID_DT_IDTYPE:
//					dst[offset++]=src->dt_idType.value;//iei half octet lost
//				break;
				case AIFG_IE_ID_DT_LUTYPE://zhugq,in case of 'O'
					if(m_o_flag == 2){
						offset--;	//the iei of this ie has only half-octet
						dst[offset] = dst[offset] | (src->dt_luType.fo_req<<3) | src->dt_luType.lut;
						offset++;
					}
					else if(m_o_flag == 0)
						dst[offset] = (src->dt_luType.fo_req<<3) | src->dt_luType.lut;
					else if(m_o_flag == 1){
						dst[offset] = (dst[offset] & 0x0F) | (src->dt_luType.fo_req<<7) | src->dt_luType.lut<<4;
						offset++;
					}
				break;
				case AIFG_IE_ID_DT_FULL_NWNAME:
				case AIFG_IE_ID_DT_SHORT_NWNAME:
					length_position = offset++;
					dst[offset++]=0x80|(src->dt_nwName.code_scheme<<4)|(src->dt_nwName.add_ci<<3)|(src->dt_nwName.spare_num);
					memcpy(&dst[offset],src->dt_nwName.text,src->dt_nwName.text_len);
					offset+=src->dt_nwName.text_len;
					if(length_position == 1)//zhugq, in case of "M"
						dst[1] = offset-2;
					else 
						dst[0] = offset-1;
				break;
				case AIFG_IE_ID_DT_REJCAUSE:
					dst[offset++]=src->dt_rejectCause.value;
				break;
				case AIFG_IE_ID_DT_FLONPROCEED://do nothing
				break;
				case AIFG_IE_ID_DT_TIMEZONE:
					dst[offset++]=src->dt_timeZone.value;
				break;
				case AIFG_IE_ID_DT_TZTIME:
					dst[offset++]=src->dt_tzTime.year;
					dst[offset++]=src->dt_tzTime.month;
					dst[offset++]=src->dt_tzTime.day;
					dst[offset++]=src->dt_tzTime.hour;
					dst[offset++]=src->dt_tzTime.minute;
					dst[offset++]=src->dt_tzTime.second;
					dst[offset++]=src->dt_tzTime.time_zone;
				break;
				case AIFG_IE_ID_DT_CTS://do nothing
				break;
				case AIFG_IE_ID_DT_LSAID:
					dst[offset++]=3;
					dst[offset++]=src->dt_lsaId.value[0];
					dst[offset++]=src->dt_lsaId.value[1];
					dst[offset++]=src->dt_lsaId.value[2];
				break;
				case AIFG_IE_ID_DT_AUXSTAT:
					dst[offset++]=1;
					dst[offset++]=0x80|(src->dt_auxStat.hold_stat<<2)|src->dt_auxStat.mpty_stat;
				break;
				case AIFG_IE_ID_DT_BEARERCAP:
					 length_position=offset++;
					if(1==src->dt_bc.coding.flag){
						//octet3 and 3a
						dst[offset++]=(src->dt_bc.channel_require<<5)
									|(src->dt_bc.coding_std<<4)
									|(src->dt_bc.trans_mode<<3)
									|src->dt_bc.info_trans_cap;
						dst[offset++]=(src->dt_bc.coding.value<<6)
									|src->dt_bc.speech_ver.value;
					}
					else{
						//octet3 without 3a
						dst[offset++]=0x80|(src->dt_bc.channel_require<<5)|(src->dt_bc.coding_std<<4)
							|(src->dt_bc.trans_mode<<3)|src->dt_bc.info_trans_cap;

						if(0!=src->dt_bc.info_trans_cap){
							///////////octet4///////
							dst[offset++]=0x80|(src->dt_bc.compress.value<<6)|(src->dt_bc.structure.value<<4)
							|(src->dt_bc.dupl_mode.value<<3)|(src->dt_bc.confiure.value<<2)
							|(src->dt_bc.nirr.value<<1)|src->dt_bc.establishment.value;

							//////octet5  and 5a,5b///////
							if(1==src->dt_bc.o_itc.flag){//octet5`s ext==0
								dst[offset++]=(src->dt_bc.access_id.value<<5)|(src->dt_bc.rate_adaption.value<<3)
									|src->dt_bc.signal_protocol.value;//octet5 with first bit "0"
								if(1==src->dt_bc.hdr_nohdr.flag){//5a and 5b
									dst[offset++]=(src->dt_bc.o_itc.value<<5)|(src->dt_bc.o_rate_adaption.value<<3);
									dst[offset++]=0x80|(src->dt_bc.hdr_nohdr.value<<6)|(src->dt_bc.multi_frame.value<<5)
										|(src->dt_bc.mode.value<<4)|(src->dt_bc.lli.value<<3)
										|(src->dt_bc.assign_or_e.value<<2)|(src->dt_bc.inb_neg.value<<1);}
									else//only 5a
										dst[offset++]=0x80|(src->dt_bc.o_itc.value<<5)|(src->dt_bc.o_rate_adaption.value<<3);
								}

							else//octet5`s ext==1
							    dst[offset++]=0x80|(src->dt_bc.access_id.value<<5)|(src->dt_bc.rate_adaption.value<<3)
									|src->dt_bc.signal_protocol.value;//octet5 with first bit "1"

							///////octet6,6a,6b,6c/////
						    dst[offset++]=(src->dt_bc.layer1_id.value<<5)|(src->dt_bc.user_info1_protocol.value<<1)
						    |src->dt_bc.sync_async.value;//octet6
						    dst[offset++]=(src->dt_bc.num_stop_bits.value<<6)|(src->dt_bc.negotiation.value<<5)
								|(src->dt_bc.num_data_bits.value<<4)|src->dt_bc.user_rate.value;//6a
							dst[offset++]=(src->dt_bc.intermed_rate.value<<5)|(src->dt_bc.nic_on_tx.value<<4)
								|(src->dt_bc.nic_on_rx.value<<3)|src->dt_bc.parity.value;//6b

							if(1==src->dt_bc.o_modem_type.flag){//6c with first bit "0"
							dst[offset++]=(src->dt_bc.connection_element.value<<5)|src->dt_bc.modem_type.value;//6c
							/////octet6d,6e,6f,7//////
							if(1==src->dt_bc.acceptable_chennel_code.flag){//6d with first bit "0"
								dst[offset++]=(src->dt_bc.o_modem_type.value<<5)|src->dt_bc.fixed_nw_user_rate.value;
								if(1==src->dt_bc.uimi.flag){//6e with first bit "0"
									dst[offset++]=(src->dt_bc.acceptable_chennel_code.value<<3)|src->dt_bc.max_traffic_channel.value;
									if(1==src->dt_bc.layer2_id.flag)//6f with first bit "0"
										dst[offset++]=(src->dt_bc.uimi.value<<4)|src->dt_bc.wanted_air_if_user_rate.value;
									else //6f with first bit "1" and 7
										dst[offset++]=0x80|(src->dt_bc.uimi.value<<4)|src->dt_bc.wanted_air_if_user_rate.value;
									dst[offset++]=0x80|(src->dt_bc.layer2_id.value<<5)|src->dt_bc.user_info2_protocol.value;//7
									}
									else //6e with first bit "1"
										dst[offset++]=0x80|(src->dt_bc.acceptable_chennel_code.value<<3)|src->dt_bc.max_traffic_channel.value;}
							else //6d with first bit "1"
								dst[offset++]=0x80|(src->dt_bc.o_modem_type.value<<5)|src->dt_bc.fixed_nw_user_rate.value;}
							else//6c with first bit "1"
							dst[offset++]=0x80|(src->dt_bc.connection_element.value<<5)|src->dt_bc.modem_type.value;//6c with first bit "1"
								
							
							}
						}
					if(length_position == 1)//zhugq,in case of "M"
						dst[1]=offset-2;
					else
						dst[0]=offset-1;
				break;
				case AIFG_IE_ID_DT_CCCAP:
					dst[offset++]=1;
					dst[offset++]=(src->dt_ccCap.pcp<<1)|src->dt_ccCap.dtmf;
				break;
				case AIFG_IE_ID_DT_CALLSTAT:
					dst[offset++]=(src->dt_callStat.coding_std<<6)|src->dt_callStat.value;
				break;
				case AIFG_IE_ID_DT_CALLEDBCD:
					dst[offset++]=(src->dt_calledNum.num_len+1)/2+1;
					dst[offset++]=0x80|(src->dt_calledNum.type<<4)|src->dt_calledNum.num_plan;
					i=0;
					while(i < src->dt_calledNum.num_len-1){
						dst[offset++]=(src->dt_calledNum.number[i+1]<<4)|src->dt_calledNum.number[i];
						i+=2;
					}
					if(1==(src->dt_calledNum.num_len%2))
					    dst[offset++]=0xf0|src->dt_calledNum.number[i];
				break;
				case AIFG_IE_ID_DT_CALLEDSUBADDR:
					connsubaddr:
					dst[offset++]=src->dt_calledSubAddr.info_len+1;
					dst[offset++]=0x80|(src->dt_calledSubAddr.type<<4)|(src->dt_calledSubAddr.odd_even_ind<<3);
					memcpy(&dst[offset],src->dt_calledSubAddr.info,src->dt_calledSubAddr.info_len);
					offset+=src->dt_calledSubAddr.info_len;
				break;
				case AIFG_IE_ID_DT_CALLERBCD:
					connnum:
					length_position = offset++;
					if(1==src->dt_callingNum.presentation_ind.flag){
						dst[offset++]=(src->dt_callingNum.type<<4)|src->dt_callingNum.num_plan;
						dst[offset++]=0x80|(src->dt_callingNum.presentation_ind.value<<5)|src->dt_callingNum.screen_ind.value;
						//dst[1]=(src->dt_callingNum.num_len+1)/2+2;
						}
					else{
						dst[offset++]=0x80|(src->dt_callingNum.type<<4)|src->dt_callingNum.num_plan;
						//dst[1]=(src->dt_callingNum.num_len+1)/2+1;
						}
					 i=0;
						while(i<src->dt_callingNum.num_len-1){
							dst[offset++]=(src->dt_callingNum.number[i+1]<<4)|src->dt_callingNum.number[i];
								i+=2;}
						if(1==src->dt_callingNum.num_len%2)
						    dst[offset++]=0xf0|src->dt_callingNum.number[i];
					if(length_position == 1)//zhugq,in case of "M"
						dst[1] = offset-2;
					else 
						dst[0] = offset-1;
				break;
				case AIFG_IE_ID_DT_CALLERSUBADDR:
					goto connsubaddr;
				break;
				case AIFG_IE_ID_DT_CONNNUM:
					goto connnum;
				break;
				case AIFG_IE_ID_DT_CONNSUBADDR:
					goto connsubaddr;
				break;
				case AIFG_IE_ID_DT_REDIRBCD:
					goto connnum;
				break;
				case AIFG_IE_ID_DT_REDIRSUBADDR:
					goto connsubaddr;
				break;
				case AIFG_IE_ID_DT_CAUSE:
					if(1==src->dt_cause.recommendation.flag){//octet3 and 3a
						dst[offset++]=src->dt_cause.diag_len+3;
						dst[offset++]=(src->dt_cause.coding_std<<5)|src->dt_cause.location;
						dst[offset++]=0x80|src->dt_cause.recommendation.value;}
					else{// octet3
						dst[offset++]=src->dt_cause.diag_len+2;
						dst[offset++]=0x80|(src->dt_cause.coding_std<<5)|src->dt_cause.location;
						}
						dst[offset++]=0x80|src->dt_cause.cause_value;
						memcpy(&dst[offset],src->dt_cause.diagnostic,src->dt_cause.diag_len);
						offset+=src->dt_cause.diag_len;	
				break;
				case AIFG_IE_ID_DT_CONGESTLEVEL:
				     dst[offset]=src->dt_congestLevel.value;
				break;
				case AIFG_IE_ID_DT_HIGHCOM:
					length_position = offset++;
					if(1==src->dt_hiComp.coding_std.flag){
						dst[offset++]=0x80|(src->dt_hiComp.coding_std.value<<5)//octet3
							|(src->dt_hiComp.interpret.value<<2)|src->dt_hiComp.presentat_method.value;
						if(1==src->dt_hiComp.high_layer_id.flag){
							if(1==src->dt_hiComp.ext_high_layer_id.flag){
								dst[offset++]=src->dt_hiComp.high_layer_id.value; // 4 with first bit "0"
								dst[offset++]=0x80|src->dt_hiComp.ext_high_layer_id.value;}// 4a
						    else
								dst[offset++]=0x80|src->dt_hiComp.high_layer_id.value;}// 4 with first bit "1"
						}
					if(length_position == 1)//zhugq,in case of "M"
						dst[1] = offset-2;
					else 
						dst[0] = offset-1;
				break;
				case AIFG_IE_ID_DT_KEYPAD:
					dst[offset++] = src->dt_keypad.value;
				break;
				case AIFG_IE_ID_DT_LOWCOM:
					dst[offset++]=src->dt_loComp.data_len;
					memcpy(&dst[offset],src->dt_loComp.data,src->dt_loComp.data_len);
					offset+=src->dt_loComp.data_len;
				break;
				case AIFG_IE_ID_DT_MOREDATA://do nothing
				break;
				case AIFG_IE_ID_DT_NOTIIND:
					dst[offset++]=0x80|src->dt_notificationInd.value;
				break;
				case AIFG_IE_ID_DT_PROGIND:
					dst[offset++]=2;
					dst[offset++]=0x80|(src->dt_progInd.coding_standard<<5)|src->dt_progInd.location;
					dst[offset++]=0x80|src->dt_progInd.desc;
				break;
//				case AIFG_IE_ID_DT_REPEATIND:
//					dst[offset++]=src->dt_rpInd.value;//iei half octet lost
//				break;
				case AIFG_IE_ID_DT_REVCALLDIR://do nothing
				break;
				case AIFG_IE_ID_DT_SIGNAL:
					dst[offset++]=src->dt_signal.value;
				break;
				case AIFG_IE_ID_DT_SSVER:
					dst[offset++]=src->dt_ssVer.info_len;
					memcpy(&dst[offset],src->dt_ssVer.info,src->dt_ssVer.info_len);
					offset+=src->dt_ssVer.info_len;
				break;
				case AIFG_IE_ID_DT_USERUSER:
					dst[offset++]=src->dt_uu.info_len+1;
				    dst[offset++]=src->dt_uu.pd;
					memcpy(&dst[offset],src->dt_uu.info,src->dt_uu.info_len);
					offset+=src->dt_uu.info_len;
				break;
				case AIFG_IE_ID_DT_ALERTPATTERN:
					dst[offset++]=1;
					dst[offset++]=src->dt_alertPattern.value;
				break;
				
				/*case AIFG_IE_ID_DT_CODESETEXT:
					//to do
				break;
				case AIFG_IE_ID_DT_SHIFT:
					//to do
				break;*/
				case AIFG_IE_ID_DT_CLIRSUP:
					//to do
				break;
				case AIFG_IE_ID_DT_CLIRIVO:
					//to do
				break;
				case AIFG_IE_ID_DT_FACILITY:
					dst[offset++] = src->dt_facility.component_len;
					memcpy(dst+offset, src->dt_facility.component, src->dt_facility.component_len);
					offset += src->dt_facility.component_len;

					/*
					length_position = offset++;
					if(src->dt_facility.components.invoke.tag == 0xa1)
					{
						dst[offset++] = src->dt_facility.components.invoke.tag;
						dst[offset++] = src->dt_facility.components.invoke.len;
						//invoke_id - M
						dst[offset++] = src->dt_facility.components.invoke.invoke_id.tag;
						dst[offset++] = src->dt_facility.components.invoke.invoke_id.len;
						dst[offset++] = src->dt_facility.components.invoke.invoke_id.id;
						//linked_id - O
						if(1 == src->dt_facility.components.invoke.linked_id.flag)
						{
							dst[offset++] = src->dt_facility.components.invoke.linked_id.tag;
							dst[offset++] = src->dt_facility.components.invoke.linked_id.len;
							dst[offset++] = src->dt_facility.components.invoke.linked_id.id;
						}
						//operatin code - M
						dst[offset++] = src->dt_facility.components.invoke.opCode.tag;
						dst[offset++] = src->dt_facility.components.invoke.opCode.len;
						memcpy(&dst[offset],src->dt_facility.components.invoke.opCode.op,src->dt_facility.components.invoke.opCode.len);
						offset += src->dt_facility.components.invoke.opCode.len;
						//parameters - O
						if(1 == src->dt_facility.components.invoke.param.flag)
							dst[offset++] = src->dt_facility.components.invoke.param.param;
					}
					if(src->dt_facility.components.return_result.tag == 0xa2)
					{
						dst[offset++] = src->dt_facility.components.return_result.tag;
						dst[offset++] = src->dt_facility.components.return_result.len;
						//invoke_id - M
						dst[offset++] = src->dt_facility.components.return_result.invoke_id.tag;
						dst[offset++] = src->dt_facility.components.return_result.invoke_id.len;
						dst[offset++] = src->dt_facility.components.return_result.invoke_id.id;
						//sequence - O
						if(1 == src->dt_facility.components.return_result.sequence.flag)
						{
							dst[offset++] = src->dt_facility.components.return_result.sequence.tag;
							dst[offset++] = src->dt_facility.components.return_result.sequence.len;
						}
						//operation code - O
						if(1 == src->dt_facility.components.return_result.opCode.flag)
						{
							dst[offset++] = src->dt_facility.components.return_result.opCode.tag;
							dst[offset++] = src->dt_facility.components.return_result.opCode.len;
							memcpy(&dst[offset],src->dt_facility.components.return_result.opCode.op,src->dt_facility.components.return_result.opCode.len);
							offset += src->dt_facility.components.return_result.opCode.len;
						}
						//parameters - O
						if(1 == src->dt_facility.components.return_result.param.flag)
						{
							if(1 == src->dt_facility.components.return_result.sequence.flag)
							{
								memcpy(&dst[offset],src->dt_facility.components.return_result.param.param,src->dt_facility.components.return_result.sequence.len);
								offset += src->dt_facility.components.return_result.sequence.len;
							}
							else
								dst[offset++] = src->dt_facility.components.return_result.param.param[0];
						}
					}
					if(src->dt_facility.components.return_error.tag == 0xa3)
					{
						dst[offset++] = src->dt_facility.components.return_error.tag;
						dst[offset++] = src->dt_facility.components.return_error.len;
						//invoke_id - M
						dst[offset++] = src->dt_facility.components.return_error.invoke_id.tag;
						dst[offset++] = src->dt_facility.components.return_error.invoke_id.len;
						dst[offset++] = src->dt_facility.components.return_error.invoke_id.id;
						//error code - M
						dst[offset++] = src->dt_facility.components.return_error.error.tag;
						dst[offset++] = src->dt_facility.components.return_error.error.len;
						memcpy(&dst[offset],src->dt_facility.components.return_error.error.er,src->dt_facility.components.return_error.error.len);
						offset += src->dt_facility.components.return_error.error.len;
						//parameters - O
						if(1 == src->dt_facility.components.return_error.param.flag)
							dst[offset++] = src->dt_facility.components.return_error.param.param;
					}
					if(src->dt_facility.components.reject.tag == 0xa4)
					{
						dst[offset++] = src->dt_facility.components.reject.tag;
						dst[offset++] = src->dt_facility.components.reject.len;
						//invoke_id - M
						dst[offset++] = src->dt_facility.components.reject.invoke_id.tag;
						dst[offset++] = src->dt_facility.components.reject.invoke_id.len;
						dst[offset++] = src->dt_facility.components.reject.invoke_id.id;
						//problem code - M
						dst[offset++] = src->dt_facility.components.reject.problem.tag;
						dst[offset++] = src->dt_facility.components.reject.problem.len;
						memcpy(&dst[offset],src->dt_facility.components.reject.problem.pro,src->dt_facility.components.reject.problem.len);
						offset += src->dt_facility.components.reject.problem.len;
					}
					if(length_position == 0)//zhugq,in case of "M"
						dst[0] = offset-1;
					else
						dst[1] = offset-2;
					*/
				break;
				case AIFG_IE_ID_DT_RP_MO_ADDR:
				case AIFG_IE_ID_DT_RP_MT_ADDR:
					if(src->dt_rpAddr.number_len == 0)
                    {
                        dst[offset] = 0;
                        offset++;
                    }
                    else
                    {
                        dst[offset++] = src->dt_rpAddr.number_len + 1;  //length
                        dst[offset++] = 0x80 | src->dt_rpAddr.number_type | src->dt_rpAddr.number_plan;
                        if(src->dt_rpAddr.number_len > 0)
                        {
                            memcpy(dst+offset, src->dt_rpAddr.number, src->dt_rpAddr.number_len);
                            offset += src->dt_rpAddr.number_len;
                        }
                    }
				break;
				case AIFG_IE_ID_DT_RP_UD:
					if (0 == m_o_flag){
						dst[offset++] = AIFG_IEI_DT_RP_UD;
					}
					dst[offset++] = src->dt_rpUD.len;
					memcpy(dst+offset, src->dt_rpUD.content, src->dt_rpUD.len);
					offset += src->dt_rpUD.len;
				break;
				case AIFG_IE_ID_DT_RP_CAUSE:
					dst[offset++] = src->dt_rpCause.diag_len + 1;
					dst[offset++] = src->dt_rpCause.cause;
					if(src->dt_rpCause.diag_len > 0)
						memcpy(dst+offset, src->dt_rpCause.diagnostic, src->dt_rpCause.diag_len);
				break;
				case AIFG_IE_ID_DT_CELLID:
					//to do
				break;
				case AIFG_IE_ID_DT_MSCM3:
					//to do
				break;
				case AIFG_IE_ID_DT_GROUPCIPHERKEY:
					//to do
				break;
				
				
			}
		break;
/////////////////////////////bssmap//////////////////////////////////////////////////
		case AIFG_MSG_BSSMAP:
			dst[offset++] = aifg_get_iei(ie_id);
			switch(ie_id){
				case AIFG_IE_ID_BM_CIC:
					dst[offset++] = src->bm_cic.pcm >> 3;
					dst[offset] = src->bm_cic.pcm;
					dst[offset] = (dst[offset] << 5) | (src->bm_cic.timeslot & 0x1F);
					offset++;
				break;
				case AIFG_IE_ID_BM_RESOURCEAVAIL:
					i = 0;
					while(i < 5){
						dst[offset++] = src->bm_resrcAvail.full_rate_channel[i] >>8;
						dst[offset++] = src->bm_resrcAvail.full_rate_channel[i] ;
						dst[offset++] = src->bm_resrcAvail.half_rate_channel[i] >>8;
						dst[offset++] = src->bm_resrcAvail.half_rate_channel[i] ;
						i++;
					}
				break;
				case AIFG_IE_ID_BM_CONNRELREQ:
					//Nothing to do
				break;
				case AIFG_IE_ID_BM_CAUSE:
					if(src->bm_cause.ext_value.flag == 1){
						dst[offset++] = 2;
						dst[offset++] = src->bm_cause.value|0x80;
						dst[offset++] = src->bm_cause.ext_value.value;
						
					}
					else{
						dst[offset++] = 1;
						dst[offset++] = src->bm_cause.value;
					}
				break;
				case AIFG_IE_ID_BM_IMSI:				
				case AIFG_IE_ID_BM_MOBILEID:
					goto MOBILE_ID; //The same as Mobile ID of DTAP
				break;
				case AIFG_IE_ID_BM_TMSI:
					dst[offset++] = 4;	//length
					memcpy(&(dst[offset]), src->bm_tmsi.value, 4);
					offset += 4;
				break;
				case AIFG_IE_ID_BM_MSNUM:
					dst[offset++] = src->bm_msNum.value;
				break;
				case AIFG_IE_ID_BM_L3HEADERINFO:
					dst[offset++] = 2;
					dst[offset++] = src->bm_L3HeaderInfo.pd & 0x0F;
					dst[offset++] = src->bm_L3HeaderInfo.ti & 0x0F;
				break;
				case AIFG_IE_ID_BM_ENCRYPTINFO:
					length_position = offset++;		//this byte is ie length which will be set later
					dst[offset++] = src->bm_encryptInfo.algorithm;
					if(src->bm_encryptInfo.algorithm > 1){
						//key
						memcpy(&(dst[offset]), src->bm_encryptInfo.key, 8);
						offset += 8;
					}
					if(length_position == 0)//zhugq,in case of "M"
							dst[0] = offset-1;
					else
							dst[1] = offset-2;	
				break;
				case AIFG_IE_ID_BM_CHANNELTYPE:
					length_position = offset++;  //skip length
					dst[offset++] = src->bm_channelType.speech_data_ind;
					dst[offset++] = src->bm_channelType.channel_rate_type;
					switch(src->bm_channelType.speech_data_ind){
						case 0x01:	//speech
							i = 0;
							while(i < src->bm_channelType.ext.speech.len){
								dst[offset++] = src->bm_channelType.ext.speech.ver[i++] | 0x80;
							}
							dst[offset-1] = src->bm_channelType.ext.speech.ver[i-1] & 0x7F;	//set ext flag of last extended byte to 0
						if(length_position == 0)//zhugq,in case of "M"
							dst[0] = offset-1;
						else
							dst[1] = offset-2;
						break;
						case 0x02:	//data
							dst[offset] = src->bm_channelType.ext.data_cfg.t_nt;
							dst[offset] = (dst[offset] << 6) | src->bm_channelType.ext.data_cfg.rate;
							if(1==src->bm_channelType.ext.data_cfg.allowed_data_rate.flag){
								dst[offset] = dst[offset] | 0x80;	//set ext flag to 1
								offset++;
								dst[offset] =  src->bm_channelType.ext.data_cfg.allowed_data_rate.value;
							}
						if(length_position == 0)//zhugq,in case of "M"
							dst[0] = offset;
						else
							dst[1] = offset-1;
						break;
						case 0x03:	//signalling
							
						break;
					}
				break;
				case AIFG_IE_ID_BM_PERIODICITY:
					dst[offset++] = src->bm_periodicity.value;
				break;
				case AIFG_IE_ID_BM_EXTRESOURCEIND:
					dst[offset] = src->bm_extResrcInd.sm & 0x01;
					dst[offset] = (dst[offset] << 1) | (src->bm_extResrcInd.tarr & 0x01);
					offset++;
				break;
				case AIFG_IE_ID_BM_TOTALRESOURCE:
					dst[offset++] = src->bm_totalResrc.full_rate_channel >> 8;
					dst[offset++] = src->bm_totalResrc.full_rate_channel ;
					dst[offset++] = src->bm_totalResrc.half_rate_channel >> 8;
					dst[offset++] = src->bm_totalResrc.half_rate_channel ;
				break;
				case AIFG_IE_ID_BM_LSAID:
					dst[offset++] = 3;
					dst[offset++] = src->bm_lsaId.value[0];
					dst[offset++] = src->bm_lsaId.value[1];
					dst[offset++] = src->bm_lsaId.value[2];
				break;
				//////////////////////////
				case AIFG_IE_ID_BM_LSAIDLIST:
                    length_position = offset++;
                     dst[offset++]=src->bm_lsaIdList.ep;
				 i=0;
					 while (i<src->bm_lsaIdList.lsa_num)
					 	{
					 	dst[offset++]=src->bm_lsaIdList.list[i].id[0];
						dst[offset++]=src->bm_lsaIdList.list[i].id[1];
						dst[offset++]=src->bm_lsaIdList.list[i].id[2];
						i++;
						}
					 //in case of "M''
					 dst[length_position]=src->bm_lsaIdList.lsa_num*3+1;
				break;
				case AIFG_IE_ID_BM_PRIORITY:
				     dst[offset++]=1;
					 dst[offset++]=(src->bm_priority.pci<<6)|(src->bm_priority.level<<2)|(src->bm_priority.qa<<1)|(src->bm_priority.pvi);
			    break;
				case AIFG_IE_ID_BM_CELLID:
					length_position = offset++;
				    dst[offset++]=src->bm_cellId.discriminator;
					switch(src->bm_cellId.discriminator){
					case 0:
						dst[offset++]=(src->bm_cellId.mcc[1]<<4)|src->bm_cellId.mcc[0];
						dst[offset++]=(src->bm_cellId.mnc[2]<<4)|src->bm_cellId.mcc[2];
						dst[offset++]=(src->bm_cellId.mnc[1]<<4)|src->bm_cellId.mnc[0];
						dst[offset++]=src->bm_cellId.LAC>>8;
						dst[offset++]=src->bm_cellId.LAC;
						dst[offset++]=src->bm_cellId.CI>>8;
						dst[offset++]=src->bm_cellId.CI;
						dst[length_position]=8;//zhugq,in case of "M"
					break;
					case 1:
						dst[offset++]=src->bm_cellId.LAC>>8;
						dst[offset++]=src->bm_cellId.LAC;
						dst[offset++]=src->bm_cellId.CI>>8;
						dst[offset++]=src->bm_cellId.CI;
						dst[length_position]=5;//zhugq
					break;
					case 2:
						dst[offset++]=src->bm_cellId.CI>>8;
						dst[offset++]=src->bm_cellId.CI;
						dst[length_position]=3;//zhugq
					break;
					default:break;
					}
				break;
				case AIFG_IE_ID_BM_BANDUSED:
					dst[offset++]=src->bm_bandUsed.value;
				break;
				case AIFG_IE_ID_BM_RRCAUSE:
					dst[offset++]=src->bm_rrCause.value;
				break;
				case AIFG_IE_ID_BM_DLCI:
					dst[offset++]=src->bm_dlci.value;
				break;
				case AIFG_IE_ID_BM_DTXFLAG:
					dst[offset++]=src->bm_dtx.value;
				break;
				case AIFG_IE_ID_BM_RESPREQ://do nothing
				break;
				case AIFG_IE_ID_BM_RESOURCEINDMEHTOD:
					dst[offset++]=src->bm_resrcIndMethod.value;
				break;
				case AIFG_IE_ID_BM_CICLIST:
					dst[offset++]=src->bm_cicList.status.len+1;
					dst[offset++]=src->bm_cicList.range;
					memcpy(&dst[offset],src->bm_cicList.status.content,src->bm_cicList.status.len);
					offset+=src->bm_cicList.status.len;
				break;
				case AIFG_IE_ID_BM_DIGNOSTIC:
					dst[offset++]=src->bm_diagnostics.err_msg.len+2;
					dst[offset++]=src->bm_diagnostics.err_pointer;
					dst[offset++]=src->bm_diagnostics.bit_pointer;
					memcpy(&dst[offset],src->bm_diagnostics.err_msg.msg,src->bm_diagnostics.err_msg.len);
					offset+=src->bm_diagnostics.err_msg.len;	
				break;
				case AIFG_IE_ID_BM_CHOSENCHANNEL:
					dst[offset++]=(src->bm_chosenChannel.mode<<4)|src->bm_chosenChannel.channel;
				break;
				case AIFG_IE_ID_BM_CIPHERRESPMODE:
					dst[offset++]=src->bm_cipherRespMode.value;
				break;
				case AIFG_IE_ID_BM_CHANNELNEEDED:
					dst[offset++]=src->bm_channelNeeded.value;
				break;
				case AIFG_IE_ID_BM_TRACETYPE:
					dst[offset++]=src->bm_traceType.value;
				break;
				case AIFG_IE_ID_BM_TRIGGERID:
					dst[offset++]=src->bm_triggerId.len;
					memcpy(&dst[offset],src->bm_triggerId.content,src->bm_triggerId.len);
					offset+=src->bm_triggerId.len;
				break;
				case AIFG_IE_ID_BM_TRACEREF:
					dst[offset++]=src->bm_traceRef.value>>8;
					dst[offset++]=src->bm_traceRef.value;
				break;
				case AIFG_IE_ID_BM_TRANSACTIONID:
					dst[offset++]=2;
					dst[offset++]=src->bm_transId.value>>8;
					dst[offset++]=src->bm_transId.value;
				break;
				case AIFG_IE_ID_BM_OMCID:
					dst[offset++]=src->bm_omcId.len;
					memcpy(&dst[offset],src->bm_omcId.id,src->bm_omcId.len);
					offset+=src->bm_omcId.len;
				break;
				case AIFG_IE_ID_BM_FORWARDIND:
					dst[offset++]=src->bm_fowardInd.value;
				break;
				case AIFG_IE_ID_BM_CHOSENENCRYPT:
					dst[offset++]=src->bm_chosenEncrypt.value;
				break;
				case AIFG_IE_ID_BM_CIRCUITPOOL:
					dst[offset++]=src->bm_circuitPool.value;
				break;
				case AIFG_IE_ID_BM_CIRCUITPOOLLIST:
					dst[offset++]=src->bm_circuitPoolList.num;
					memcpy(&dst[offset],src->bm_circuitPoolList.circuit,src->bm_circuitPoolList.num);
					offset+=src->bm_circuitPoolList.num;
				break;
				case AIFG_IE_ID_BM_TIMEIND:
					dst[offset++]=src->bm_timeId.value;
				break;
				case AIFG_IE_ID_BM_RESOURCESITUATION:
					length_position = offset++;
					i=0;
					while(i<src->bm_resrcSit.band_num){
						dst[offset++]=(src->bm_resrcSit.band[i].band_ind<<4)|src->bm_resrcSit.band[i].channel_type;
						if(src->bm_resrcSit.band[i].channel_num>127){
						dst[offset++]=(src->bm_resrcSit.band[i].channel_num>>8)|0x80;
						dst[offset++]=src->bm_resrcSit.band[i].channel_num;}
						else
						dst[offset++]=src->bm_resrcSit.band[i].channel_num;
						i++;}
					if(length_position == 0)//zhugq,in case of "M"
						dst[0] = offset-1;
					else
						dst[1] = offset-2;
				break;
				case AIFG_IE_ID_BM_CURCHANNELTYPE1:
					dst[offset++]=(src->bm_curChannelType1.channel_mode<<4)|src->bm_curChannelType1.channel;
				break;
				case AIFG_IE_ID_BM_QUEUEIND:
					dst[offset++]=src->bm_queuingInd.value<<1;
				break;
				case AIFG_IE_ID_BM_SPEECHVER:
					dst[offset++]=src->bm_speechVer.value;
				break;
				case AIFG_IE_ID_BM_ASSIGNREQUIREMENT:
					dst[offset++]=src->bm_assignReq.value;
				break;
				case AIFG_IE_ID_BM_TALKERFLAG://do nothing
				break;
				case AIFG_IE_ID_BM_GROUPCALLREF:
					dst[offset++]=5;
					groupref:
					dst[offset++]=src->bm_groupRef.binary_code>>19;
					dst[offset++]=src->bm_groupRef.binary_code>>11;
					dst[offset++]=src->bm_groupRef.binary_code>>3;
					dst[offset]=((src->bm_groupRef.binary_code & 0x07)<<5)|(src->bm_groupRef.sf<<4);
					dst[offset]=dst[offset]|(src->bm_groupRef.af<<3)|src->bm_groupRef.call_priority;
					offset++;
					dst[offset++]=src->bm_groupRef.cipher_info<<4;
				break;
				case AIFG_IE_ID_BM_EMLPP:
					dst[offset++]=src->bm_eMLPP.value;
				break;
				case AIFG_IE_ID_BM_CFGEVOIND:
					dst[offset++]=src->bm_cfgEvoInd.value;
				break;
				case AIFG_IE_ID_BM_BSSOLDTONEW:
					dst[offset++]=src->bm_bssOldtoNew.len;
					memcpy(&dst[offset],src->bm_bssOldtoNew.content,src->bm_bssOldtoNew.len);
				    offset+=src->bm_bssOldtoNew.len;
				break;
				case AIFG_IE_ID_BM_LSAINFO:
					dst[offset++]=src->bm_lsaInfo.lsa_num*4+1;
					dst[offset++]=src->bm_lsaInfo.lsa_only;
					 i=0;
					while(i<src->bm_lsaInfo.lsa_num)
						{
						dst[offset++]=src->bm_lsaInfo.info[i].priority;
						dst[offset++]=src->bm_lsaInfo.info[i].id[0];
						dst[offset++]=src->bm_lsaInfo.info[i].id[1];
						dst[offset++]=src->bm_lsaInfo.info[i].id[2];
						i++;}
				break;
				case AIFG_IE_ID_BM_LOCATIONINFO:
					dst[offset++]=src->bm_locInfo.len;
					memcpy(&dst[offset],src->bm_locInfo.info,src->bm_locInfo.len);
					offset+=src->bm_locInfo.len;
				break;
				case AIFG_IE_ID_BM_CLASSMARKINFO2:
					classmarkinfo2:
					dst[offset++]=3;
					i = (src->bm_cmInfo2.rev_level<<5) | (src->bm_cmInfo2.es_ind<<4);
					i = i | (src->bm_cmInfo2.a5_1<<3) | src->bm_cmInfo2.rf_power_cap;
					dst[offset++] = i;
					j = (src->bm_cmInfo2.ps_cap<<6)|(src->bm_cmInfo2.ss_screen_ind<<4);
					j = j|(src->bm_cmInfo2.sm_cap<<3)|(src->bm_cmInfo2.vbs<<2);
					j = j|(src->bm_cmInfo2.vgcs<<1)|src->bm_cmInfo2.fc;
					dst[offset++] = j;
					k = (src->bm_cmInfo2.cm3<<7)|(src->bm_cmInfo2.lcsva_cap<<5);
					k = k|(src->bm_cmInfo2.so_lsa<<3)|(src->bm_cmInfo2.cmsp<<2);
					k = k|(src->bm_cmInfo2.a5_3<<1)|src->bm_cmInfo2.a5_2;
					dst[offset++] = k;
				break;
				case AIFG_IE_ID_BM_CELLIDLIST:
					length_position = offset++;
				    i=0;
				    dst[offset++]=src->bm_cellIdList.discriminator;
					switch(src->bm_cellIdList.discriminator){
					case 0:
						while(i<src->bm_cellIdList.cid_num){
					    dst[offset++]=(src->bm_cellIdList.cell_id[i].mcc[1]<<4)|src->bm_cellIdList.cell_id[i].mcc[0];
						dst[offset++]=(src->bm_cellIdList.cell_id[i].mnc[2]<<4)|src->bm_cellIdList.cell_id[i].mcc[2];
						dst[offset++]=(src->bm_cellIdList.cell_id[i].mnc[1]<<4)|src->bm_cellIdList.cell_id[i].mnc[0];
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC>>8;
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC;
						dst[offset++]=src->bm_cellIdList.cell_id[i].CI>>8;
						dst[offset++]=src->bm_cellIdList.cell_id[i].CI;
						i++;}
					break;
					case 1:
                        while(i<src->bm_cellIdList.cid_num){
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC>>8;
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC;
						dst[offset++]=src->bm_cellIdList.cell_id[i].CI>>8;
						dst[offset++]=src->bm_cellIdList.cell_id[i].CI;
						i++;}
					break;
					case 2:
						while(i<src->bm_cellIdList.cid_num){
						dst[offset++]=src->bm_cellIdList.cell_id[i].CI>>8;
						dst[offset++]=src->bm_cellIdList.cell_id[i].CI;
						i++;}
					break;
					case 4:
						while(i<src->bm_cellIdList.cid_num){
					    dst[offset++]=(src->bm_cellIdList.cell_id[i].mcc[1]<<4)|src->bm_cellIdList.cell_id[i].mcc[0];
						dst[offset++]=(src->bm_cellIdList.cell_id[i].mnc[2]<<4)|src->bm_cellIdList.cell_id[i].mcc[2];
						dst[offset++]=(src->bm_cellIdList.cell_id[i].mnc[1]<<4)|src->bm_cellIdList.cell_id[i].mnc[0];
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC>>8;
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC;
						i++;}
					break;
					case 5:
						while(i<src->bm_cellIdList.cid_num){
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC>>8;
						dst[offset++]=src->bm_cellIdList.cell_id[i].LAC;
						i++;}
					break;
					}
					if(length_position == 0)//zhugq,in case of "M"
						dst[0] = offset-1;
					else
						dst[1] = offset-2;
				break;
				case AIFG_IE_ID_BM_CLASSMARKINFO3:
					//to do
				break;
				case AIFG_IE_ID_BM_L3INFO:
					//to do
				break;
				case AIFG_IE_ID_BM_CLASSMARKINFO1:
					//to do
				break;
				case AIFG_IE_ID_BM_L3MSGCONTENT:
					//to do
				break;
			}
		break;
			   
	}
	
	return offset;

ERR_PROC:
	//	aifg_debug_print(aifg_event, (void*)src, NULL);
	return AIFG_ERROR;
}
//End of information element process functions definition------------------------------

