/******************************************************************** 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(imobileId.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(imobileId.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(idt_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 (ibm_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(ibm_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(ibm_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(ibm_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(ibm_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(ibm_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(ibm_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(ibm_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------------------------------