2228 lines
79 KiB
C
2228 lines
79 KiB
C
/********************************************************************
|
|
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------------------------------
|
|
|