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 */