FreeCalypso > hg > freecalypso-sw
changeset 664:d36f647c2432
gsm-fw/comlib: initial import of TI's source
cl_des.c and cl_imei.c are from the Leonardo semi-src; others are from LoCosto
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 28 Sep 2014 05:09:53 +0000 |
parents | 643379e7e141 |
children | 39bacc7d5c49 |
files | gsm-fw/comlib/cl_des.c gsm-fw/comlib/cl_imei.c gsm-fw/comlib/cl_list.c gsm-fw/comlib/cl_md5.c gsm-fw/comlib/cl_ribu.c gsm-fw/comlib/cl_rlcmac.c gsm-fw/comlib/cl_shrd.c |
diffstat | 7 files changed, 2822 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/comlib/cl_des.c Sun Sep 28 05:09:53 2014 +0000 @@ -0,0 +1,368 @@ +/* ++----------------------------------------------------------------------------- +| Project : COMLIB +| Modul : cl_des.c ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : Definitions of common library functions: Implementation of + DES algorithm ++----------------------------------------------------------------------------- +*/ +/* + * Version 1.0 + */ + +/**********************************************************************************/ + +/* +NOTE: +*/ + +/**********************************************************************************/ + +#ifndef CL_DES_C +#define CL_DES_C + +/* + * DES routine is used only on Calypso platform + */ +#if defined(CL_IMEI_CALYPSO_PLATFORM) && defined(FF_PROTECTED_IMEI) + +#include <string.h> +#include "typedefs.h" +#include "cl_des.h" + + +/* 64+64+17*56+16*48+64+17*32+17*32 = 3000 bytes */ +static UBYTE binmsg[64] , binkey[64], cd[17][56] , deskey[16][48] , ip[64]; +static UBYTE l[17][32] , r[17][32]; +/* 64+64+32+32+64+64+17*3+2 = 373 bytes */ +static UBYTE rnew[64] , xorres[64] , scale[32] , perm[32] , rl[64] , encpt[64]; + +/* 64+16+48+64+48+32+64+8*66 = 864 bytes */ +const UBYTE shtamt[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; +const UBYTE iporder[64] = {58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4,62,54, + 46,38,30,22,14,6,64,56,48,40,32,24,16,8,57,49,41,33, + 25,17,9,1,59,51,43,35,27,19,11,3,61,53,45,37,29,21, + 13,5,63,55,47,39,31,23,15,7}; +const UBYTE pc1[64] = {57,49,41,33,25,17,9,1,58,50,42,34,26,18,10,2,59,51,43, + 35,27,19,11,3,60,52,44,36,63,55,47,39,31,23,15,7,62,54, + 46,38,30,22,14,6,61,53,45,37,29,21,13,5,28,20,12,4}; +const UBYTE pc2[48] = {14,17,11,24,1,5,3,28,15,6,21,10,23,19,12,4,26,8, + 16,7,27,20,13,2,41,52,31,37,47,55,30,40,51,45,33, + 48,44,49,39,56,34,53,46,42,50,36,29,32}; +const UBYTE e[48] = {32,1,2,3,4,5,4,5,6,7,8,9,8,9,10,11,12,13,12,13,14,15, + 16,17,16,17,18,19,20,21,20,21,22,23,24,25,24,25,26,27, + 28,29,28, 29,30,31,32,1}; +const UBYTE sp[32] = {16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10, + 2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25}; +const UBYTE ipinv[64] = {40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,38,6,46, + 14,54,22,62,30,37,5,45,13,53,21,61,29,36,4,44,12,52, + 20,60,28,35,3,43,11,51,19,59,27,34,2,42,10,50,18,58, + 26,33,1,41,9,49,17,57,25}; +const UBYTE s[8][66] = {{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,0,15,7,4,14,2,13, + 1,10,6,12,11,9,5,3,8,4,1,14,8,13,6,2,11,15,12,9,7,3,10, + 5,0,15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13}, + {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,3,13,4,7,15,2,8, + 14,12,0,1,10,6,9,11,5,0,14,7,11,10,4,13,1,5,8,12,6,9,3, + 2,15,13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9}, + {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,13,7,0,9,3,4,6, + 10,2,8,5,14,12,11,15,1,13,6,4,9,8,15,3,0,11,1,2,12,5, + 10,14,7,1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12 }, + {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,13,8,11,5,6,15, + 0,3,4,7,2,12,1,10,14,9,10,6,9,0,12,11,7,13,15,1,3,14, + 5,2,8,4,3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14 }, + {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,14,11,2,12,4,7, + 13,1,5,0,15,10,3,9,8,6,4,2,1,11,10,13,7,8,15,9,12,5,6, + 3,0,14,11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3 }, + {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,10,15,4,2,7,12, + 9,5,6,1,13,14,0,11,3,8,9,14,15,5,2,8,12,3,7,0,4,10,1, + 13,11,6,4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13 }, + {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,13,0,11,7,4,9,1, + 10,14,3,5,12,2,15,8,6,1,4,11,13,12,3,7,14,10,15,6,8,0, + 5,9,2,6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12 }, + {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,1,15,13,8,10,3,7, + 4,12,5,6,11,0,14,9,2,7,11,4,1,9,12,14,2,0,6,10,13,15,3, + 5,8,2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11 }}; + + +/*==== FUNCTIONS ==================================================*/ + +/* ++------------------------------------------------------------------------------ +| Function : des_hex2bin4 ++------------------------------------------------------------------------------ +| Description : The function converts a 4 bit hex value to 4 binary values +| +| Parameters : hex : value in hex +| m : pointer to buffer of 4 elements to store binary values ++------------------------------------------------------------------------------ +*/ +LOCAL void des_hex2bin4(UBYTE hex, UBYTE *m) +{ + m[0] = (hex & 0x08) >> 3; + m[1] = (hex & 0x04) >> 2; + m[2] = (hex & 0x02) >> 1; + m[3] = hex & 0x01; +} + +/* ++------------------------------------------------------------------------------ +| Function : des_hex2bin8 ++------------------------------------------------------------------------------ +| Description : The function converts a 8 bit hex value to 8 binary values +| +| Parameters : hex : value in hex +| m : pointer to buffer of 8 elements to store binary values ++------------------------------------------------------------------------------ +*/ +LOCAL void des_hex2bin8(UBYTE hex, UBYTE *m) +{ + m[0] = (hex & 0x80) >> 7; + m[1] = (hex & 0x40) >> 6; + m[2] = (hex & 0x20) >> 5; + m[3] = (hex & 0x10) >> 4; + m[4] = (hex & 0x08) >> 3; + m[5] = (hex & 0x04) >> 2; + m[6] = (hex & 0x02) >> 1; + m[7] = hex & 0x01; +} + +/* ++------------------------------------------------------------------------------ +| Function : des_bin2hex ++------------------------------------------------------------------------------ +| Description : The function converts 8 bin values to an 8 bit hex value +| +| Parameters : m[8] : input bin values +| Return : converted hex value ++------------------------------------------------------------------------------ +*/ + +LOCAL UBYTE des_bin2hex(UBYTE *m) +{ + UBYTE hex; + return hex = (m[0]<<7) | (m[1]<<6) | (m[2]<<5) | (m[3]<<4) | + (m[4]<<3) | (m[5]<<2) | (m[6]<<1) | m[7]; +} + + + +/* ++------------------------------------------------------------------------------ +| Function : des_shift ++------------------------------------------------------------------------------ +| Description : The function performs shifting +| +| Parameters : dst : pointer to destination buffer +| src : pointer to source buffer +| sht : shift value ++------------------------------------------------------------------------------ +*/ + +LOCAL void des_shift(UBYTE *dst, UBYTE *src, UBYTE sht) +{ + UBYTE c1 , c2 , d1 , d2; + int i; + + c1 = src[0]; + c2 = src[1]; + d1 = src[28]; + d2 = src[29]; + + for ( i = 0 ; i < 28 - sht ; i++) { + dst[i] = src[i + sht]; /* copying c[i] */ + dst[28 + i] = src[28 + i + sht]; /* copying d[i] */ + } + + if (sht == 1){ + dst[27] = c1; + dst[55] = d1; + } else { + dst[26] = c1; + dst[27] = c2; + dst[54] = d1; + dst[55] = d2; + } +} + +/* ++------------------------------------------------------------------------------ +| Function : des_indx ++------------------------------------------------------------------------------ +| Description : The function generates index for S table +| +| Parameters : m[6] : +| Return : index value ++------------------------------------------------------------------------------ +*/ +LOCAL UBYTE des_indx(UBYTE *m) +{ + return( (((m[0]<<1) + m[5])<<4) + ((m[1]<<3) + (m[2]<<2) + (m[3]<<1) + m[4])); +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_des ++------------------------------------------------------------------------------ +| Description : The function performs DES encrypting or decrypting +| +| Parameters : inMsgPtr : pointer to input message M. The length of message +| has to be min. 8 bytes e.g. M = 0123456789abcdef +| desKeyPtr : pointer to DES key. Length has to be 8 bytes +| outMsgPtr : output encrypted/decrypted message. The length is 8 b. +| code : CL_DES_ENCRYPTION, CL_DES_DECRYPTION ++------------------------------------------------------------------------------ +*/ +EXTERN void cl_des(UBYTE *inMsgPtr, UBYTE *desKeyPtr, UBYTE *outMsgPtr, UBYTE code) +{ + + int y , z , g; + UBYTE temp, more; + + /* + * convert message from hex to bin format + */ + for(y = 0; y < 8; y++){ + des_hex2bin8(inMsgPtr[y], &binmsg[8 * y]); + } + + /* + * Convert DES key value from hex to bin format + */ + for( y = 0; y < 8; y++){ + des_hex2bin8(desKeyPtr[y], &binkey[8 * y]); + } + + /* + * Step 1: Create 16 subkeys, each of which is 48-bits long. + * + * The 64-bit key is permuted according to the table pc1, + * to get the 56 bit subkey K+. The subkey K+ consists of left + * and right halves C0 and D0, where each half has 28 bits. + */ + for(y = 0 ; y < 56 ; y++) + cd[0][y] = binkey[pc1[y] - 1]; + /* + * Create futher 15 subkeys C1-C16 and D1-D16 by left shifts of + * each previous key, i.e. C2 and D2 are obtained from C1 and D1 and so on. + */ + for(y = 0 ; y < 16 ; y++) + des_shift(cd[y + 1] , cd[y] , shtamt[y]); + + /* + * Form the keys K1-K16 by applying the pc2 permutation + * table to each of the concatenated pairs CnDn. + */ + for(y = 0; y < 16; y++){ + for(z = 0 ; z < 48 ; z++){ + deskey[y][z] = cd[y + 1][pc2[z] - 1]; + } + } + + /* + * Step 2: Encode each 64-bit block of data + * + * Perform initial permutation IP of th e64 bits the message data M. + * This rearranges the bits according to the iporder table. + */ + for(y = 0; y < 64; y++) + ip[y] = binmsg[iporder[y] - 1]; + + /* + * Divide the permuted block IP into left half L0 + * and a right half R0 each of 32 bits. + */ + for(y = 0; y < 32; y++){ + l[0][y] = ip[y]; + r[0][y] = ip[y + 32]; + } + + /* + * Proceed through 16 iterations, operation on two blocks: + * a data block of 32 bits and a key Kn of 48 bits to produce a block of 32 + * bits. This results in a final block L16R16. In each iteration, we take + * the right 32 bits of the previous result and make them the left 32 bits + * of the current step. For the right 32 bits in the current step, we XOR + * the left 32 bits of the previous step. + */ + for (y = 0; y < 16; y++){ + if (code == CL_DES_ENCRYPTION)/* encryption */ + g = y; + else /* decryption */ + g = 15 - y; + + /* + * Copie the right bits Rn of the current step + * to the left bits Ln+1 of the next step + */ + for(z = 0; z < 32; z++) + l[y + 1][z] = r[y][z]; + + /* + * Expand the block Rn from 32 to 48 bits by using the selection table E. + * Then XOR the result with the key Kn+1. + */ + for(z = 0; z < 48; z++){ + rnew[z] = r[y][e[z] - 1]; + xorres[z] = (rnew[z] ^ deskey[g][z]); + } + + /* + * We now have 48 bits, or eight groups of six bits. We use them as + * addresses in tables calle "S boxes". Each group of six bits will + * give us an address in a different S box. + */ + for(z = 0; z < 8; z++){ + temp = s[z][des_indx(&xorres[z * 6])]; + des_hex2bin4(temp, &scale[z * 4]); + } + + /* + * Perform a permutation P of the S box output. + */ + for(z = 0; z < 32; z++) + perm[z] = scale[sp[z] - 1]; + + /* + * XOR the result with the left half of current step + * and copie it to the right half of the next step + */ + for(z = 0; z < 32; z++) + r[y+1][z] = (l[y][z] ^ perm[z]); + } + + /* + * Reserve the order of the final block L16R16 to R16L16 + */ + for( z = 0; z < 32; z++){ + rl[z] = r[16][z]; + rl[z + 32] = l[16][z]; + } + + /* + * Apply the final inverse permutation IP + */ + for( z = 0; z < 64; z++){ + encpt[z] = rl[ipinv[z] - 1]; + } + + /* + * Convert from bin to hex format + */ + for(z = 0; z < 8; z++){ + outMsgPtr[z] = des_bin2hex(&encpt[8 * z]); + } +} +#endif /* CL_IMEI_CALYPSO_PLATFORM */ +#endif /* CL_DES_C */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/comlib/cl_imei.c Sun Sep 28 05:09:53 2014 +0000 @@ -0,0 +1,390 @@ +/* ++----------------------------------------------------------------------------- +| Project : COMLIB +| Modul : cl_imei.c ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : Definitions of common library functions: IMEI decryption with + DES algorithm ++----------------------------------------------------------------------------- +*/ +/* + * Version 1.0 + */ + +/**********************************************************************************/ + +/* +NOTE: +*/ + +/**********************************************************************************/ + +#ifndef CL_IMEI_C +#define CL_IMEI_C + +#include "typedefs.h" +#include "vsi.h" /* to get a lot of macros */ + +#ifndef _SIMULATION_ +#include "ffs/ffs.h" +#include "config/chipset.cfg" +#include "config/board.cfg" +#include "memif/mem.h" +#include "pcm.h" +#endif /* ifdef SIMULATION */ + +#include "cl_imei.h" +#include "cl_des.h" +#include <string.h> + +#if defined(CL_IMEI_CALYPSO_PLUS_PLATFORM) && defined(FF_PROTECTED_IMEI) +#include "secure_rom/secure_rom.h" +#endif + +static UBYTE stored_imei[CL_IMEI_SIZE]; /* when the imei is read once, the value + is stored in this buffer */ +static UBYTE imei_flag = 0; /* this flag indicates, if IMEI was successful read + and is stored in the stored_imei buffer */ + +#if !defined (CL_IMEI_CALYPSO_PLUS_PLATFORM) +/* Default IMEISV for D-Sample 00440000-350-111-20 */ +const UBYTE C_DEFAULT_IMEISV_DSAMPLE[CL_IMEI_SIZE] = + {0x00, 0x44, 0x00, 0x00, 0x35, 0x01, 0x11, 0x20}; +#define CL_IMEI_FFS_PATH "/gsm/imei.enc" +#endif /* CL_IMEI_CALYPSO_PLATFORM */ + +#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM +/* Default IMEISV for E-Sample 00440000-351-222-30 */ +const UBYTE C_DEFAULT_IMEISV_ESAMPLE[CL_IMEI_SIZE] = + {0x00, 0x44, 0x00, 0x00, 0x35, 0x12, 0x22, 0x30}; +#endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */ + +/*==== FUNCTIONS ==================================================*/ +#ifdef FF_PROTECTED_IMEI + +#ifdef CL_IMEI_CALYPSO_PLATFORM +/* ++------------------------------------------------------------------------------ +| Function : get_dieID ++------------------------------------------------------------------------------ +| Description : the function reads the Die-ID from base band processor and +| extracts it from 4 BYTEs to 8 BYTEs. +| +| Parameters : inBufSize - size of buffer where to store Die ID, min.8 BYTE +| *outBufPtr - pointer to buffer where to store the Die ID +| Return : void ++------------------------------------------------------------------------------ +*/ +LOCAL void get_dieID(USHORT inBufSize, UBYTE *outBufPtr) +{ + int i; + USHORT *outBuf16 = (USHORT*)&outBufPtr[0]; + volatile USHORT *reg_p = (USHORT *) CL_IMEI_DIE_ID_REG; + + TRACE_FUNCTION("get_dieID()"); + + if(inBufSize < CL_IMEI_DIE_ID_SIZE){ + TRACE_ERROR("CL IMEI ERROR: buffer size for Die ID to short!"); + } +#ifdef IMEI_DEBUG + TRACE_EVENT_P1("CL IMEI INFO: Die-ID address(0x%x)", CL_IMEI_DIE_ID_REG); +#endif + for (i = 0; i < CL_IMEI_DIE_ID_SIZE; i++) { + /* Die ID is 4 BYTE long, extract it to 8 BYTE. */ + outBuf16[i] = (USHORT)(*(UINT8*)(reg_p)++); + } +} + +/* ++------------------------------------------------------------------------------ +| Function : ffs_get_imeisv ++------------------------------------------------------------------------------ +| Description : the function reads IMEI from FFS +| +| Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE +| *outBufPtr - pointer to buffer where to store the IMEI +| Return : 0 - OK +| <0 - ERROR ++------------------------------------------------------------------------------ +*/ +LOCAL BYTE ffs_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr) +{ + UBYTE i; + UBYTE isdid_buf[CL_IMEI_ISDID_SIZE]; + UBYTE r_dieId[CL_DES_KEY_SIZE]; /* read Die ID */ + UBYTE d_dieId[CL_DES_KEY_SIZE]; /* deciphered Die ID */ + SHORT ret; + + TRACE_FUNCTION("ffs_get_imeisv()"); + + if(inBufSize < CL_IMEI_SIZE){ + TRACE_ERROR("CL IMEI ERROR: buffer size for IMEI to short!"); + return CL_IMEI_ERROR; + } + + /* + * Read ISDID(enciphered IMEISV+DieID) from FFS. + */ + if((ret = ffs_file_read(CL_IMEI_FFS_PATH, isdid_buf, CL_IMEI_ISDID_SIZE)) >= EFFS_OK) + { + /* + * Read Die ID for using as DES key + */ + get_dieID(CL_DES_KEY_SIZE, r_dieId); + /* + * Call DES algorithm routine + */ + /* decipher first 8 BYTEs */ + cl_des(&isdid_buf[0], r_dieId, outBufPtr, CL_DES_DECRYPTION); + /* decipher the rest 8 BYTEs */ + cl_des(&isdid_buf[CL_DES_BUFFER_SIZE], r_dieId, d_dieId, CL_DES_DECRYPTION); + if(!memcmp(d_dieId, r_dieId, CL_DES_KEY_SIZE)) + { + /* Die ID is valid */ + ret = CL_IMEI_OK; + } else {/* Die ID is corrupted */ + char pr_buf[126]; + TRACE_ERROR("CL IMEI ERROR: Die ID is corrupted"); + sprintf(pr_buf,"Read DieID: %02x %02x %02x %02x %02x %02x %02x %02x", + r_dieId[0], r_dieId[1], r_dieId[2], r_dieId[3], + r_dieId[4], r_dieId[5], r_dieId[6], r_dieId[7]); + TRACE_ERROR(pr_buf); + sprintf(pr_buf,"Deciphered DieID: %02x %02x %02x %02x %02x %02x %02x %02x", + d_dieId[0], d_dieId[1], d_dieId[2], d_dieId[3], + d_dieId[4], d_dieId[5], d_dieId[6], d_dieId[7]); + TRACE_ERROR(pr_buf); + + ret = CL_IMEI_INVALID_DIE_ID; + } + } else { + ret = CL_IMEI_READ_IMEI_FAILED; + } + + return ret; + +}/* ffs_get_imeisv() */ +#endif /* CL_IMEI_CALYPSO_PLATFORM */ + + +#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM +/* ++------------------------------------------------------------------------------ +| Function : securerom_get_imeisv ++------------------------------------------------------------------------------ +| Description : the function reads IMEI from Secure ROM +| +| Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE +| *outBufPtr - pointer to buffer where to store the IMEI +| Return : 0 - OK +| <0 - ERROR ++------------------------------------------------------------------------------ +*/ +LOCAL BYTE securerom_get_imeisv (USHORT inBufSize, UBYTE *outBufPtr) +{ + BYTE ret; + + TRACE_FUNCTION("securerom_get_imeisv()"); + + if((ret = securerom_drv(inBufSize, outBufPtr)) == CL_IMEI_OK){ + return CL_IMEI_OK; + } else { + return CL_IMEI_READ_IMEI_FAILED; + } +} +#endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */ + +/* ++------------------------------------------------------------------------------ +| Function : get_secure_imeisv ++------------------------------------------------------------------------------ +| Description : the function reads IMEI either from FFS or from Secure ROM of +| from other locations depended on hardware platform +| +| Parameters : inBufSize - size of buffer where to store IMEI, min. 8 BYTE +| *outBufPtr - pointer to buffer where to store the IMEI +| Return : 0 - OK +| negative value - ERROR ++------------------------------------------------------------------------------ +*/ +LOCAL BYTE get_secure_imeisv(USHORT inBufSize, UBYTE *outBufPtr) +{ + BYTE ret = 0; + UBYTE chipset = CHIPSET; + UBYTE board = BOARD; + + TRACE_FUNCTION("get_secure_imeisv()"); + +/* + * SW is running on Calypso platform (D-Sample) + */ +#ifdef CL_IMEI_CALYPSO_PLATFORM + /* + * Read IMEI from FFS inclusive deciphering with DES. + */ + if((ret = ffs_get_imeisv (inBufSize, outBufPtr)) == CL_IMEI_OK) + { + /* store IMEI */ + memcpy(stored_imei, outBufPtr, CL_IMEI_SIZE); + imei_flag = 1; + return CL_IMEI_OK; + } +#else /* CL_IMEI_CALYPSO_PLATFORM */ +/* + * SW is running on Calypso plus platform (E-Sample) + */ +#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM + if((ret = securerom_get_imeisv (inBufSize, outBufPtr)) == CL_IMEI_OK) + { + /* store IMEI */ + memcpy(stored_imei, outBufPtr, CL_IMEI_SIZE); + imei_flag = 1; + return CL_IMEI_OK; + } +#else /* CL_IMEI_CALYPSO_PLUS_PLATFORM */ +/* + * SW is running on an other platform (neither Calypso nor Calypso plus) + */ +#ifdef CL_IMEI_OTHER_PLATFORM + { + TRACE_EVENT_P2("CL IMEI WARNING: unknown hardware: board=%d, chipset=%d, return default imei", + board, chipset); + memcpy(outBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE); + return CL_IMEI_OK; + } +#endif /* CL_IMEI_OTHER_PLATFORM */ +#endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */ +#endif /* CL_IMEI_CALYPSO_PLATFORM */ + + return ret; /* get_secure_imeisv is failed, return error code */ + +} /* get_secure_imeisv() */ + + +#endif /* FF_PROTECTED_IMEI */ + +/* ++------------------------------------------------------------------------------ +| Function : cl_get_imeisv ++------------------------------------------------------------------------------ +| Description : Common IMEI getter function +| +| Parameters : imeiBufSize - size of buffer where to store IMEI, min 8 BYTEs +| *imeiBufPtr - pointer to buffer where to store the IMEI +| imeiType - indicates, if the IMEI should be read from +| FFS/Secure ROM (value=CL_IMEI_GET_SECURE_IMEI) or +| if the already read and stored IMEI (if available) +| should be delivered (value=CL_IMEI_GET_STORED_IMEI) +| The second option should be used only by ACI or +| BMI to show the IMEISV on mobile's display or +| in terminal window, e.g. if user calls *#06#. +| For IMEI Control reason (used by ACI), the value +| has to be CL_IMEI_CONTROL_IMEI +| Return : OK - 0 +| ERROR - negative values ++------------------------------------------------------------------------------ +*/ +extern BYTE cl_get_imeisv(USHORT imeiBufSize, UBYTE *imeiBufPtr, UBYTE imeiType) +{ + BYTE ret = 0; + + TRACE_FUNCTION("cl_get_imeisv()"); + +#ifdef _SIMULATION_ + memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE); + return CL_IMEI_OK; +#else /* _SIMULATION_ */ + +#ifdef FF_PROTECTED_IMEI + /* + * The user has required a stored IMEI. If it has been already read + * and stored, so return stored IMEI + */ + if((imeiType == CL_IMEI_GET_STORED_IMEI) && (imei_flag == 1)){ + memcpy(imeiBufPtr, stored_imei, CL_IMEI_SIZE); + return CL_IMEI_OK; + } + /* + * The user has required a secure IMEI. Read IMEI from FFS or from Secure ROM + */ + if((ret = get_secure_imeisv(imeiBufSize, imeiBufPtr)) == CL_IMEI_OK) + { + return CL_IMEI_OK; + } else { + TRACE_ERROR("CL IMEI FATAL ERROR: IMEI not available!"); + /* + * Notify the Frame entity about FATAL ERROR, but not in the case, + * if ACI is checking IMEI, because ACI will take trouble about it. + */ + if (imeiType != CL_IMEI_CONTROL_IMEI){ + TRACE_ASSERT(ret == CL_IMEI_OK); + } + return ret; + } +/* + * The feature flag FF_PROTECTED_IMEI is not enabled. + */ +#else /* FF_PROTECTED_IMEI */ + +/* + * Return default CALYPSO+ IMEISV value + */ +#ifdef CL_IMEI_CALYPSO_PLUS_PLATFORM + + TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number"); + memcpy(imeiBufPtr, C_DEFAULT_IMEISV_ESAMPLE, CL_IMEI_SIZE); + +/* + * CL_IMEI_CALYPSO_PLATFORM or CL_IMEI_OTHER_PLATFORM is defined. + * Try to read the IMEI number from the old ffs:/pcm/IMEI file, + * if it failes, return default CALYPSO IMEISV value + */ +#else /* CL_IMEI_CALYPSO_PLUS_PLATFORM */ + { + UBYTE version; + USHORT ret; + UBYTE buf[SIZE_EF_IMEI]; + + ret = pcm_ReadFile ((UBYTE *)EF_IMEI_ID, SIZE_EF_IMEI, buf, &version); + if(ret == PCM_OK){ + TRACE_EVENT("CL IMEI INFO: return IMEI-SV number from ffs:/pcm/IMEI"); + /* + * swap digits + */ + imeiBufPtr[0] = ((buf[0] & 0xf0) >> 4) | ((buf[0] & 0x0f) << 4); + imeiBufPtr[1] = ((buf[1] & 0xf0) >> 4) | ((buf[1] & 0x0f) << 4); + imeiBufPtr[2] = ((buf[2] & 0xf0) >> 4) | ((buf[2] & 0x0f) << 4); + imeiBufPtr[3] = ((buf[3] & 0xf0) >> 4) | ((buf[3] & 0x0f) << 4); + imeiBufPtr[4] = ((buf[4] & 0xf0) >> 4) | ((buf[4] & 0x0f) << 4); + imeiBufPtr[5] = ((buf[5] & 0xf0) >> 4) | ((buf[5] & 0x0f) << 4); + imeiBufPtr[6] = ((buf[6] & 0xf0) >> 4) | ((buf[6] & 0x0f) << 4); + imeiBufPtr[7] = ((buf[7] & 0xf0) >> 4) | ((buf[7] & 0x0f) << 4); + /* store IMEI */ + memcpy(stored_imei, imeiBufPtr, CL_IMEI_SIZE); + imei_flag = 1; + + }else{ + TRACE_EVENT("CL IMEI INFO: return default IMEI-SV number"); + memcpy(imeiBufPtr, C_DEFAULT_IMEISV_DSAMPLE, CL_IMEI_SIZE); + } + } +#endif /* CL_IMEI_CALYPSO_PLUS_PLATFORM */ + + return CL_IMEI_OK; + +#endif /* FF_PROTECTED_IMEI */ +#endif /* _SIMULATION_ */ +} + + +#endif /* CL_IMEI_C */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/comlib/cl_list.c Sun Sep 28 05:09:53 2014 +0000 @@ -0,0 +1,650 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This module defines the functions for the List +| processing functions used in components RR/PL of the mobile station. ++----------------------------------------------------------------------------- +*/ + +#ifndef CL_LIST_C +#define CL_LIST_C + +#define ENTITY_RR +#define ENTITY_PL + +/*==== INCLUDES ===================================================*/ + +#include <string.h> +#include <stdlib.h> +#include <stddef.h> +#include "typedefs.h" +#include "message.h" +#include "vsi.h" +#include "gsm.h" +#include "prim.h" +#include "cl_list.h" + +/*==== CONST ======================================================*/ +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT +#define INRANGE(min, x, max) ((unsigned)(x-min) <= (max-min)) +#endif + +/*==== VARIABLES ==================================================*/ +LOCAL const BYTE ByteBitMask[]= {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x1}; + +/*==== EXPORT =====================================================*/ + +/*==== PRIVATE FUNCTIONS ==========================================*/ +LOCAL UBYTE srv_is_not_in_list (USHORT * channels, + USHORT new_channel, + USHORT size); + + +/*==== PUBLIC FUNCTIONS ===========================================*/ +/* + * List processing Functions + * + * RR uses a lot of channel lists. They are organized internally as bitmaps. + * In the following a set of functions is defined for access to this lists: + * + * srv_set_channel + * srv_unset_channel + * srv_get_channel + * srv_create_list + * srv_clear_list + * srv_copy_list + * srv_compare_list + * srv_merge_list + * srv_is_empty_list + * srv_create_chan_mob_alloc + * + * The size of the internal channel lists depends on the supported frequency + * band: + * + * STD=1 (STD_900) GSM 900 + * STD=2 (STD_EGSM) E-GSM + * STD=3 (STD_1900) PCS 1900 + * STD=4 (STD_1800) DCS 1800 + * STD=5 (STD_DUAL) GSM 900 / DCS 1800 DUALBAND + * STD=6 (STD_DUAL_EGSM) GSM 900 / E-GSM / DCS 1800 DUALBAND + * STD=7 (STD_850) GSM 850 + * STD=8 (STD_DUAL_US) GSM 850 / PCS 1900 DUALBAND + * + * We use a compressed bit array to store the list of channels. + * Dependent on the configured or found frequency bands the bit array + * needs several numbers of bytes. For the representation of the individual + * bits in the array we need the function scr_channel_bit(), setBit(), + * resetBit() and getBit(). + * + */ + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : setBit | ++--------------------------------------------------------------------+ + + PURPOSE : sets bit. + +*/ + +LOCAL void setBit (UBYTE* bitstream, unsigned bitindex) +{ + bitstream[bitindex >> 3] |= ByteBitMask[bitindex & 7]; +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : resetBit | ++--------------------------------------------------------------------+ + + PURPOSE : Resets bit. + +*/ + +LOCAL void resetBit (UBYTE* bitstream, unsigned bitindex) +{ + bitstream[bitindex >> 3] &= ~ByteBitMask[bitindex & 7]; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : getBit | ++--------------------------------------------------------------------+ + + PURPOSE : Gets bit. + +*/ + + +LOCAL BYTE getBit (UBYTE* bitstream, unsigned bitindex) +{ + unsigned ByteIdx = bitindex >> 3; + + if (bitstream[ByteIdx]) + return (bitstream[ByteIdx] & ByteBitMask[bitindex & 7]) ? 1 : 0; + else + return 0; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : scr_channel_bit | ++--------------------------------------------------------------------+ + + PURPOSE : calculate bit position in the bitstream for a given + channel and execute function dependent on mode. + +*/ + +GLOBAL UBYTE scr_channel_bit(T_LIST * list, int channel, int mode) +{ + int bitposition = -1; + UBYTE ret = 0; + + /* + * a more efficient way of range checking for ARM + * (according to application note 34, ARM DAI 0034A, January 1998) + * + * For the following code: + * if (channel >= low_channel AND channel <= high_channel) + * bitposition = ...; + * + * exist the faster way to implemented this: + * if ((unsigned)(channel - low_channel) <= (high_channel - low_channel) + * bitposition = ...; + * + * Future versions of the compiler will perform this optimization + * automatically. + * + * We use the follwing macro: + * #define INRANGE(min, x, max) ((unsigned)(x-min) <= (max-min)) + */ + if(channel EQ CHANNEL_0) + channel = CHANNEL_0_INTERNAL; + + bitposition = BITOFFSET_LIST - channel; + /*if (channel EQ CHANNEL_0) + bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_B - CHANNEL_0_INTERNAL); + else if (INRANGE(LOW_CHANNEL_900,channel,HIGH_CHANNEL_900)) + bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_A - channel); + else if (INRANGE(LOW_CHANNEL_EGSM,channel,HIGH_CHANNEL_EGSM)) + bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_B - channel); + else if (INRANGE(LOW_CHANNEL_1800,channel,HIGH_CHANNEL_1800)) + bitposition = (USHORT)(BITOFFSET_DUAL_EGSM_C - channel); + if (INRANGE(LOW_CHANNEL_850,channel,HIGH_CHANNEL_850)) + bitposition = (USHORT)(BITOFFSET_DUAL_US_A - channel); + else if (INRANGE(LOW_CHANNEL_1900,channel,HIGH_CHANNEL_1900)) + bitposition = (USHORT)(BITOFFSET_DUAL_US_B - channel); +*/ + if (bitposition >=0) + { + switch (mode) + { + case SET_CHANNEL_BIT: + setBit (list->channels, bitposition); + break; + case RESET_CHANNEL_BIT: + resetBit (list->channels, bitposition); + break; + case GET_CHANNEL_BIT: + ret = getBit (list->channels, bitposition); + break; + case CHECK_CHANNEL: + ret = 1; + break; + } + } + return ret; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_create_list | ++--------------------------------------------------------------------+ + + PURPOSE : Creates a frequency list in USHORT format from the + bit list. USHORT format means an array of USHORTs + followed by NOT_PRESENT_16BIT (0xFFFF), except for the + case when all elements of the array are used, i.e. the + array's space is fully occupied. + In this function the channels are just converted between + the formats, any semantic errors are not checked here, ie. + if the MS is 1800-only and the list contains a 900 channel + this will be converted even if this leads to an error. + This has to be handled by the caller. + + Parameters: + list - [in] is the input list. + channel_array - [out] converted list. + size - [in] defines the maximum number of channels + in the list. + zero_at_start - [in] specifies where the CHANNEL_0 should be + put: + TRUE - at the start of the list + FALSE - at the end of the list + start_index - [in] specifies a index into the channel_array. + new channels are added at the positions + following and including the index: + channel_array[start_index] to + channel_array[size-1] + + If the start_index is not equal zero it is + also checked if the new channel is already + in the channel_array list (from + channel_array[0] to + channel_array[start_index-1]) + + If the start_index is equal zero the + above check is not performed. + + Return Value: + number of elements added + start_index + +*/ + +GLOBAL int srv_create_list (T_LIST * list, USHORT * channel_array, USHORT size, + UBYTE zero_at_start, USHORT start_index) +{ + int BitOffset, Idx; + unsigned int ByteValue, BitMask, LeftMask; + int i = start_index; + UBYTE *pch; + USHORT *parray = &channel_array[start_index]; + + pch = &list->channels[T_LIST_MAX_SIZE-1]; + for(Idx = T_LIST_MAX_SIZE-1; Idx >= 0 AND i < size; Idx--, pch--) + { + /* + * check and add all channels + */ + if ((ByteValue = *pch) NEQ 0) + { + /* byte contains set bits */ + + /* check single bits */ + for (BitOffset=7, BitMask=0x01, LeftMask=0xfe; + BitOffset>=0; + BitOffset--, BitMask<<=1, LeftMask<<=1) + { + if (ByteValue & BitMask) + { + *parray = BITOFFSET_LIST - (BitOffset+(Idx<<3)); + if(!start_index OR + srv_is_not_in_list (channel_array, *parray, start_index)) + { + /* if the check is ok, ie: + * always add channel, or the channel has not yet existed + * in the list, then advance the pointer and add the + * next channel on next position + * if the check fails the pointer is not advanced and + * the channel will not be added and the next channel + * will overwrite the current channel. + */ + parray++; + + /* check if list is full */ + if (++i >= size) + break; + } + /* check if any bits are left */ + if ((ByteValue & LeftMask) EQ 0) + break; + } + } /* for all bits in byte */ + } /* if Byte NEQ 0 */ + } /* for all Bytes in List */ + + + /* + * If CHANNEL_0 is included in the list + * it has to be changed from CHANNEL_0_INTERNAL to CHANNEL_0 + * and then the zero_at_start flag is handled. + * + * If CHANNEL_0 is in the list it is always + * at the end of the list. + */ + if(i NEQ start_index AND + *(parray-1) EQ CHANNEL_0_INTERNAL) + { + *(parray-1) = CHANNEL_0; + + if(zero_at_start AND (i > 1)) + { + memmove(&channel_array[1], &channel_array[0], (int)sizeof(channel_array[0])*(i-1)); + channel_array[0] = CHANNEL_0; + } + } + + /* + * add the end identifier to the output list + */ + if (i<size) + { + *parray = NOT_PRESENT_16BIT; + } + + return i; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_is_not_in_list | ++--------------------------------------------------------------------+ + + PURPOSE : Checks if the given channel number is a member of the given + list. + + Parameters: + channels - contains the existing output list. + new_channel - is the channel number which shall be checked. + size - indicates the length of the list. + +*/ + +static UBYTE srv_is_not_in_list (USHORT * channels, + USHORT new_channel, + USHORT size) +{ + USHORT i; + + /* + * for all members of the list + */ + for (i=0;i<size;i++) + { + /* + * The end of the list is reached + * that means the new channel is not inside. + */ + if (channels[i] EQ NOT_PRESENT_16BIT) + return TRUE; + + /* + * the channel is inside + */ + if (channels[i] EQ new_channel) + return FALSE; + } + + return TRUE; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_clear_list | ++--------------------------------------------------------------------+ + + PURPOSE : Clears a list by clearing all bits. + +*/ + +GLOBAL void srv_clear_list (T_LIST * list) +{ + /* + * simple algorithm: clear the whole list. + */ + memset (list, 0, sizeof (T_LIST)); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_copy_list | ++--------------------------------------------------------------------+ + + PURPOSE : Copies a list. + +*/ + +GLOBAL void srv_copy_list (T_LIST * target_list, T_LIST * source_list, + UBYTE size) +{ + memcpy (target_list, source_list, size); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_compare_list | ++--------------------------------------------------------------------+ + + PURPOSE : Compares two lists. + +*/ + +GLOBAL UBYTE srv_compare_list (T_LIST * list1, T_LIST * list2) +{ + return (memcmp (list1, list2, sizeof (T_LIST)) EQ 0); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_merge_list | ++--------------------------------------------------------------------+ + + PURPOSE : Merges two lists. Both lists are bitmaps. So the merge + is done by a bitwise OR. + +*/ + +GLOBAL void srv_merge_list (T_LIST * target_list, T_LIST * list) +{ + USHORT i; + + /* + * The maximum list size is T_LIST_MAX_SIZE Bytes for the dualband extended + * frequency standard. + */ + + for (i=0;i<T_LIST_MAX_SIZE;i++) + target_list->channels[i] |= list->channels[i]; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_unmask_list | ++--------------------------------------------------------------------+ + + PURPOSE : This routine resets those bits in destination list that are set in + the source list. + Refer Cell Selection Improvements-LLD section:4.1.1.3.11 +*/ + +GLOBAL void srv_unmask_list(T_LIST *target,T_LIST *source) +{ + UBYTE count=0; + for (count=0;count<T_LIST_MAX_SIZE; count++) + { + target->channels[count] &= ~source->channels[count]; + } +} + + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_trace_freq_in_list | ++--------------------------------------------------------------------+ + + PURPOSE : This routine traces the frequencies in the list + CSI-LLD section:4.1.1.3.11 +*/ + +GLOBAL void srv_trace_freq_in_list(T_LIST *list) +{ + U16 i; + + for(i=CHANNEL_0;i<CHANNEL_0_INTERNAL;i++) + { + if(srv_get_channel (list, i)) + { + TRACE_EVENT_P1("arfcn=%u",i); + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_count_list | ++--------------------------------------------------------------------+ + + PURPOSE : This routine returns the count of the number of channels + set in the List + CSI-LLD section:4.1.1.3.11 +*/ + +GLOBAL U16 srv_count_list(T_LIST *list) +{ + U16 i; + U16 sum = 0; + + for(i=CHANNEL_0;i<CHANNEL_0_INTERNAL;i++) + { + if(srv_get_channel (list, i)) + { + sum++; + } + } + + return sum; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_is_list_set | ++--------------------------------------------------------------------+ + + PURPOSE : This routine checks if any channel in the list is set + CSI-LLD section:4.1.1.3.11 +*/ + +GLOBAL BOOL srv_is_list_set(T_LIST *list) +{ + U8 i; + + for(i=0;i<T_LIST_MAX_SIZE;i++) + { + if(list->channels[i]) + { + return TRUE; + } + } + + return FALSE; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_get_region_from_std | ++--------------------------------------------------------------------+ + + PURPOSE : This routine derived "region" from "std" + CSI-LLD section:4.1.1.3.11 +*/ +GLOBAL U8 srv_get_region_from_std(U8 std) +{ +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + U8 region = BOTH_REGIONS; +#else + U8 region = EUROPEAN_REGION; +#endif + + switch(std) + { + case STD_850: + case STD_1900: + case STD_DUAL_US: + region = AMERICAN_REGION; + break; +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + case STD_900: + case STD_1800: + case STD_DUAL: + case STD_DUAL_EGSM: + region = EUROPEAN_REGION; + break; + default: + TRACE_EVENT_P1 ("srv_get_region_from_std: wrong std %x", std); + TRACE_ERROR ("srv_get_region_from_std: wrong std"); + break; +#endif + } + + return region; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_get_region_from_std_arfcn| ++--------------------------------------------------------------------+ + + PURPOSE : This routine derived "region" from "std" and "ARFCN" +*/ +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT +GLOBAL U8 srv_get_region_from_std_arfcn(U8 std, U16 arfcn) +{ + U8 region = EUROPEAN_REGION; + + switch(std) + { + case STD_850_1800: + case STD_850_900_1800: + if (INRANGE(LOW_CHANNEL_850,arfcn,HIGH_CHANNEL_850)) + region = AMERICAN_REGION; + else + region = EUROPEAN_REGION; + break; + + case STD_900_1900: + if (INRANGE(LOW_CHANNEL_1900,arfcn,HIGH_CHANNEL_1900)) + region = AMERICAN_REGION; + else + region = EUROPEAN_REGION; + break; + + case STD_850_900_1900: + if (INRANGE(LOW_CHANNEL_1900,arfcn,HIGH_CHANNEL_1900) OR + INRANGE(LOW_CHANNEL_850,arfcn,HIGH_CHANNEL_850)) + region = AMERICAN_REGION; + else + region = EUROPEAN_REGION; + break; + default: + TRACE_EVENT_P1 ("srv_get_region_from_std_arfcn: wrong std %x", std); + TRACE_ERROR ("srv_get_region_from_std_arfcn: wrong std"); + break; + } + + return region; +} +#endif + +#endif /* !CL_LIST_C */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/comlib/cl_md5.c Sun Sep 28 05:09:53 2014 +0000 @@ -0,0 +1,576 @@ +/* ++----------------------------------------------------------------------------- +| Project : COMLIB +| Modul : cl_md5.c ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : Definitions of common library functions: MD5 algorithm ++----------------------------------------------------------------------------- +*/ +/* + * Version 1.0 + */ + +/**********************************************************************************/ + +/* +NOTE: +*/ + +/**********************************************************************************/ + +#ifndef CL_MD5_C +#define CL_MD5_C + +#include "typedefs.h" +#include <string.h> +#include "vsi.h" /* to get a lot of macros */ +#include "cl_md5.h" +#include "stdio.h" + + +/*==== FUNCTIONS ==================================================*/ + + +/* + * Constants for MD5 routine. + */ + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +/* + * F, G, H and I are basic MD5 functions. + */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* + * ROTATE_LEFT rotates x left n bits. + */ +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* + * FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. + * Rotation is separate from addition to prevent recomputation. + */ +#define FF(a, b, c, d, x, s, ac) { \ + (a) += F ((b), (c), (d)) + (x) + (UINT)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define GG(a, b, c, d, x, s, ac) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define HH(a, b, c, d, x, s, ac) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +#define II(a, b, c, d, x, s, ac) { \ + (a) += I ((b), (c), (d)) + (x) + (UINT)(ac); \ + (a) = ROTATE_LEFT ((a), (s)); \ + (a) += (b); \ + } +/* + * 1. Append the length in bits + * 2. Process message + * 3. Store state in digest + */ +#define PROCESS_MSG() {\ + memcpy(&context.buffer[56], bits, 8);\ + cl_md5_transform(context.state, context.buffer);\ + cl_md5_enc (digest, context.state, 16);\ + } + +#ifdef _SIMULATION_ +/* ++------------------------------------------------------------------------------ +| Function : MDPrint ++------------------------------------------------------------------------------ +| Description : Prints a message digest in hexadecimal. +| +| Parameters : UBYTE digest[16] ++------------------------------------------------------------------------------ +*/ +GLOBAL void MDPrint (UBYTE *digest, UINT len) +{ + UINT i; + for (i = 0; i < len; i+=8) + TRACE_EVENT_P8 ("0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, ", + digest[i], digest[i+1], digest[i+2], digest[i+3], + digest[i+4], digest[i+5], digest[i+6], digest[i+7]); +} +#endif + +/* ++------------------------------------------------------------------------------ +| Function : cl_md5_enc ++------------------------------------------------------------------------------ +| Description : Encodes input (UINT) into output (UBYTE). Assumes len +| is a multiple of 4. +| +| Parameters : UBYTE *output +| UINT *input +| UINT len ++------------------------------------------------------------------------------ +*/ +void cl_md5_enc (UBYTE *output, UINT *input, UINT len) +{ + UINT i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (UBYTE)(input[i] & 0xff); + output[j+1] = (UBYTE)((input[i] >> 8) & 0xff); + output[j+2] = (UBYTE)((input[i] >> 16) & 0xff); + output[j+3] = (UBYTE)((input[i] >> 24) & 0xff); + } +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_md5_dec ++------------------------------------------------------------------------------ +| Description : Decodes input (UBYTE) into output (UINT). Assumes len +| is a multiple of 4. +| +| Parameters : UINT *output +| UBYTE *input +| UINT len ++------------------------------------------------------------------------------ +*/ +void cl_md5_dec (UINT *output, UBYTE *input, UINT len) +{ + UINT i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT)input[j]) | (((UINT)input[j+1]) << 8) | + (((UINT)input[j+2]) << 16) | (((UINT)input[j+3]) << 24); +} + + +/* ++------------------------------------------------------------------------------ +| Function : cl_md5_transform ++------------------------------------------------------------------------------ +| Description : MD5 basic transformation. Transforms state based on block. +| For more information see RFC 1321 "MD5 Message-Digest Algorithm". +| This routine is derived from the RSA Data Security, Inc. MD5 +| Message-Digest Algorithm. +| +| Parameters : UINT state[4] +| UBYTE block[64] +| ++------------------------------------------------------------------------------ +*/ +void cl_md5_transform (UINT state[4], UBYTE block[64]) +{ + UINT a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + cl_md5_dec (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information.*/ + memset((UBYTE *)x, 0, sizeof (x)); +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_md5 ++------------------------------------------------------------------------------ +| Description : Digests a string and prints the result. For more information see +| RFC 1321 "MD5 Message-Digest Algorithm". +| +| Parameters : UBYTE *input - input challenge string +| UINT len - length of input string +| UBYTE *digest - output digest message ++------------------------------------------------------------------------------ +*/ +GLOBAL void cl_md5 (UBYTE *input, UINT len, UBYTE *digest) +{ + MD5_CTX context; + UBYTE bits[8]; + UINT ind; + int chk_len; + TRACE_EVENT("cl_md5"); + + if(len==0) + len = strlen ((char *)input); + +#ifdef _SIMULATION_ + TRACE_EVENT("Input Message"); + MDPrint (input, len); +#endif + + /* + * MD5 initialization. Begins an MD5 operation, writing a new context. + */ + context.count[0] = context.count[1] = 0; + /* + * Load magic initialization constants according to RFC 1321 + */ + context.state[0] = 0x67452301; /* word A */ + context.state[1] = 0xefcdab89; /* word B */ + context.state[2] = 0x98badcfe; /* word C */ + context.state[3] = 0x10325476; /* word D */ + /* + * Update number of bits (64-bit representation of message length) + */ + if ((context.count[0] += ((UINT)len << 3)) < ((UINT)len << 3)) + context.count[1]++; + context.count[1] += ((UINT)len >> 29); + /* + * Save number of bits + */ + cl_md5_enc (bits, context.count, 8); + + /* + * Step 1. Append Padding Bits + * The message is extended so that its length is congruent to 56 bytes + * (448 bits), modulo 64 (512). Extending is always performed, even if the + * length is already congruent to 56 bytes, modulo 64. + * + * Extending is performed as follows, a single "1" bit is append to the + * message, and then "0" bits are appended so that the legth in bits of the + * message becomes congruent to 56, modulo 64. In all, at least one byte and + * at most 64 bytes are appended. + * + * Step 2. Append Length. + * A 64-bit representation of the message length before the padding is + * appended to the result of previous step. + * + * Step 3. Process Message in 16-word blocks + */ + if(len < 56) + { + /* + * copy message + */ + memcpy(&context.buffer[0], &input[0], len); + /* + * Append length to 56 bytes + */ + context.buffer[len] = 0x80; /* append a single "1" bit */ + memset(&context.buffer[len+1], 0, 55-len); /* append "0" bits */ + /* + * Append length in bits and process message + */ + PROCESS_MSG(); + } + else if(len >= 56 && len < 64) + { + /* + * copy message + */ + memcpy(&context.buffer[0], &input[0], len); + /* + * Append length to 64 bytes + */ + context.buffer[len] = 0x80; + memset(&context.buffer[len+1], 0, 63-len); + /* + * Process message + */ + cl_md5_transform (context.state, context.buffer); + /* + * Append length to 56 bytes + */ + memset(&context.buffer[0], 0, 56); + /* + * Append the length in bits and process message + */ + PROCESS_MSG(); + } + else if(len >= 64) + { + /* + * Copy first 64 bytes + */ + memcpy(&context.buffer[0], &input[0], 64); + /* + * Process message + */ + cl_md5_transform (context.state, context.buffer); + if(len >= 120) + { + /* + * Process message in 64-byte blocks + */ + for (ind = 64; ind + 63 < len; ind += 64) + cl_md5_transform (context.state, &input[ind]); + } + else + ind = 64; + /* + * Copy the rest + */ + memcpy(&context.buffer[0], &input[ind], len-ind); + /* + * Append length to 56 bytes + */ + /*lint -e661 -e662 -e669 possible access or creation of bount ptr or data overrun*/ + context.buffer[len-ind] = 0x80; + chk_len=55-(len-ind); + if(chk_len >=0) + memset(&context.buffer[len-ind+1], 0, chk_len); + /*lint +e661 +e662 +e669 possible access or creation of bount ptr or data overun*/ + /* + * Append the length in bits and process message + */ + PROCESS_MSG(); + } + +#ifdef _SIMULATION_ + TRACE_EVENT("Digest Message"); + MDPrint (digest, 16); +#endif +} + + +#ifdef _SIMULATION_ +/* ++------------------------------------------------------------------------------ +| Function : MDTestSuite ++------------------------------------------------------------------------------ +| Description : Digests a reference suite of strings and prints the results. +| +| Parameters : void ++------------------------------------------------------------------------------ +*/ +GLOBAL void cl_md5TestSuite () +{ + UBYTE digest[16]; + UBYTE test_digest0[16] = {0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e}; + UBYTE test_digest1[16] = {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, + 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61}; + UBYTE test_digest3[16] = {0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, + 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72}; + UBYTE test_digest14[16] = {0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, + 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0}; + UBYTE test_digest26[16] = {0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, + 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b}; + UBYTE test_digest62[16] = {0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, + 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f}; + UBYTE test_digest80[16] = {0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, + 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a}; + UBYTE test_digest160[16] = {0x26, 0x8c, 0x79, 0x19, 0x18, 0x9d, 0x85, 0xe2, + 0x76, 0xd7, 0x4b, 0x8c, 0x60, 0xb2, 0xf8, 0x4f}; + + TRACE_EVENT("MD5 test suite:"); + + /* + * Test 1. Lenght := 0 + */ + cl_md5("", 0, digest); + if(memcmp(digest, test_digest0, 16)) + { + TRACE_EVENT("CHAP MD5: Test 1 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 1 passed."); + } + + /* + * Test 2. Lenght := 1 + */ + cl_md5("a", 0, digest); + if(memcmp(digest, test_digest1, 16)) + { + TRACE_EVENT("CHAP MD5: Test 2 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 2 passed."); + } + + /* + * Test 3. Lenght := 3 + */ + cl_md5("abc", 0, digest); + if(memcmp(digest, test_digest3, 16)) + { + TRACE_EVENT("CHAP MD5: Test 3 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 3 passed."); + } + + /* + * Test 4. Lenght := 14 + */ + cl_md5("message digest", 0, digest); + if(memcmp(digest, test_digest14, 16)) + { + TRACE_EVENT("CHAP MD5: Test 4 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 4 passed."); + } + + /* + * Test 5. Lenght := 26 + */ + cl_md5("abcdefghijklmnopqrstuvwxyz", 0, digest); + if(memcmp(digest, test_digest26, 16)) + { + TRACE_EVENT("CHAP MD5: Test5 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 5 passed."); + } + + /* + * Test 6. Lenght := 62 + */ + cl_md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 0, digest);/*62*/ + if(memcmp(digest, test_digest62, 16)) + { + TRACE_EVENT("CHAP MD5: Test 6 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 6 passed."); + } + + /* + * Test 7. Lenght := 80 + */ + cl_md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, digest);/*80*/ + if(memcmp(digest, test_digest80, 16)) + { + TRACE_EVENT("CHAP MD5: Test 7 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 7 passed."); + } + + /* + * Test 8. Lenght := 160 + */ + cl_md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890\ +12345678901234567890123456789012345678901234567890123456789012345678901234567890", 0, digest); + if(memcmp(digest, test_digest160, 16)) + { + TRACE_EVENT("CHAP MD5: Test 8 failed!!"); + } + else + { + TRACE_EVENT("CHAP MD5: Test 8 passed."); + } + +} +#endif/*_SIMULATION_*/ + + +#endif /* CL_MD5_C */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/comlib/cl_ribu.c Sun Sep 28 05:09:53 2014 +0000 @@ -0,0 +1,283 @@ +/* ++----------------------------------------------------------------------------- +| Project : COMLIB +| Modul : cl_ribu.c ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : Definitions of common library functions: ring buffer ++----------------------------------------------------------------------------- +*/ +/* + * Version 1.0 + */ + +/**********************************************************************************/ + +/* +NOTE: +*/ + +/**********************************************************************************/ + +#ifndef CL_RIBU_C +#define CL_RIBU_C + +#include <string.h> + +#include "typedefs.h" +#include "vsi.h" +#include "cl_ribu.h" + +#undef ENA_ASSERT + +/*==== FUNCTIONS ==================================================*/ + +GLOBAL void cl_ribu_init(T_RIBU *ribu, const U8 depth) +{ + TRACE_FUNCTION("cl_ribu_init()"); + +#ifdef ENA_ASSERT + assert(ribu NEQ NULL); +#else + if (ribu EQ NULL) + { + TRACE_ERROR("ribu EQ NULL"); + return; + } +#endif + + ribu->ri = 0; + ribu->wi = 0; + ribu->depth = depth; + ribu->filled = 0; +} + +GLOBAL U8 cl_ribu_read_index(T_RIBU *ribu) +{ + U8 ri; + + TRACE_FUNCTION("cl_ribu_read_index()"); + +#ifdef ENA_ASSERT + assert(ribu NEQ NULL); +#else + if (ribu EQ NULL) + { + TRACE_ERROR("ribu EQ NULL"); + return 0; //255; + } +#endif + + ri = ribu->ri; + ribu->ri++; + if (ribu->ri EQ ribu->depth) + { + ribu->ri = 0; + } + ribu->filled--; + return ri; +} + +GLOBAL U8 cl_ribu_write_index(T_RIBU *ribu) +{ + U8 wi; + + TRACE_FUNCTION("cl_ribu_write_index()"); + +#ifdef ENA_ASSERT + assert(ribu NEQ NULL); +#else + if (ribu EQ NULL) + { + TRACE_ERROR("ribu EQ NULL"); + return 0; //255; + } +#endif + + wi = ribu->wi; + ribu->wi++; + if (ribu->wi EQ ribu->depth) + { + ribu->wi = 0; + } + +#ifdef ENA_ASSERT + assert(ribu->ri NEQ ribu->wi); +#else + if (ribu->ri EQ ribu->wi) + { + TRACE_ERROR("cl_ribu_write_index(): buffer full!"); + return 0; //255; + } +#endif + + ribu->filled++; + return wi; +} + +GLOBAL void cl_ribu_create(T_RIBU_FD **ribu, const U8 buflen, const U8 depth) +{ + int i; + + TRACE_FUNCTION("cl_ribu_create()"); + + if (*ribu NEQ NULL) + { + TRACE_EVENT("cl_ribu_create(): *ribu already created ?"); + } + + MALLOC(*ribu, sizeof(T_RIBU_FD)); + + cl_ribu_init(&(*ribu)->idx, depth); + + MALLOC((*ribu)->pFDv, depth * sizeof(T_FD*)); + + for (i = 0; i < depth; i++) + { + T_FD **pFD = &(*ribu)->pFDv[i]; + MALLOC(*pFD, sizeof(T_FD)); + MALLOC((*pFD)->buf, buflen * sizeof(U8)); + } +} + +GLOBAL void cl_ribu_release(T_RIBU_FD **ribu) +{ + int i; + + TRACE_FUNCTION("cl_ribu_release()"); + + if (*ribu EQ NULL) + { + TRACE_EVENT("cl_ribu_release(): *ribu EQ NULL!"); + return; + } + + for (i = 0; i < (*ribu)->idx.depth; i++) + { + T_FD *pFD = (*ribu)->pFDv[i]; + MFREE(pFD->buf); + MFREE(pFD); + } + + MFREE((*ribu)->pFDv); + MFREE(*ribu); + *ribu = NULL; +} + +GLOBAL BOOL cl_ribu_data_avail(const T_RIBU_FD *ribu) +{ + TRACE_FUNCTION("cl_ribu_data_avail()"); + +#ifdef ENA_ASSERT + assert(ribu NEQ NULL); +#else + if (ribu EQ NULL) + { + TRACE_ERROR("ribu EQ NULL"); + return 0; //255; + } +#endif + + return ribu->idx.ri NEQ ribu->idx.wi; +} + +GLOBAL T_FD *cl_ribu_get_new_frame_desc(T_RIBU_FD *ribu) +{ + U8 wi; + T_FD *pFDc; + + TRACE_FUNCTION("cl_ribu_get_new_frame_desc()"); + +#ifdef ENA_ASSERT + assert(ribu NEQ NULL); +#else + if (ribu EQ NULL) + { + TRACE_ERROR("ribu EQ NULL"); + return NULL; + } +#endif + + wi = cl_ribu_write_index(&ribu->idx); + if (wi >= ribu->idx.depth) + { + TRACE_EVENT_P1("invalid write index: %d", (int)wi); + return NULL; + } + pFDc = ribu->pFDv[wi]; + + return pFDc; +} + +GLOBAL void cl_ribu_put(const T_FD fd, T_RIBU_FD *ribu) +{ + T_FD *pFDc = cl_ribu_get_new_frame_desc(ribu); + + TRACE_FUNCTION("cl_ribu_put()"); + + if (pFDc EQ NULL) + { + TRACE_ERROR("cl_ribu_put(): no write buffer!"); + return; + } + + (*pFDc).type = fd.type; + (*pFDc).status = fd.status; + (*pFDc).len = fd.len; + memcpy((*pFDc).buf, fd.buf, fd.len); +} + +GLOBAL T_FD *cl_ribu_get(T_RIBU_FD *ribu) +{ + int ri; + T_FD *pFDc; + + TRACE_FUNCTION("cl_ribu_get()"); + +#ifdef ENA_ASSERT + assert(ribu NEQ NULL); +#else + if (ribu EQ NULL) + { + TRACE_ERROR("ribu EQ NULL"); + return NULL; + } +#endif + + ri = (int)cl_ribu_read_index(&ribu->idx); + pFDc = ribu->pFDv[ri]; + + return pFDc; +} + +GLOBAL void cl_set_frame_desc(T_FRAME_DESC *frame_desc, U8 *A0, U16 L0, U8 *A1, U16 L1) +{ + TRACE_ASSERT(frame_desc NEQ NULL); + + frame_desc->Adr[0] = A0; + frame_desc->Len[0] = L0; + frame_desc->Adr[1] = A1; + frame_desc->Len[1] = L1; +} + +GLOBAL void cl_set_frame_desc_0(T_FRAME_DESC *frame_desc, U8 *A0, U16 L0) +{ + TRACE_ASSERT(frame_desc NEQ NULL); + + frame_desc->Adr[0] = A0; + frame_desc->Len[0] = L0; + frame_desc->Adr[1] = NULL; + frame_desc->Len[1] = 0; +} + +#endif /* CL_RIBU_C */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/comlib/cl_rlcmac.c Sun Sep 28 05:09:53 2014 +0000 @@ -0,0 +1,117 @@ +/* ++----------------------------------------------------------------------------- +| Project : COMLIB +| Modul : RLCMAC ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : Definitions of common library functions: RLC/MAC layer. ++----------------------------------------------------------------------------- +*/ + +#ifndef CL_RLCMAC_C +#define CL_RLCMAC_C +#endif /* #ifndef CL_RLCMAC_C */ + +#define ENTITY_GRLC +#define ENTITY_GRR + +/*==== INCLUDES =============================================================*/ + +#include "typedefs.h" +#include "vsi.h" +#include "macdef.h" +#include "gprs.h" +#include "gsm.h" +#include "ccdapi.h" +#include "prim.h" +#include "message.h" +#include "cl_rlcmac.h" + +/*==== CONST ================================================================*/ + +/*==== LOCAL VARS ===========================================================*/ + +/*==== PRIVATE FUNCTIONS ====================================================*/ + +/*==== PUBLIC FUNCTIONS =====================================================*/ +/* ++------------------------------------------------------------------------------ +| Function : cl_rlcmac_get_msg_name ++------------------------------------------------------------------------------ +| Description : +| +| Parameters : +| ++------------------------------------------------------------------------------ +*/ + +#if !defined (NTRACE) + + +#define RETURN(msg) return( #msg ); + +GLOBAL char* cl_rlcmac_get_msg_name ( UBYTE msg_type, + T_RLC_MAC_ROUTE route ) +{ + if( route EQ RLC_MAC_ROUTE_UL ) + { + switch( msg_type ) + { + case U_RESOURCE_REQ_c: RETURN( U_RESOURCE_REQ ); /*lint !e527*/ + case U_DL_ACK_c: RETURN( U_DL_ACK ); /*lint !e527 !e825*/ + case U_CTRL_ACK_c: RETURN( U_CTRL_ACK ); /*lint !e527 !e825*/ + case U_CELL_CHAN_FAILURE_c: RETURN( U_CELL_CHAN_FAILURE ); /*lint !e527 !e825*/ + case U_UL_DUMMY_c: RETURN( U_UL_DUMMY ); /*lint !e527 !e825*/ + case U_MEAS_REPORT_c: RETURN( U_MEAS_REPORT ); /*lint !e527 !e825*/ + case U_MS_TBF_STATUS_c: RETURN( U_MS_TBF_STATUS ); /*lint !e527 !e825*/ + case U_PKT_PSI_STATUS_MSG_c: RETURN( U_PKT_PSI_STATUS_MSG ); /*lint !e527 !e825*/ + case U_MSG_TYPE_CHANNEL_REQ_c: return( "U_MSG_TYPE_CHANNEL_REQ" ); /*lint !e527 !e825*/ + case U_MSG_TYPE_UNKNOWN_c: /*lint !e527 !e825*/ + default: return( "U_MSG_TYPE_UNKNOWN" ); /*lint !e527 !e825*/ + } + } + else + { + switch( msg_type ) + { + case D_ACCESS_REJ_c: RETURN( D_ACCESS_REJ ); /*lint !e527*/ + case D_QUEUING_NOT_c: RETURN( D_QUEUING_NOT ); /*lint !e527 !e825*/ + case D_UL_ASSIGN_c: RETURN( D_UL_ASSIGN ); /*lint !e527 !e825*/ + case D_DL_ASSIGN_c: RETURN( D_DL_ASSIGN ); /*lint !e527 !e825*/ + case D_TBF_RELEASE_c: RETURN( D_TBF_RELEASE ); /*lint !e527 !e825*/ + case D_PAGING_REQ_c: RETURN( D_PAGING_REQ ); /*lint !e527 !e825*/ + case D_UL_ACK_c: RETURN( D_UL_ACK ); /*lint !e527 !e825*/ + case PSI_1_c: RETURN( PSI_1 ); /*lint !e527 !e825*/ + case PSI_2_c: RETURN( PSI_2 ); /*lint !e527 !e825*/ + case PSI_3_c: RETURN( PSI_3 ); /*lint !e527 !e825*/ + case PSI_3_BIS_c: RETURN( PSI_3_BIS ); /*lint !e527 !e825*/ + case PSI_4_c: RETURN( PSI_4 ); /*lint !e527 !e825*/ + case PSI_5_c: RETURN( PSI_5 ); /*lint !e527 !e825*/ + case PSI_13_c: RETURN( PSI_13 ); /*lint !e527 !e825*/ + case D_CELL_CHAN_ORDER_c: RETURN( D_CELL_CHAN_ORDER ); /*lint !e527 !e825*/ + case D_DL_DUMMY_c: RETURN( D_DL_DUMMY ); /*lint !e527 !e825*/ + case D_MEAS_ORDER_c: RETURN( D_MEAS_ORDER ); /*lint !e527 !e825*/ + case D_PDCH_RELEASE_c: RETURN( D_PDCH_RELEASE ); /*lint !e527 !e825*/ + case D_POLLING_REQ_c: RETURN( D_POLLING_REQ ); /*lint !e527 !e825*/ + case D_CTRL_PWR_TA_c: RETURN( D_CTRL_PWR_TA ); /*lint !e527 !e825*/ + case D_PRACH_PAR_c: RETURN( D_PRACH_PAR ); /*lint !e527 !e825*/ + case D_TS_RECONFIG_c: RETURN( D_TS_RECONFIG ); /*lint !e527 !e825*/ + case D_MSG_TYPE_CRC_ERROR_c: return( "D_MSG_TYPE_CRC_ERROR" ); /*lint !e527 !e825*/ + case D_MSG_TYPE_2ND_SEGMENT_c: return( "D_MSG_TYPE_2ND_SEGMENT" ); /*lint !e527 !e825*/ + case D_MSG_TYPE_UNKNOWN_c: /*lint !e527 !e825*/ + default: return( "D_MSG_TYPE_UNKNOWN" ); /*lint !e527 !e825*/ + } + } +} /* cl_rlcmac_get_msg_name */ + +#endif /* #if !defined (NTRACE) */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/comlib/cl_shrd.c Sun Sep 28 05:09:53 2014 +0000 @@ -0,0 +1,438 @@ +/* ++----------------------------------------------------------------------------- +| Project : COMLIB +| Modul : cl_shrd.c ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : Definitions of common library functions: Implementation of + creation of Semaphores and usage of it by any entity in + PS ++----------------------------------------------------------------------------- +*/ +/* + * Version 1.0 + */ + +/**********************************************************************************/ + +/* +NOTE: +*/ + +/**********************************************************************************/ +#ifndef CL_SHRD_C +#define CL_SHRD_C +/*==== INCLUDES ===================================================*/ + +#include <string.h> +#include <stdio.h> +#include "typedefs.h" +#include "vsi.h" +#include "cl_shrd.h" + +/*==== VARIABLES ==================================================*/ + +static T_HANDLE cl_handle; + +#ifdef OPTION_MULTITHREAD +#define VSI_CALLER cl_handle, +#else +#define VSI_CALLER +#endif + +/* Pointer is used for faster memory access */ +static T_SHRD_DATA shrd_data_base; +T_SHRD_DATA *shared_data = &shrd_data_base; + +static T_HANDLE sem_SHARED = VSI_ERROR; +static BOOL is_initialized = FALSE; + +/*==== FUNCTIONS ==================================================*/ + +/* ++--------------------------------------------------------------------------------- +| Function : cl_shrd_init ++--------------------------------------------------------------------------------- +| Description : Opens counting semaphore specified by its name. +| If semaphore doesnot exists, creates semaphore with count given. +| +| Parameters : T_HANDLE +| +| Return : void +| ++--------------------------------------------------------------------------------- +*/ +GLOBAL void cl_shrd_init (T_HANDLE handle) +{ + TRACE_FUNCTION ("cl_shrd_init()"); + + if(is_initialized NEQ TRUE) + { + cl_handle = handle; + + memset(shared_data, 0, sizeof(T_SHRD_DATA)); + sem_SHARED = vsi_s_open (VSI_CALLER "SHARED_SEM",1); + + if (sem_SHARED NEQ VSI_ERROR) + { + TRACE_EVENT ("Semaphore opened successfully \"SHARED_SEM\""); + is_initialized = TRUE; +#ifdef TI_PS_FF_AT_P_CMD_CTREG + /* + * Initialize the Two tables with the default values + */ + memcpy(shared_data->no_serv_mod_time,&no_service_mode_time, + sizeof(no_service_mode_time)); + + memcpy(shared_data->lim_serv_mod_time,&lim_service_mode_time, + sizeof(lim_service_mode_time)); +#endif /* TI_PS_FF_AT_P_CMD_CTREG */ + } + else + TRACE_EVENT ("Cant open semaphore \"SHARED_SEM\""); + } +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_exit ++------------------------------------------------------------------------------ +| Description : Close the semaphore. +| +| Parameters : void +| +| Return : void +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL void cl_shrd_exit (void) +{ + TRACE_FUNCTION ("cl_shrd_exit()"); + if(is_initialized EQ TRUE) + { + if (sem_SHARED NEQ VSI_ERROR) + vsi_s_close (VSI_CALLER sem_SHARED); + + memset(shared_data, 0, sizeof(T_SHRD_DATA)); + is_initialized = FALSE; + } +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_get_loc ++------------------------------------------------------------------------------ +| Description : Copies the content from global T_LOC_INFO to the +| passed parameter +| +| Parameters : <loc_info>: Location information +| +| Return : void +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL BOOL cl_shrd_get_loc (T_LOC_INFO *loc_info) +{ + BOOL ret = FALSE; + TRACE_FUNCTION ("cl_shrd_get_loc()"); + + if (sem_SHARED NEQ VSI_ERROR) + { + if (vsi_s_get (VSI_CALLER sem_SHARED) EQ VSI_OK) + { + if ( loc_info NEQ NULL ) + memcpy(loc_info, &shared_data->location_info, sizeof(T_LOC_INFO)); + vsi_s_release (VSI_CALLER sem_SHARED); + ret = TRUE; + } + else + { + TRACE_EVENT ("Semaphore not free or Invalid handle \"sem_SHARED\""); + return(ret); + } + } + return(ret); +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_set_loc ++------------------------------------------------------------------------------ +| Description : Copies the content from passed parameter to the +| global structure +| +| Parameters : <loc_info>: Location information +| +| Return : void +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL void cl_shrd_set_loc (T_LOC_INFO *loc_info) +{ + TRACE_FUNCTION ("cl_shrd_set_loc()"); + + if (sem_SHARED NEQ VSI_ERROR) + { + if (vsi_s_get (VSI_CALLER sem_SHARED) EQ VSI_OK) + { + if ( loc_info NEQ NULL ) + memcpy(&shared_data->location_info, loc_info, sizeof(T_LOC_INFO)); + vsi_s_release (VSI_CALLER sem_SHARED); + } + else + { + TRACE_EVENT ("Semaphore not free or Invalid handle \"sem_SHARED\""); + } + } +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_get_tim_adv ++------------------------------------------------------------------------------ +| Description : Copies the content from global T_TIM_ADV to the +| passed parameter +| +| Parameters : <tim_adv>: Timing Advance and ME status. +| +| Return : void +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL BOOL cl_shrd_get_tim_adv (T_TIM_ADV *tim_adv) +{ + BOOL ret = FALSE; + TRACE_FUNCTION ("cl_shrd_get_tim_adv()"); + + if (sem_SHARED NEQ VSI_ERROR) + { + if (vsi_s_get (VSI_CALLER sem_SHARED) EQ VSI_OK) + { + if ( tim_adv NEQ NULL ) + memcpy(tim_adv, &shared_data->timing_advance, sizeof(T_TIM_ADV)); + vsi_s_release (VSI_CALLER sem_SHARED); + ret = TRUE; + } + else + { + TRACE_EVENT ("Semaphore not free or Invalid handle \"sem_SHARED\""); + return(ret); + } + } + return(ret); +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_set_tim_adv ++------------------------------------------------------------------------------ +| Description : Copies the content from passed parameter to the +| global structure +| +| Parameters : <tim_adv>: Timing Advance and ME status. +| +| Return : void +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL void cl_shrd_set_tim_adv (T_TIM_ADV *tim_adv) +{ + TRACE_FUNCTION ("cl_shrd_set_tim_adv()"); + + if (sem_SHARED NEQ VSI_ERROR) + { + if (vsi_s_get (VSI_CALLER sem_SHARED) EQ VSI_OK) + { + if ( tim_adv NEQ NULL ) + memcpy(&shared_data->timing_advance, tim_adv, sizeof(T_TIM_ADV)); + vsi_s_release (VSI_CALLER sem_SHARED); + } + else + { + TRACE_EVENT ("Semaphore not free or Invalid handle \"sem_SHARED\""); + } + } +} +#ifdef TI_PS_FF_AT_P_CMD_CTREG +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_set_treg_val ++------------------------------------------------------------------------------ +| Description : Copies the content from passed parameter to the +| global structure Used for %CTREG setting the values. +| +| Parameters : <mode> : Selects the mode of operation read or write +| <tab_id> : Selects either no_service_mode_time or +| lim_service_mode_time for updating. +| <tab_val>: Table values to be updated in the selcted table. +| +| Return : BOOL +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL BOOL cl_shrd_set_treg_val ( T_TREG *treg ) +{ + UBYTE i; + BOOL ret = FALSE; + + TRACE_FUNCTION ("cl_shrd_set_treg_val()"); + + if (sem_SHARED NEQ VSI_ERROR) + { + if (vsi_s_get (VSI_CALLER sem_SHARED) EQ VSI_OK) + { + if ( treg NEQ NULL ) + { + switch(treg->tab_id) + { + case NOSERVICE_MODE_TIME: + memcpy(shared_data->no_serv_mod_time, treg->tab_val, + MAX_CTREG_TAB_LEN); + break; + case LIMSERVICE_MODE_TIME: + memcpy(shared_data->lim_serv_mod_time, treg->tab_val, + MAX_CTREG_TAB_LEN); + break; + default: + break; + } + ret = TRUE; + } + vsi_s_release (VSI_CALLER sem_SHARED); + } + else + { + TRACE_EVENT ("Semaphore not free or Invalid handle \"sem_SHARED\""); + } + } + return(ret); +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_get_treg_val ++------------------------------------------------------------------------------ +| Description : Reads the content from passed parameter to the +| global structure. +| +| Parameters : <mode> : Selects the mode of operation read or write +| <tab_id> : Selects either no_service_mode_time or +| lim_service_mode_time for updating. +| <tab_val>: Table values to be read from the selected table. +| +| Return : BOOL +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL BOOL cl_shrd_get_treg_val ( T_TREG *treg ) +{ + UBYTE i; + BOOL ret = FALSE; + + TRACE_FUNCTION ("cl_shrd_get_treg_val()"); + + if (sem_SHARED NEQ VSI_ERROR) + { + if (vsi_s_get (VSI_CALLER sem_SHARED) EQ VSI_OK) + { + if ( treg NEQ NULL ) + { + switch(treg->tab_id) + { + case NOSERVICE_MODE_TIME: + memcpy(treg->tab_val, shared_data->no_serv_mod_time, + MAX_CTREG_TAB_LEN); + break; + case LIMSERVICE_MODE_TIME: + memcpy(treg->tab_val, shared_data->lim_serv_mod_time, + MAX_CTREG_TAB_LEN); + break; + default: + break; + } + ret = TRUE; + } + vsi_s_release (VSI_CALLER sem_SHARED); + } + else + { + TRACE_EVENT ("Semaphore not free or Invalid handle \"sem_SHARED\""); + } + } + return(ret); +} + +/* ++------------------------------------------------------------------------------ +| Function : cl_shrd_get_treg ++------------------------------------------------------------------------------ +| Description : Reads the TREG Timer value from the selected Table and +| returns the data to called Entity (RR) +| +| Parameters : <tab_id> : Selects either no_service_mode_time or +| lim_service_mode_time for getting TREG value. +| <offset> : Offset value to point at exact position in the +| selected Table for getting TREG value. +| <tab_val>: Table value in the selcted table. +| +| Return : BOOL +| ++------------------------------------------------------------------------------ +*/ + +GLOBAL BOOL cl_shrd_get_treg (UBYTE tab_id, UBYTE offset, UBYTE *tab_val) +{ + BOOL ret = FALSE; + + TRACE_FUNCTION ("cl_shrd_get_treg()"); + + if (sem_SHARED NEQ VSI_ERROR) + { + if (vsi_s_get (VSI_CALLER sem_SHARED) EQ VSI_OK) + { + /* Check for the proper value of offset, it should be between 0 to 24 */ + if(offset > (MAX_CTREG_TAB_LEN - 1)) + { + return(ret); + } + switch(tab_id) + { + case NOSERVICE_MODE_TIME: + *tab_val = shared_data->no_serv_mod_time[offset]; + break; + case LIMSERVICE_MODE_TIME: + *tab_val = shared_data->lim_serv_mod_time[offset]; + break; + default: + break; + } + ret = TRUE; + vsi_s_release (VSI_CALLER sem_SHARED); + } + else + { + TRACE_EVENT ("Semaphore not free or Invalid handle \"sem_SHARED\""); + } + } + return(ret); +} +#endif /* TI_PS_FF_AT_P_CMD_CTREG */ + +#endif /* CL_SHRD_C */