diff src/g23m-gprs/sndcp/sndcp_mgf.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-gprs/sndcp/sndcp_mgf.c	Sun Jul 15 04:40:46 2018 +0000
@@ -0,0 +1,6120 @@
+/*
++-----------------------------------------------------------------------------
+|  Project :  GPRS (8441)
+|  Modul   :  sndcp_mgf.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 :  This modul is part of the entity SNDCP and implements all
+|             procedures and functions as described in the
+|             SDL-documentation (MG-statemachine)
++-----------------------------------------------------------------------------
+*/
+
+
+#define ENTITY_SNDCP
+
+/*==== INCLUDES =============================================================*/
+
+#include "typedefs.h"    /* to get Condat data types */
+#include "vsi.h"        /* to get a lot of macros */
+#include "macdef.h"
+#include "gsm.h"        /* to get a lot of macros */
+#include "prim.h"       /* to get the definitions of used SAP and directions */
+
+#include "dti.h"
+
+#include "sndcp.h"        /* to get the global entity definitions */
+#include "sndcp_f.h"       /* to get the functions to access the global arrays*/
+
+#include "sndcp_cias.h"    /* to get the signals to service cia */
+#include "sndcp_nds.h"    /* to get the signals to service nd */
+#include "sndcp_nus.h"    /* to get the signals to service nu */
+#include "sndcp_nuf.h"    
+#include "sndcp_sus.h"    /* to get the signals to service su */
+#include "sndcp_suas.h"    /* to get the signals to service su */
+#include "sndcp_sds.h"    /* to get the signals to service sd */
+#include "sndcp_sdas.h"    /* to get the signals to service sda */
+
+#include "sndcp_mgf.h"      /* to get ths file */
+#include "sndcp_nup.h"      /* nu_sn_[unit]data_req is called from
+                               sig_callback().*/
+
+#include <string.h>
+
+/*==== CONST ================================================================*/
+
+/*==== LOCAL VARS ===========================================================*/
+
+/*==== PRIVATE FUNCTIONS ====================================================*/
+
+LOCAL void mg_get_sapi_dcomp_dntt (UBYTE sapi, UBYTE dcomp, UBYTE* dntt);
+
+LOCAL void mg_get_sapi_dntt_nsapi (UBYTE sapi, UBYTE dntt, UBYTE nsapi, BOOL* used);
+
+LOCAL void mg_get_sapi_dntt_state (UBYTE sapi, UBYTE dntt, UBYTE* state);
+
+LOCAL void mg_get_sapi_dcomp_state (UBYTE sapi, UBYTE dcomp, UBYTE* stat);
+
+LOCAL void mg_get_sapi_pcomp_state (UBYTE sapi, UBYTE pcomp, UBYTE* stat);
+
+LOCAL void mg_get_sapi_pntt_state (UBYTE sapi, UBYTE pntt, UBYTE* state);
+
+LOCAL void mg_set_sapi_dntt_nsapi (UBYTE sapi, UBYTE dntt, UBYTE nsapi, BOOL used);
+
+LOCAL void mg_set_sapi_dcomp_state (UBYTE sapi, UBYTE dcomp, UBYTE stat);
+
+LOCAL void mg_set_sapi_dcomp_dntt (UBYTE sapi, UBYTE dcomp, UBYTE dntt);
+
+LOCAL void mg_set_sapi_dntt_rej (UBYTE sapi, UBYTE dntt, BOOL rej);
+
+LOCAL void mg_set_sapi_dntt_state (UBYTE sapi, UBYTE dntt, UBYTE state);
+
+LOCAL void mg_set_sapi_pntt_nsapi (UBYTE sapi, UBYTE pntt, UBYTE nsapi, BOOL used);
+
+LOCAL void mg_set_sapi_pcomp_state (UBYTE sapi, UBYTE pcomp, UBYTE stat);
+
+LOCAL void mg_set_sapi_pcomp_pntt (UBYTE sapi, UBYTE pcomp, UBYTE pntt);
+
+LOCAL void mg_set_sapi_pntt_rej (UBYTE sapi, UBYTE pntt, BOOL rej);
+
+LOCAL void mg_set_sapi_pntt_state (UBYTE sapi, UBYTE pntt, UBYTE state);
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_dcomp_dntt
++------------------------------------------------------------------------------
+| Description : The procedures indicates the dntt assigned to a given dcomp
+|               for a given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dcomp UBYTE,
+|               IN/OUT dntt UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_get_sapi_dcomp_dntt (UBYTE sapi, UBYTE dcomp, UBYTE* dntt)
+{
+  TRACE_FUNCTION( "mg_get_sapi_dcomp_dntt" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *dntt = sndcp_data->mg.sapi_dcomp_dntt_ra[sapi_index][dcomp];
+  }
+} /* mg_get_sapi_dcomp_dntt() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_dntt_nsapi
++------------------------------------------------------------------------------
+| Description : The procedure informs if a given nsapi uses a given dntt on a
+|               given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dntt UBYTE,
+|               IN nsapi UBYTE,
+|               IN/OUT used BOOL
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_get_sapi_dntt_nsapi (UBYTE sapi, UBYTE dntt, UBYTE nsapi, BOOL* used)
+{
+  TRACE_FUNCTION( "mg_get_sapi_dntt_nsapi" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *used = sndcp_data->mg.sapi_dntt_nsapi_set_ra[sapi_index][dntt][nsapi];
+  }
+} /* mg_get_sapi_dntt_nsapi() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_dcomp_state
++------------------------------------------------------------------------------
+| Description : The procedures informs about the state of a given dcomp on a
+|               given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dcomp UBYTE,
+|               IN/OUT stat UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_get_sapi_dcomp_state (UBYTE sapi, UBYTE dcomp, UBYTE* stat)
+{
+  TRACE_FUNCTION( "mg_get_sapi_dcomp_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *stat = sndcp_data->mg.sapi_dcomp_state_ra[sapi_index][dcomp];
+  }
+} /* mg_get_sapi_dcomp_state() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_dntt_state
++------------------------------------------------------------------------------
+| Description : The procedures informs about the state of a given data
+|               compression entity on a given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dntt UBYTE,
+|               IN/OUT state UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_get_sapi_dntt_state (UBYTE sapi, UBYTE dntt, UBYTE* state)
+{
+  TRACE_FUNCTION( "mg_get_sapi_dntt_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *state = sndcp_data->mg.sapi_dntt_state_ra[sapi_index][dntt];
+  }
+
+
+
+} /* mg_get_sapi_dntt_state() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_pcomp_state
++------------------------------------------------------------------------------
+| Description : The procedures informs about the state of a given pcomp on a
+|               given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pcomp UBYTE,
+|               IN/OUT stat UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_get_sapi_pcomp_state (UBYTE sapi, UBYTE pcomp, UBYTE* stat)
+{
+  TRACE_FUNCTION( "mg_get_sapi_pcomp_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *stat = sndcp_data->mg.sapi_pcomp_state_ra[sapi_index][pcomp];
+  }
+} /* mg_get_sapi_pcomp_state() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_pntt_state
++------------------------------------------------------------------------------
+| Description : The procedures informs about the state of a given header
+|               compression entity on a given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pntt UBYTE,
+|               IN/OUT state UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_get_sapi_pntt_state (UBYTE sapi, UBYTE pntt, UBYTE* state)
+{
+  TRACE_FUNCTION( "mg_get_sapi_pntt_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *state = sndcp_data->mg.sapi_pntt_state_ra[sapi_index][pntt];
+  }
+} /* mg_get_sapi_pntt_state() */
+
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_check_sense_bitwise
++------------------------------------------------------------------------------
+| Description : Checks, if "small" is bitwise smaller than or equal to "big"
+|
+| Parameters  : USHORT small, big, BOOL wrong is set to TRUE, if small > big
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_ushort_sense_bitwise (USHORT small,
+                                    USHORT big,
+                                    BOOL* wrong) {
+  UBYTE bit = 0;
+  TRACE_FUNCTION( "mg_check_sense_bitwise" );
+  *wrong = TRUE;
+  for (bit = 0; bit < 8 * sizeof(USHORT); bit++) {
+    if ((small & (1 << bit)) > (big & (1 << bit))) {
+      return;
+    }
+  }
+  *wrong = FALSE;
+} /* mg_check_sense_bitwise() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_check_sense_bitwise
++------------------------------------------------------------------------------
+| Description : Checks, if "small" is bitwise smaller than "big"
+|
+| Parameters  : UBYTE small, big, BOOL wrong is set to TRUE, if small > big
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_ubyte_sense_bitwise (UBYTE small,
+                                    UBYTE big,
+                                    BOOL* wrong) {
+  UBYTE bit = 0;
+  TRACE_FUNCTION( "mg_check_sense_bitwise" );
+  *wrong = TRUE;
+  for (bit = 0; bit < 8 * sizeof(UBYTE); bit++) {
+    if ((small & (1 << bit)) > (big & (1 << bit))) {
+      return;
+    }
+  }
+  *wrong = FALSE;
+} /* mg_check_sense_bitwise() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_decode_v42
++------------------------------------------------------------------------------
+| Description : decodes the v42 part of given sdu to given xid block
+|
+| Parameters  : source sdu,
+|               index in sdu,
+|               field index in sdu (sub index in compression fields,
+|               destination xid block,
+|               success ok
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_decode_v42 (T_sdu* sdu,
+                           USHORT* index,
+                           USHORT* field_index,
+                           T_XID_BLOCK* xid_block,
+                           BOOL* ok,
+                           UBYTE p_bit) {
+#define CHECK_XID_BUFFER_LEN2 if (*index + *field_index >= ((sdu->l_buf) >> 3)) return
+
+  USHORT field_length = 0;
+  TRACE_FUNCTION( "mg_decode_v42" );
+  *ok = FALSE;
+
+  /*
+   * Set field_index to length of field octet.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN2;
+  field_length = sdu->buf[*index + *field_index];
+  /*
+   * NSAPIS parameter and followers omitted?
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    if (field_length == MG_DATA_P_1_NSAPIS_OM) {
+      *ok = TRUE;
+      return;
+    }
+  } else {
+    if (field_length == MG_DATA_P_0_NSAPIS_OM) {
+      *ok = TRUE;
+      return;
+    }
+  }
+  /*
+   * If p bit set to 1, set field_index to dcomp field.
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    (*field_index)++;
+    CHECK_XID_BUFFER_LEN2;
+    xid_block->v42.dcomp =
+      ((USHORT)sdu->buf[*index + *field_index]) >> 4;
+  }
+  /*
+   * Set field_index to MSB of applicable nsapis short.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN2;
+  xid_block->v42.nsapis =
+    ((USHORT)sdu->buf[*index + *field_index]) << 8;
+  xid_block->v42.nsapis_set = TRUE;
+  /*
+   * Set field_index to LSB of applicable nsapis short.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN2;
+  xid_block->v42.nsapis +=
+    ((USHORT)sdu->buf[*index + *field_index]);
+  /*
+   * P0 parameter and followers omitted?
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    if (field_length == MG_DATA_P_1_P0_OM) {
+      *ok = TRUE;
+      return;
+    }
+  } else {
+    if (field_length == MG_DATA_P_0_P0_OM) {
+      *ok = TRUE;
+      return;
+    }
+  }
+  /*
+   * Set field_index to p0.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN2;
+  xid_block->v42.p0 =
+    sdu->buf[*index + *field_index];
+  xid_block->v42.p0_set = TRUE;
+  /*
+   * P1 parameter and followers omitted?
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    if (field_length == MG_DATA_P_1_P1_OM) {
+      *ok =TRUE;
+      return;
+    }
+  } else {
+    if (field_length == MG_DATA_P_0_P1_OM) {
+      *ok =TRUE;
+      return;
+    }
+  }
+  /*
+   * Set field_index to MSB of p1.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN2;
+  xid_block->v42.p1 =
+    ((USHORT)sdu->buf[*index + *field_index]) << 8;
+  xid_block->v42.p1_set = TRUE;
+  /*
+   * Set field_index to LSB of p1.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN2;
+  xid_block->v42.p1 +=
+    ((USHORT)sdu->buf[*index + *field_index]);
+  /*
+   * P2 parameter and followers omitted?
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    if (field_length == MG_DATA_P_1_P2_OM) {
+      *ok = TRUE;
+      return;
+    }
+  } else {
+    if (field_length == MG_DATA_P_0_P2_OM) {
+      *ok = TRUE;
+      return;
+    }
+  }
+  /*
+   * Set field_index to p2.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN2;
+  xid_block->v42.p2 =
+    sdu->buf[*index + *field_index];
+  xid_block->v42.p2_set = TRUE;
+
+  /*
+   * If length of v42 field is longer than specified, ignore the rest.
+   */
+  while (*field_index < field_length) {
+    CHECK_XID_BUFFER_LEN2;
+    (*field_index)++;
+  }
+
+  *ok = TRUE;
+
+} /* mg_decode_v42() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_decode_vj
++------------------------------------------------------------------------------
+| Description : decodes the vj part of given sdu to given xid block
+|
+| Parameters  : source sdu,
+|               index in sdu,
+|               field index in sdu (sub index in compression fields,
+|               destination xid block,
+|               success ok
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_decode_vj (T_sdu* sdu,
+                           USHORT* index,
+                           USHORT* field_index,
+                           T_XID_BLOCK* xid_block,
+                           BOOL* ok,
+                           UBYTE p_bit) {
+#define CHECK_XID_BUFFER_LEN3 if (*index + *field_index >= ((sdu->l_buf) >> 3)) return
+
+  USHORT field_length = 0;
+  TRACE_FUNCTION( "mg_decode_vj" );
+
+  /*
+   * Set field_index to length of field octet.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN3;
+  field_length = sdu->buf[*index + *field_index];
+  /*
+   * NSAPIS parameter and followers omitted?
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    if (field_length == MG_HEADER_P_1_NSAPIS_OM) {
+      *ok = TRUE;
+      return;
+    }
+  } else {
+    if (field_length == MG_HEADER_P_0_NSAPIS_OM) {
+      *ok = TRUE;
+      return;
+    }
+  }
+  /*
+   * If p bit set to 1, set field_index to dcomp field.
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    (*field_index)++;
+    CHECK_XID_BUFFER_LEN3;
+    xid_block->vj.pcomp1 =
+      ((USHORT)sdu->buf[*index + *field_index]) >> 4;
+    xid_block->vj.pcomp2 =
+      ((USHORT)sdu->buf[*index + *field_index]) & 0xf;
+  }
+
+  /*
+   * Set field_index to MSB of applicable nsapis short.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN3;
+  xid_block->vj.nsapis =
+    ((USHORT)sdu->buf[*index + *field_index]) << 8;
+  xid_block->vj.nsapis_set = TRUE;
+  /*
+   * Set field_index to LSB of applicable nsapis short.
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN3;
+  xid_block->vj.nsapis +=
+    ((USHORT)sdu->buf[*index + *field_index]);
+  /*
+   * S0_M_1 parameter omitted?
+   */
+  if (p_bit == SNDCP_P_BIT_1) {
+    if (field_length == MG_HEADER_P_1_S0_M_1_OM) {
+      *ok = TRUE;
+      return;
+    }
+  } else {
+    if (field_length == MG_HEADER_P_0_S0_M_1_OM) {
+      *ok = TRUE;
+      return;
+    }
+  }
+  /*
+   * Set field_index to "s0 - 1" Parameter
+   */
+  (*field_index)++;
+  CHECK_XID_BUFFER_LEN3;
+  xid_block->vj.s0_m_1 = sdu->buf[*index + *field_index];
+  xid_block->vj.s0_m_1_set = TRUE;
+
+  /*
+   * If length of vj field is longer than specified, ignore the rest.
+   */
+  while (*field_index < field_length) {
+    CHECK_XID_BUFFER_LEN3;
+    (*field_index)++;
+  }
+
+
+  *ok = TRUE;
+
+} /* mg_decode_vj() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_detect_mode_clash
++------------------------------------------------------------------------------
+| Description : Unacknowledged and acknowledged contexts may not share the same
+| compressor entity. This procdure detects possible violations of that rule.
+|
+| Parameters  : the set of nsapis given as USHORT bit mask,
+|               violation detected, TRUE if at least 1 acknowledged and 1
+|               unacknowledged context share the same compressor.
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_detect_mode_clash (USHORT nsapis, BOOL* vio)
+{
+  UBYTE nsapi = 0;
+  BOOL unack_found = FALSE;
+  BOOL ack_found = FALSE;
+  BOOL ack = FALSE;
+  TRACE_FUNCTION( "mg_detect_mode_clash" );
+  /*
+   * Find affected nsapis.
+   */
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    if ((nsapis & (1 << nsapi)) > 0) {
+      sndcp_get_nsapi_ack(nsapi, &ack);
+      if (ack) {
+        ack_found = TRUE;
+      } else {
+        unack_found = TRUE;
+      }
+    }
+  }
+  *vio = unack_found && ack_found;
+
+
+} /* mg_detect_mode_clash() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_respond_if_nec
++------------------------------------------------------------------------------
+| Description : All nsapis connected to the given sapi
+|               that are in state MG_ACT are sent an
+|               SNSM_ACTIVATE_RES.
+|
+| Parameters  : sapi
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_respond_if_nec (UBYTE sapi) {
+  UBYTE nsapi = 0;
+  UBYTE sapi_index = 0;
+#ifdef SNDCP_UPM_INCLUDED
+  BOOL ack = FALSE;
+#endif /* SNDCP_UPM_INCLUDED */
+
+  TRACE_FUNCTION( "mg_respond_if_nec" );
+
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    USHORT nsapi_state = MG_IDLE;
+    USHORT sapi_state = MG_IDLE;
+    UBYTE local_sapi = 0;
+    sndcp_get_nsapi_state(nsapi, &nsapi_state);
+    sndcp_get_nsapi_sapi(nsapi, &local_sapi);
+    sndcp_get_sapi_state(local_sapi, &sapi_state);
+    if (((nsapi_state & MG_ACT) > 0)
+        &&
+        ((sapi_state & MG_XID) == 0)
+        &&
+        ((sapi_state & MG_EST) == 0)
+        &&
+        (local_sapi == sapi)) {
+
+      /*
+       * Open DTI connection.
+       */
+#ifndef SNDCP_UPM_INCLUDED
+      mg_dti_open(nsapi);
+#else 
+      sndcp_get_nsapi_ack(nsapi, &ack);
+      if (ack) {
+        nu_ready_ind_if_nec(nsapi);
+      } else {
+        nu_unitready_ind_if_nec(nsapi);
+      }
+#endif
+
+      mg_send_snsm_activate_res(nsapi);
+      /*
+       * Set nsapi state to MG_IDLE.
+       */
+      sndcp_unset_nsapi_state (nsapi, MG_ACT);
+    }
+
+    if (((nsapi_state & MG_DEACT) > 0)
+        &&
+        ((sapi_state & MG_XID) == 0)
+        &&
+        ((sapi_state & MG_REL) == 0)
+        &&
+        (local_sapi == sapi)) {
+
+#ifdef SNDCP_UPM_INCLUDED 
+      PALLOC(snsm_deactivate_res, SN_DEACTIVATE_CNF);
+#else
+      PALLOC(snsm_deactivate_res, SNSM_DEACTIVATE_RES);
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+      /*
+       * Now the NSAPI is not in use anymore:
+       */
+      sndcp_set_nsapi_used(nsapi, FALSE);
+      sndcp_set_nsapi_ack(nsapi, FALSE);
+
+      snsm_deactivate_res->nsapi = nsapi;
+      sndcp_unset_nsapi_state(nsapi, MG_DEACT);
+#ifdef SNDCP_UPM_INCLUDED
+      PSEND(hCommUPM, snsm_deactivate_res);
+#else
+      PSEND(hCommSM, snsm_deactivate_res);
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    }
+
+  }
+
+} /* mg_respond_if_nec */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_ntt_comp
++------------------------------------------------------------------------------
+| Description : Sets ntt and comp values acc. to req_xid_block.
+|
+| Parameters  : UBYTE sapi, BOOL is this a renegotiation?
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_ntt_comp (UBYTE sapi) {
+  UBYTE sapi_index = 0;
+  UBYTE nsapi = 0;
+  TRACE_FUNCTION( "mg_set_ntt_comp" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+
+  if (sndcp_data->mg.req_xid_block[sapi_index].v42.is_set) {
+    mg_set_sapi_dntt_state(sapi,
+                          sndcp_data->mg.req_xid_block[sapi_index].v42.ntt,
+                          MG_SELECTED);
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if ((sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis & (1 << nsapi))
+           > 0) {
+        mg_set_sapi_dntt_nsapi(sapi,
+                               sndcp_data->mg.req_xid_block[sapi_index].v42.ntt,
+                               nsapi,
+                               TRUE);
+      }
+    }
+    mg_set_sapi_dcomp_state(sapi,
+                            sndcp_data->mg.req_xid_block[sapi_index].v42.dcomp,
+                            MG_SELECTED);
+    mg_set_sapi_dcomp_dntt(sapi,
+                           sndcp_data->mg.req_xid_block[sapi_index].v42.dcomp,
+                           sndcp_data->mg.req_xid_block[sapi_index].v42.ntt);
+  }
+  if (sndcp_data->mg.req_xid_block[sapi_index].vj.is_set) {
+    mg_set_sapi_pntt_state(sapi,
+                          sndcp_data->mg.req_xid_block[sapi_index].vj.ntt,
+                          MG_SELECTED);
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if ((sndcp_data->mg.req_xid_block[sapi_index].vj.nsapis & (1 << nsapi))
+           > 0) {
+        mg_set_sapi_pntt_nsapi(sapi,
+                               sndcp_data->mg.req_xid_block[sapi_index].vj.ntt,
+                               nsapi,
+                               TRUE);
+      }
+    }
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.req_xid_block[sapi_index].vj.pcomp1,
+                            MG_SELECTED);
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.req_xid_block[sapi_index].vj.pcomp2,
+                            MG_SELECTED);
+    mg_set_sapi_pcomp_pntt(sapi,
+                           sndcp_data->mg.req_xid_block[sapi_index].vj.pcomp1,
+                           sndcp_data->mg.req_xid_block[sapi_index].vj.ntt);
+    mg_set_sapi_pcomp_pntt(sapi,
+                           sndcp_data->mg.req_xid_block[sapi_index].vj.pcomp2,
+                           sndcp_data->mg.req_xid_block[sapi_index].vj.ntt);
+  }
+
+
+} /* mg_set_ntt_comp() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_dntt_nsapi
++------------------------------------------------------------------------------
+| Description : The procedure  stores the info that a given nsapi uses a given
+|               dntt on a given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dntt UBYTE,
+|               IN nsapi UBYTE,
+|               IN used BOOL
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_dntt_nsapi (UBYTE sapi, UBYTE dntt, UBYTE nsapi, BOOL used)
+{
+  TRACE_FUNCTION( "mg_set_sapi_dntt_nsapi" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_dntt_nsapi_set_ra[sapi_index][dntt][nsapi] = used;
+  }
+} /* mg_set_sapi_dntt_nsapi() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_dcomp_state
++------------------------------------------------------------------------------
+| Description : The procedures sets the state of a given dcomp on a given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dcomp UBYTE,
+|               IN stat UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_dcomp_state (UBYTE sapi, UBYTE dcomp, UBYTE stat)
+{
+  TRACE_FUNCTION( "mg_set_sapi_dcomp_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_dcomp_state_ra[sapi_index][dcomp] = stat;
+  }
+} /* mg_set_sapi_dcomp_state() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_dcomp_dntt
++------------------------------------------------------------------------------
+| Description : The procedures sets the dntt assigned to a given dcomp
+|               for a given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dcomp UBYTE,
+|               IN dntt UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_dcomp_dntt (UBYTE sapi, UBYTE dcomp, UBYTE dntt)
+{
+  TRACE_FUNCTION( "mg_set_sapi_dcomp_dntt" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_dcomp_dntt_ra[sapi_index][dcomp] = dntt;
+  }
+} /* mg_set_sapi_dcomp_dntt() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_dntt_rej
++------------------------------------------------------------------------------
+| Description : The procedures stores if a given data
+|               compression entity on a given SAPI is to be rejected in
+|               LL_XID_REQ because it cannot be set up.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dntt UBYTE,
+|               IN rej BOOL
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_dntt_rej (UBYTE sapi, UBYTE dntt, BOOL rej)
+{
+  TRACE_FUNCTION( "mg_set_sapi_dntt_rej" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_dntt_rej_ra[sapi_index][dntt] = rej;
+  }
+} /* mg_set_sapi_dntt_rej() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_dntt_state
++------------------------------------------------------------------------------
+| Description : The procedures sets the state of a given data
+|               compression entity on a given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dntt UBYTE,
+|               IN state UBYTE
+| Note        : sapi dntt rej will be set ti FALSE if state is UNASSIGNED
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_dntt_state (UBYTE sapi, UBYTE dntt, UBYTE state)
+{
+  TRACE_FUNCTION( "mg_set_sapi_dntt_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_dntt_state_ra[sapi_index][dntt] = state;
+
+    if (state == MG_UNASSIGNED) {
+      mg_set_sapi_dntt_rej(sapi, dntt, FALSE);
+    }
+  }
+} /* mg_set_sapi_dntt_state() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_pntt_nsapi
++------------------------------------------------------------------------------
+| Description : The procedure  stores the info that a given nsapi uses a given
+|               pntt on a given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pntt UBYTE,
+|               IN nsapi UBYTE,
+|               IN used BOOL
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_pntt_nsapi (UBYTE sapi, UBYTE pntt, UBYTE nsapi, BOOL used)
+{
+  TRACE_FUNCTION( "mg_set_sapi_pntt_nsapi" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_pntt_nsapi_set_ra[sapi_index][pntt][nsapi] = used;
+  }
+} /* mg_set_sapi_pntt_nsapi() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_pcomp_state
++------------------------------------------------------------------------------
+| Description : The procedures sets the state of a given pcomp on a given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pcomp UBYTE,
+|               IN stat UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_pcomp_state (UBYTE sapi, UBYTE pcomp, UBYTE stat)
+{
+  TRACE_FUNCTION( "mg_set_sapi_pcomp_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_pcomp_state_ra[sapi_index][pcomp] = stat;
+  }
+} /* mg_set_sapi_pcomp_state() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_pcomp_pntt
++------------------------------------------------------------------------------
+| Description : The procedures sets the pntt assigned to a given pcomp
+|               for a given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pcomp UBYTE,
+|               IN pntt UBYTE
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_pcomp_pntt (UBYTE sapi, UBYTE pcomp, UBYTE pntt)
+{
+  TRACE_FUNCTION( "mg_set_sapi_pcomp_pntt" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_pcomp_pntt_ra[sapi_index][pcomp] = pntt;
+  }
+} /* mg_get_sapi_pcomp_pntt() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_pntt_rej
++------------------------------------------------------------------------------
+| Description : The procedures stores if a given data
+|               compression entity on a given SAPI is to be rejected in
+|               LL_XID_REQ because it cannot be set up.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pntt UBYTE,
+|               IN rej BOOL
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_pntt_rej (UBYTE sapi, UBYTE pntt, BOOL rej)
+{
+  TRACE_FUNCTION( "mg_set_sapi_pntt_rej" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_pntt_rej_ra[sapi_index][pntt] = rej;
+  }
+} /* mg_set_sapi_pntt_rej() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_sapi_pntt_state
++------------------------------------------------------------------------------
+| Description : The procedures sets the state of a given header
+|               compression entity on a given SAPI.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pntt UBYTE,
+|               IN state UBYTE
+| Note        : sapi pntt rej will be set ti FALSE if state is UNASSIGNED
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_sapi_pntt_state (UBYTE sapi, UBYTE pntt, UBYTE state)
+{
+  TRACE_FUNCTION( "mg_set_sapi_pntt_state" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_data->mg.sapi_pntt_state_ra[sapi_index][pntt] = state;
+
+    if (state == MG_UNASSIGNED) {
+      mg_set_sapi_pntt_rej(sapi, pntt, FALSE);
+    }
+  }
+} /* mg_set_sapi_pntt_state() */
+
+#ifndef NCONFIG 
+/*
++------------------------------------------------------------------------------
+| Function    : mg_config_delay
++------------------------------------------------------------------------------
+| Description : after config prim DELAY each new context activation will be
+|               computed with a delay.
+|
+| Parameters  : delay in milliseconds
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_config_delay (USHORT millis)
+{
+
+  TRACE_FUNCTION("mg_config_delay");
+
+  sndcp_data->millis = millis;
+
+} /* mg_config_delay() */
+#endif
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_reset_compressors
++------------------------------------------------------------------------------
+| Description : All compressors used by this nsapi are reset.
+|
+| Parameters  : nsapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_reset_compressors (UBYTE nsapi)
+{
+  BOOL compressed = FALSE;
+  TRACE_FUNCTION( "mg_reset_compressors" );
+
+  sndcp_is_nsapi_data_compressed(nsapi, &compressed);
+  if (compressed) {
+    /*
+     * Must be added when data compression is added.
+     */
+  }
+
+  sndcp_is_nsapi_header_compressed(nsapi, &compressed);
+  if (compressed) {
+    UBYTE sapi = 0;
+    UBYTE sapi_index = 0;
+    /*
+     * This is implementation dependent and only works as long as only 1
+     * header compressor is used in cia service.
+     */
+    sndcp_get_nsapi_sapi(nsapi, &sapi);
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sig_mg_cia_new_xid(&sndcp_data->mg.cur_xid_block[sapi_index]);
+  }
+
+} /* mg_reset_compressors() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_reset_comp_ack
++------------------------------------------------------------------------------
+| Description : all compression entities using
+|               acknowledged peer-to-peer LLC operation on this SAPI are reset.
+|
+| Parameters  : sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_reset_comp_ack (UBYTE sapi) {
+  UBYTE nsapi = 0;
+  TRACE_FUNCTION( "mg_reset_comp_ack" );
+  /*
+   * All nsapis at this sapi that use ack mode reset their compressors.
+   */
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+    UBYTE s = 0;
+    BOOL ack = FALSE;
+    BOOL used = FALSE;
+    sndcp_is_nsapi_used(nsapi, &used);
+    if (!used) {
+      continue;
+    }
+    sndcp_get_nsapi_sapi(nsapi, &s);
+    sndcp_get_nsapi_ack(nsapi, &ack);
+    if (ack && s == sapi) {
+      mg_reset_compressors(nsapi);
+    }
+  } /* for all nsapis */
+
+} /* mg_reset_comp_ack() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_reset_states_n_rej
++------------------------------------------------------------------------------
+| Description : Resets all states for ntts and p/dcomp to "unassigned".
+|               Resets the arrays with information on rejcted entities.
+|
+| Parameters  : index of the affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_reset_states_n_rej (UBYTE sapi_index)
+{
+
+  UBYTE ntt = 0;
+  UBYTE nsapi = 0;
+  UBYTE dcomp = 0;
+  UBYTE pcomp = 0;
+  TRACE_FUNCTION( "mg_reset_states_n_rej" );
+
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    sndcp_data->mg.sapi_dntt_state_ra[sapi_index][ntt] = MG_UNASSIGNED;
+    sndcp_data->mg.sapi_pntt_state_ra[sapi_index][ntt] = MG_UNASSIGNED;
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      sndcp_data->mg.sapi_dntt_nsapi_set_ra[sapi_index][ntt][nsapi] = FALSE;
+      sndcp_data->mg.sapi_pntt_nsapi_set_ra[sapi_index][ntt][nsapi] = FALSE;
+    }
+    sndcp_data->mg.sapi_dntt_rej_ra[sapi_index][ntt] = FALSE;
+    sndcp_data->mg.sapi_pntt_rej_ra[sapi_index][ntt] = FALSE;
+  }
+  for (dcomp = 0; dcomp < MG_MAX_DCOMP; dcomp++) {
+    sndcp_data->mg.sapi_dcomp_state_ra[sapi_index][dcomp] = MG_UNASSIGNED;
+  }
+  for (pcomp = 0; pcomp < MG_MAX_PCOMP; pcomp++) {
+    sndcp_data->mg.sapi_pcomp_state_ra[sapi_index][pcomp] = MG_UNASSIGNED;
+  }
+  /*
+   * sapi_dcomp_dntt_ra, sapi_pcomp_pntt_ra not initialized.
+   */
+
+} /* mg_reset_states_n_rej() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_xid_nsapis
++------------------------------------------------------------------------------
+| Description : AN LL_XID_IND has delivered a desired set of nsapis for
+| a V42.bis or VJ compressor entity. Now this is compared to a possibly
+| already existing set of nsapis connected to the given entity.
+| Also the rules in GSM 4.65, 6.8.x are checked.
+|
+| Parameters  : a flag telling if we work on V42 or VanJacobson 'nsapis':
+|            MG_XID_V42_NSAPIS or MG_XID_VJ_NSAPIS.
+|            affected sapi,
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void mg_set_xid_nsapis (UBYTE sapi, UBYTE p_type)
+{
+  USHORT* cur_nsapis = 0;
+  USHORT* ind_nsapis = 0;
+  USHORT* res_nsapis = 0;
+  BOOL* ind_nsapis_set = NULL;
+  UBYTE sapi_index = 0;
+  UBYTE* p_bit = NULL;
+  UBYTE ntt_state = MG_UNASSIGNED;
+  U8 nsapi = 0;
+  U8 s0_m_1_min = 0;
+
+
+  TRACE_FUNCTION( "mg_set_xid_nsapis" );
+
+  sndcp_get_sapi_index(sapi, &sapi_index);
+
+  /*
+   * V42.bis or VanJacobson?
+   */
+  if (p_type == MG_XID_V42_NSAPIS) {
+    cur_nsapis = &(sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis);
+    ind_nsapis = &(sndcp_data->mg.ind_xid_block[sapi_index].v42.nsapis);
+    res_nsapis = &(sndcp_data->mg.res_xid_block[sapi_index].v42.nsapis);
+    ind_nsapis_set =
+      &(sndcp_data->mg.ind_xid_block[sapi_index].v42.nsapis_set);
+    p_bit = &(sndcp_data->mg.ind_xid_block[sapi_index].v42.p_bit);
+
+    *res_nsapis = 0;
+    /*
+     * Only those nsapis will be set in the response for which the user
+     * requested compression. 
+     * Note: te other params are not yet set, must be implemented later.
+     */
+    sndcp_data->mg.res_xid_block[sapi_index].v42.nsapis_set = FALSE;
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if ((((1 << nsapi) & sndcp_data->mg.user_xid_block[nsapi].v42.nsapis) > 
+           0) && 
+           (((1 << nsapi) & 
+            sndcp_data->mg.ind_xid_block[sapi_index].v42.nsapis) > 0)) {
+
+        *res_nsapis |= (1 << nsapi);
+        sndcp_data->mg.res_xid_block[sapi_index].v42.nsapis_set = TRUE;
+
+      }
+    } /* for nsapi */
+
+  } else {
+    cur_nsapis = &(sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis);
+    ind_nsapis = &(sndcp_data->mg.ind_xid_block[sapi_index].vj.nsapis);
+    res_nsapis = &(sndcp_data->mg.res_xid_block[sapi_index].vj.nsapis);
+    ind_nsapis_set =
+      &(sndcp_data->mg.ind_xid_block[sapi_index].vj.nsapis_set);
+    p_bit = &(sndcp_data->mg.ind_xid_block[sapi_index].vj.p_bit);
+
+    *res_nsapis = 0;
+    /*
+     * Only those nsapis will be set in the response for which the user
+     * requested compression. 
+     * In the same loop we set the s0_m_1 to the minimum of
+     * the indicated value and the values requested by the user.
+     * Also the direction is set to the minimum of all requested
+     * directions.
+     */
+    if (sndcp_data->mg.ind_xid_block[sapi_index].vj.s0_m_1 > 0) {
+      s0_m_1_min = sndcp_data->mg.ind_xid_block[sapi_index].vj.s0_m_1;
+    } else if (sndcp_data->mg.cur_xid_block[sapi_index].vj.s0_m_1 > 0) {
+      s0_m_1_min = sndcp_data->mg.cur_xid_block[sapi_index].vj.s0_m_1;
+    } else {
+      s0_m_1_min = SNDCP_VJ_DEFAULT_S0_M_1;
+    }
+ #ifdef SNDCP_UPM_INCLUDED 
+    sndcp_data->mg.res_xid_block[sapi_index].vj.direction = 
+      NAS_HCOMP_BOTH_DIRECT;
+#else
+    sndcp_data->mg.res_xid_block[sapi_index].vj.direction = 
+      SNSM_COMP_BOTH_DIRECT;
+#endif 
+    
+    sndcp_data->mg.res_xid_block[sapi_index].vj.nsapis_set = FALSE;
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if (((1 << nsapi) & sndcp_data->mg.user_xid_block[nsapi].vj.nsapis) > 
+          0 && 
+           (((1 << nsapi) & 
+            sndcp_data->mg.ind_xid_block[sapi_index].vj.nsapis) > 0)) {
+
+        *res_nsapis |= (1 << nsapi);
+        sndcp_data->mg.res_xid_block[sapi_index].vj.nsapis_set = TRUE;
+        if (sndcp_data->mg.user_xid_block[nsapi].vj.s0_m_1 < s0_m_1_min) {
+          s0_m_1_min = sndcp_data->mg.user_xid_block[nsapi].vj.s0_m_1;
+        }
+        sndcp_data->mg.res_xid_block[sapi_index].vj.direction &=
+          sndcp_data->mg.user_xid_block[nsapi].vj.direction;
+      }
+    } /* for nsapi */
+    sndcp_data->mg.res_xid_block[sapi_index].vj.s0_m_1 = s0_m_1_min;
+    if (s0_m_1_min > 0) {
+      sndcp_data->mg.res_xid_block[sapi_index].vj.s0_m_1_set = TRUE;
+    } else {
+      sndcp_data->mg.res_xid_block[sapi_index].vj.direction = 0;
+    }
+  }
+
+    
+
+  /*
+   * Rules in GSM 4.65, 6.8.1: acknowledged and unacknowlegded contexts may not
+   * share the same compressor. If that is demanded by the indication, reset
+   * nsapis parameter to the ones currently used.
+   */
+  if (*ind_nsapis_set &&
+      *ind_nsapis > 0) {
+    BOOL vio = FALSE;
+    mg_detect_mode_clash(*ind_nsapis, &vio);
+    if (!vio) {
+      /*
+       * Modes are the same, set cur to res.
+       */
+      *cur_nsapis = *res_nsapis;
+    } else {
+      *res_nsapis = *cur_nsapis;
+    }
+  }
+
+  /*
+   * Also from 6.8.3: If an unassigned entity number is included with the
+   * p bit set to 0, then the Applicable NSAPIs field shall be set to 0.
+   */
+  if (p_type == MG_XID_V42_NSAPIS) {
+    mg_get_sapi_dntt_state
+      (sapi, sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt, &ntt_state);
+  } else {
+    mg_get_sapi_pntt_state
+      (sapi, sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt, &ntt_state);
+  }
+  if (ntt_state == MG_UNASSIGNED && *p_bit == 0) {
+      *cur_nsapis = 0;
+      *res_nsapis = 0;
+  }
+
+} /* mg_set_xid_nsapis() */
+
+
+/*==== PUBLIC FUNCTIONS =====================================================*/
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_check_cnf_xid
++------------------------------------------------------------------------------
+| Description : The confirmation of a requested XID negotiation has been
+|               received. The answer is now checked.
+|               A main issue is the comparison with the service variable
+|               req_xid_block which holds the requested xid block sent to the
+|               network.
+|               Detected errors:
+| - SNDCP version number not correct
+| - incorrect entity number (must be proposed one)
+| - incorrect sense of negotiation for each parameter (down mainly,
+|   NSAPI down bitwise)
+| - an entity is included in the cnf that was not requested, does not exist
+| Not checked:
+| - out of range value of parameters (must be in range if sense ofnegotiation was right.
+| - parameters with duplicated instances.
+| If one of these errors occurs ret is set to MG_XID_BAD_CONTENT, else
+| MG_XID_OK.
+|
+| Parameters  : ret, affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_check_cnf_xid (UBYTE* ret, UBYTE sapi)
+{
+  UBYTE sapi_index = 0;
+  BOOL wrong = FALSE;
+  TRACE_FUNCTION( "mg_check_cnf_xid" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  *ret = MG_XID_BAD_CONTENT;
+  /*
+   * Check SNDCP version.
+   */
+  if (sndcp_data->mg.cnf_xid_block[sapi_index].version_set) {
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].version !=
+        SNDCP_XID_VERSION) {
+      return;
+    }
+  }
+  /*
+   * If an entity is included that has not been requested / does not exist:
+   * bad content!
+   */
+  if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.is_set &&
+      ! sndcp_data->mg.req_xid_block[sapi_index].v42.is_set &&
+      ! sndcp_data->mg.cur_xid_block[sapi_index].v42.is_set) {
+
+    return;
+  }
+  if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.is_set &&
+      ! sndcp_data->mg.req_xid_block[sapi_index].vj.is_set &&
+      ! sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set) {
+
+    return;
+  }
+
+  /*
+   * Check V42 parameters, if they are set.
+   */
+  if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.is_set) {
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p_bit == 1) {
+      return;
+    }
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.ntt !=
+        sndcp_data->mg.req_xid_block[sapi_index].v42.ntt) {
+      return;
+    }
+    /*
+     * Sense of negotiation. If cnf value has been set, but req has not been
+     * set then cnf value will be compared with cur value. This
+     * is not applied to "applicable nsapis".
+     */
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.nsapis_set) {
+      if (sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis_set) {
+        mg_ushort_sense_bitwise
+          (sndcp_data->mg.cnf_xid_block[sapi_index].v42.nsapis,
+           sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis,
+           &wrong);
+      }
+      if (wrong) {
+        return;
+      }
+    }
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p0_set) {
+      if (sndcp_data->mg.req_xid_block[sapi_index].v42.p0_set) {
+        mg_ubyte_sense_bitwise(sndcp_data->mg.cnf_xid_block[sapi_index].v42.p0,
+                               sndcp_data->mg.req_xid_block[sapi_index].v42.p0,
+                               &wrong);
+      } else {
+        mg_ubyte_sense_bitwise(sndcp_data->mg.cnf_xid_block[sapi_index].v42.p0,
+                               sndcp_data->mg.cur_xid_block[sapi_index].v42.p0,
+                               &wrong);
+      }
+      if (wrong) {
+        return;
+      }
+    }
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p1_set) {
+      if (sndcp_data->mg.req_xid_block[sapi_index].v42.p1_set) {
+        if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p1 >
+          sndcp_data->mg.req_xid_block[sapi_index].v42.p1) {
+          return;
+        }
+      } else {
+        if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p1 >
+          sndcp_data->mg.cur_xid_block[sapi_index].v42.p1) {
+          return;
+        }
+      }
+    }
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p2_set) {
+      if (sndcp_data->mg.req_xid_block[sapi_index].v42.p2_set) {
+        if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p2 >
+          sndcp_data->mg.req_xid_block[sapi_index].v42.p2) {
+          return;
+        }
+      } else {
+        if (sndcp_data->mg.cnf_xid_block[sapi_index].v42.p2 >
+          sndcp_data->mg.cur_xid_block[sapi_index].v42.p2) {
+          return;
+        }
+      }
+    }
+  }
+  /*
+   * Check VJ parameters, if they are set.
+   */
+  if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.is_set) {
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.p_bit == 1) {
+      return;
+    }
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.ntt !=
+        sndcp_data->mg.req_xid_block[sapi_index].vj.ntt) {
+      return;
+    }
+    /*
+     * Sense of negotiation.
+     */
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.nsapis_set) {
+      if (sndcp_data->mg.req_xid_block[sapi_index].vj.nsapis_set) {
+        mg_ushort_sense_bitwise(sndcp_data->mg.cnf_xid_block[sapi_index].vj.nsapis,
+                                sndcp_data->mg.req_xid_block[sapi_index].vj.nsapis,
+                                &wrong);
+      }
+      if (wrong) {
+        return;
+      }
+    }
+    if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.s0_m_1_set) {
+      if (sndcp_data->mg.req_xid_block[sapi_index].vj.s0_m_1_set) {
+        if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.s0_m_1 >
+          sndcp_data->mg.req_xid_block[sapi_index].vj.s0_m_1) {
+          return;
+        }
+      } else {
+        if (sndcp_data->mg.cnf_xid_block[sapi_index].vj.s0_m_1 >
+          sndcp_data->mg.cur_xid_block[sapi_index].vj.s0_m_1) {
+          return;
+        }
+      }
+    }
+  }
+  *ret = MG_XID_OK;
+
+} /* mg_check_cnf_xid() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_check_ind_xid
++------------------------------------------------------------------------------
+| Description : Service variable ind_xid_block holds the xid block indicated
+| by the peer. The ind_xid_block is now checked: (from 4.65 6.8.2).
+| Criterium 1:
+| If the indicated ntt is already used and pcomp or dcomp values are different,
+| ret is set to MG_XID_BAD_CONTENT.
+| Criterium 2:
+| If the indicated algorithm type is already used and pcomp or dcomp values
+| are different, ret is set to MG_XID_BAD_CONTENT.
+|
+| Note: implementation dependent: if data compression is proposed, it will
+| be rejected.
+|
+| Otherwise ret is set to MG_XID_OK.
+| Parameters  : ret, affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_check_ind_xid (UBYTE* ret, UBYTE sapi)
+{
+  UBYTE sapi_index = 0;
+  UBYTE status = MG_UNASSIGNED;
+  TRACE_FUNCTION( "mg_check_ind_xid" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  *ret = MG_XID_OK;
+
+  /*
+   * Check criterium 1.
+   */
+  if (sndcp_data->mg.ind_xid_block[sapi_index].v42.is_set &&
+      sndcp_data->mg.ind_xid_block[sapi_index].v42.p_bit == SNDCP_P_BIT_1) {
+    mg_get_sapi_dntt_state
+      (sapi, sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt, &status);
+    if (status == MG_ASSIGNED) {
+      /*
+       * Entity already used. DCOMP values differ?
+       */
+      mg_get_sapi_dcomp_state
+        (sapi, sndcp_data->mg.ind_xid_block[sapi_index].v42.dcomp, &status);
+      if (status != MG_ASSIGNED) {
+        /*
+         * The indicated dcomp is not assigned. Error.
+         */
+        mg_set_sapi_dntt_rej(sapi,
+                             sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt,
+                             TRUE);
+        *ret = MG_XID_BAD_CONTENT;
+      } else {
+        UBYTE dntt = 0;
+        mg_get_sapi_dcomp_dntt
+          (sapi, sndcp_data->mg.ind_xid_block[sapi_index].v42.dcomp, &dntt);
+        if (dntt != sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt) {
+          /*
+           * Dcomp values differ, Error.
+           */
+          mg_set_sapi_dntt_rej(sapi,
+                               sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt,
+                               TRUE);
+          *ret = MG_XID_BAD_CONTENT;
+        }
+      }
+    }
+  }
+  if (sndcp_data->mg.ind_xid_block[sapi_index].vj.is_set &&
+      sndcp_data->mg.ind_xid_block[sapi_index].vj.p_bit == SNDCP_P_BIT_1) {
+    mg_get_sapi_pntt_state
+      (sapi, sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt, &status);
+    if (status == MG_ASSIGNED) {
+      /*
+       * Entity already used. PCOMP values differ?
+       */
+      /*
+       * PCOMP 1.
+       */
+      mg_get_sapi_pcomp_state
+        (sapi, sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp1, &status);
+      if (status != MG_ASSIGNED) {
+        /*
+         * The indicated pcomp is not assigned. Error.
+         */
+        mg_set_sapi_pntt_rej(sapi,
+                             sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                             TRUE);
+        *ret = MG_XID_BAD_CONTENT;
+      } else {
+        UBYTE pntt = 0;
+        mg_get_sapi_pcomp_pntt
+          (sapi, sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp1, &pntt);
+        if (pntt != sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt) {
+          /*
+           * Pcomp values differ, Error.
+           */
+          mg_set_sapi_pntt_rej(sapi,
+                               sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                               TRUE);
+          *ret = MG_XID_BAD_CONTENT;
+        }
+      }
+      /*
+       * PCOMP 2.
+       */
+      mg_get_sapi_pcomp_state
+        (sapi, sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp1, &status);
+      if (status != MG_ASSIGNED) {
+        /*
+         * The indicated pcomp is not assigned. Error.
+         */
+        mg_set_sapi_pntt_rej(sapi,
+                             sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                             TRUE);
+        *ret = MG_XID_BAD_CONTENT;
+      } else {
+        UBYTE pntt = 0;
+        mg_get_sapi_pcomp_pntt
+          (sapi, sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp1, &pntt);
+        if (pntt != sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt) {
+          /*
+           * Dcomp values differ, Error.
+           */
+          mg_set_sapi_pntt_rej(sapi,
+                               sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                               TRUE);
+          *ret = MG_XID_BAD_CONTENT;
+        }
+      }
+    }
+  }
+
+  /*
+   * Check criterium 2.
+   * Since in the current implementation there is only SNDCP_XID_VJ and
+   * SNDCP_XID_V42, and only 1 instance of each,
+   * it will be sufficient to compare the proposed values for pcomp/dcomp
+   * with the ones in cur_xid_block.
+   * An error may only occur if cur and ind are set.
+   */
+  if (sndcp_data->mg.ind_xid_block[sapi_index].v42.is_set &&
+      sndcp_data->mg.cur_xid_block[sapi_index].v42.is_set &&
+      sndcp_data->mg.ind_xid_block[sapi_index].v42.p_bit == SNDCP_P_BIT_1) {
+    if (sndcp_data->mg.ind_xid_block[sapi_index].v42.dcomp !=
+      sndcp_data->mg.cur_xid_block[sapi_index].v42.dcomp) {
+      mg_set_sapi_dntt_rej(sapi,
+                           sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt,
+                           TRUE);
+      *ret = MG_XID_BAD_CONTENT;
+    }
+  }
+  if (sndcp_data->mg.ind_xid_block[sapi_index].vj.is_set &&
+      sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set &&
+      sndcp_data->mg.ind_xid_block[sapi_index].v42.p_bit == SNDCP_P_BIT_1) {
+    if (sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp1 !=
+      sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp1) {
+      mg_set_sapi_pntt_rej(sapi,
+                           sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                           TRUE);
+      *ret = MG_XID_BAD_CONTENT;
+    }
+    if (sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp2 !=
+      sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp2) {
+      mg_set_sapi_pntt_rej(sapi,
+                           sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                           TRUE);
+      *ret = MG_XID_BAD_CONTENT;
+    }
+  }
+
+#ifndef TI_PS_FF_V42BIS
+  /*
+   * Implementation dependent: If data compression is proposed, reject it!
+   */
+  if (sndcp_data->mg.ind_xid_block[sapi_index].v42.is_set) {
+    mg_set_sapi_dntt_rej(sapi,
+                         sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt,
+                         TRUE);
+  }
+#endif /* !TI_PS_FF_V42BIS */
+} /* mg_check_ind_xid() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_clean_xid
++------------------------------------------------------------------------------
+| Description : Cleans up the XID organizing arrays for nsapis and ntts
+|
+| Parameters  :
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_clean_xid (UBYTE sapi) {
+  UBYTE nsapi = 0;
+  UBYTE sapi_index = 0;
+  UBYTE stat = MG_UNASSIGNED;
+  TRACE_FUNCTION( "mg_clean_xid" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+
+
+  /*
+   * NSAPIs that were assigned to a compressor unit but are not any more.
+   */
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    BOOL connected =
+      ((1 << nsapi) & (sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis)) > 0;
+    mg_set_sapi_dntt_nsapi(sapi,
+                           sndcp_data->mg.cur_xid_block[sapi_index].v42.ntt,
+                           nsapi,
+                           connected);
+    connected =
+      ((1 << nsapi) & (sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis)) > 0;
+    mg_set_sapi_pntt_nsapi(sapi,
+                           sndcp_data->mg.cur_xid_block[sapi_index].vj.ntt,
+                           nsapi,
+                           connected);
+
+
+  }
+
+  /*
+   * Formerly assigned ntts that are now unassigned are cleaned.
+   * Implemented here: the one dntt and the one pntt in cur_xid_block are now
+   * checked. If they are in state MG_ASSIGNED but the affected 'nsapis'
+   * element is set to all '0' then the entities enter state MG_UNASSIGNED,
+   * all nsapis re set to FALSE in the sapi_?ntt_nsapi_ra, all
+   * affected pcomp/dcomp values are set to MG_UNASSIGNED.
+   */
+  mg_get_sapi_dntt_state(sapi,
+                         sndcp_data->mg.cur_xid_block[sapi_index].v42.ntt,
+                         &stat);
+  if (stat == MG_ASSIGNED &&
+      sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis == 0) {
+    /*
+     * Reset dntt state.
+     */
+    mg_set_sapi_dntt_state(sapi,
+                           sndcp_data->mg.cur_xid_block[sapi_index].v42.ntt,
+                           MG_UNASSIGNED);
+
+    /*
+     * reset nsapi connections.
+     */
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      mg_set_sapi_dntt_nsapi(sapi,
+                             sndcp_data->mg.cur_xid_block[sapi_index].v42.ntt,
+                             nsapi,
+                             FALSE);
+    }
+    /*
+     * Reset dcomp.
+     */
+    mg_set_sapi_dcomp_state(sapi,
+                            sndcp_data->mg.cur_xid_block[sapi_index].v42.dcomp,
+                            MG_UNASSIGNED);
+  }
+
+
+  /*
+   * The same for header compresion.
+   */
+  mg_get_sapi_pntt_state(sapi,
+                         sndcp_data->mg.cur_xid_block[sapi_index].vj.ntt,
+                         &stat);
+  if (stat == MG_ASSIGNED &&
+      sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis == 0) {
+    /*
+     * Reset pntt state.
+     */
+    mg_set_sapi_pntt_state(sapi,
+                           sndcp_data->mg.cur_xid_block[sapi_index].vj.ntt,
+                           MG_UNASSIGNED);
+    /*
+     * reset nsapi connections.
+     */
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      mg_set_sapi_pntt_nsapi(sapi,
+                             sndcp_data->mg.cur_xid_block[sapi_index].vj.ntt,
+                             nsapi,
+                             FALSE);
+    }
+    /*
+     * Reset pcomps.
+     */
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp1,
+                            MG_UNASSIGNED);
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp2,
+                            MG_UNASSIGNED);
+  }
+
+
+
+} /* mg_clean_xid() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_col_no_re
++------------------------------------------------------------------------------
+| Description : The function mg_col_no_re represents  the SDL label
+|               COL_NO_RE: an LL_ESTABLISH_IND has been received, we do
+|               have a collision situation like given in [GSM 4.65, 6.2.1.4],
+|               we do not have a re-establishment situation.
+|
+| Parameters  : the received LL_ESTABLISH_IND
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_col_no_re (T_LL_ESTABLISH_IND* ll_establish_ind)
+{
+  TRACE_FUNCTION( "mg_col_no_re" );
+
+  /*
+   * Resume data transfer suspended due to pending establishment;
+   */
+  sig_mg_su_resume(ll_establish_ind->sapi);
+  sig_mg_sua_resume(ll_establish_ind->sapi);
+  mg_resume_affected_nus(ll_establish_ind->sapi);
+
+  /*
+   * Now proceed like without collision.
+   */
+  mg_no_col_no_re(ll_establish_ind);
+
+
+} /* mg_col_no_re() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_col_re
++------------------------------------------------------------------------------
+| Description : The function mg_col_re represents  the SDL label
+|               COL_RE: an LL_ESTABLISH_IND has been received, we do
+|               have a collision situation like given in [GSM 4.65, 6.2.1.4],
+|               we do have a re-establishment situation.
+|
+| Parameters  : the received LL_ESTABLISH_IND
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_col_re (T_LL_ESTABLISH_IND* ll_establish_ind)
+{
+  TRACE_FUNCTION( "mg_col_re" );
+  /*
+   * Resume data transfer suspended due to pending establishment;
+   */
+  sig_mg_su_resume(ll_establish_ind->sapi);
+  sig_mg_sua_resume(ll_establish_ind->sapi);
+  mg_resume_affected_nus(ll_establish_ind->sapi);
+  /*
+   * Now proceed like without collision.
+   */
+  mg_no_col_re(ll_establish_ind);
+} /* mg_col_re() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_decode_xid
++------------------------------------------------------------------------------
+| Description : Implementation dependent.
+|               The entity number
+|               Works only for algorithm types 0
+|               (V42 for data and VanJacobson for header).
+|               This procedure reads the given xid block (in form of an sdu)
+|               and writes the fields to the given xid_block variable, if
+|               compression fields for algorithms 0 (V42 or VanJacobson) are
+|               given.
+|               If the parsed sdu starts a negotiation then the p bit will be
+|               set to 1 and the "algorithm type" field will be included. If
+|               the parsed sdu ends a negotiation then the p bit will be set
+|               to 0 and the "algorithm type" field will not be included.
+|               In this case it will be checked if the "entity number" field
+|               corresponds with the entity number set in req_xid_block.
+|
+|               Note: This procedure only re-formats the xid_block. The content
+|               of the xid_block are not checked. This will be done in a later
+|               procedure on the basis of the xid_block filled in here.
+|               The only error possibly detected is returned, if the byte format
+|               of the given xid block sdu is not correct: MG_XID_BAD_FORMAT.
+|               Then parameter type 1 list is read. If a data comp field has
+|               an algorithm of type 0 (V42bis) then its values are written
+|               to the given xid_block. If the algorithm is not 0 (V42bis) then
+|               the entity is rejected.
+|               The same for parameter type 2, here only algorithm type 0
+|               (VanJacobson) is written to the xid_block.
+|               Note: it is assumed here that the parameters come in line 0, 1, 2.
+|               If that will no be the case, the parsing will have to modified
+|               slightly.
+|               If an unknown parameter type (not 0, 1, 2) is detected, an
+|               MG_XID_BAD_FORMAT is returned.
+|
+| Parameters  : the sdu to be parsed, is negotiation started here?, the 
+|               destination T_XID_BLOCK, a return value that should be MG_XID_OK
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_decode_xid (T_sdu* sdu,
+                           T_XID_BLOCK* xid_block,
+                           UBYTE* ret,
+                           UBYTE sapi)
+{
+
+#define CHECK_XID_BUFFER_LEN if (index + field_index >= ((sdu->l_buf) >> 3)) return
+  UBYTE sapi_index = 0;
+  /*
+   * Index for the whole sdu.
+   */
+  USHORT index = sdu->o_buf / 8;
+  /*
+   * Sub index used in compression fields.
+   */
+  USHORT field_index = 0;
+  /*
+   * This is the index where the parameter 2 for header compression begins.
+   */
+  USHORT beginning_of_header_comp = 0;
+  /*
+   * Length of complete parameter blocks of type 1 or 2.
+   */
+  USHORT length = 0;
+  /*
+   * Was decoding successful?
+   */
+  BOOL ok = FALSE;
+
+  TRACE_FUNCTION( "mg_decode_xid" );
+
+  /*
+   * Reset xid_block.
+   */
+  sndcp_reset_xid_block(xid_block);
+
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  *ret = MG_XID_BAD_FORMAT;
+
+  /*
+   * If end is reached, return with ok.
+   */
+  if (sdu->l_buf == 0) {
+    *ret = MG_XID_OK;
+    return;
+  }
+  /*
+   * If parameter type 0 is included, store it.
+   */
+  CHECK_XID_BUFFER_LEN;
+  if (sdu->buf[index] == SNDCP_XID_PARAM_TYPE_0) {
+    index++;
+    xid_block->version_set = TRUE;
+    /*
+     * Length should be SNDCP_XID_0_LEN, but is not checked.
+     */
+    CHECK_XID_BUFFER_LEN;
+    length = sdu->buf[index];
+
+    index++;
+    /*
+     * Set the version in xid_block.
+     */
+    CHECK_XID_BUFFER_LEN;
+    xid_block->version = sdu->buf[index];
+    index+= length;
+  }
+
+  /*
+   * If end is reached, return with ok.
+   */
+  if (index == ((sdu->l_buf) >> 3)) {
+    *ret = MG_XID_OK;
+    return;
+  }
+
+  /*
+   * If parameter type 1 is included, store it.
+   */
+  if (sdu->buf[index] == SNDCP_XID_PARAM_TYPE_1) {
+    /*
+     * Length of all data compression parameters.
+     */
+    index++;
+    CHECK_XID_BUFFER_LEN;
+    length = sdu->buf[index];
+    /*
+     * This is the index where the parameter 2 infos for header compression
+     * begin.
+     */
+    beginning_of_header_comp = index + length + 1;
+
+    /*
+     * Search data compression parameters for algorithm type 1.
+     */
+    while (length > 0) {
+      /*
+       * Index is now on p-bit-entity-octet for one field.
+       * If the p bit is set to 1 then we read the algorithm
+       * type and drop the field if it is not SNDCP_XID_V42.
+       * If the p bit is not set to 1 then we read the
+       * entity number and drop the field if it is not the entity number
+       * proposed in req_xid_block.
+       */
+
+      /*
+       * Set field_index to beginning of next data compression field.
+       */
+      field_index++;
+
+      CHECK_XID_BUFFER_LEN;
+      if ((sdu->buf[index + field_index] & 0x80) > 0) {
+        /*
+         * P bit set to 1. Check algorithm type and drop field if
+         * type is not known.
+         * Set ntt.
+         */
+        xid_block->v42.ntt = sdu->buf[index + field_index] & 0x1F;
+        /*
+         * Set field_index to algorithm type.
+         */
+        field_index ++;
+        CHECK_XID_BUFFER_LEN;
+        if ((sdu->buf[index + field_index] & 0xf) != SNDCP_XID_V42) {
+          /*
+           * Wrong algorithm type. Add the ntt to list of rejected ones.
+           */
+          mg_set_sapi_dntt_rej(sapi, xid_block->v42.ntt, TRUE);
+          /*
+           * Set index to length octet.
+           */
+          field_index ++;
+          /*
+           * Set index to next field. Check field length.
+           */
+          CHECK_XID_BUFFER_LEN;
+          field_index += sdu->buf[index + field_index];
+          if (field_index > length) {
+            /*
+             * Field is too long, bad format.
+             */
+            return;
+          }
+          if (field_index == length) {
+            /*
+             * Field is completed but entity number has not been found because in
+             * that case the loop would have been left with break;
+             */
+            xid_block->v42.is_set = FALSE;
+            break;
+          }
+          continue;
+        } else {
+          /*
+           * Correct algorithm type.
+           */
+          if (xid_block->v42.is_set == FALSE) {
+            /*
+             * This is the first occurrence.
+             */
+            xid_block->v42.is_set = TRUE;
+            xid_block->v42.p_bit = 1;
+
+
+            mg_decode_v42(sdu,
+                          &index,
+                          &field_index,
+                          xid_block,
+                          &ok,
+                          SNDCP_P_BIT_1);
+            if (!ok) {
+              /*
+               * Decoding was not successful.
+               */
+              return;
+            }
+          } else {
+            /*
+             * There has been an occurrence of this algorithm.
+             */
+            /*
+             * Set index to length octet.
+             */
+            field_index ++;
+            /*
+             * Set index to next field. Check field length.
+             */
+            CHECK_XID_BUFFER_LEN;
+            field_index += sdu->buf[index + field_index];
+            if (field_index > length) {
+              /*
+               * Field is too long, bad format.
+               */
+              return;
+            }
+            if (field_index == length) {
+              /*
+               * Field is completed.
+               */
+              break;
+            }
+
+          }
+          /*
+           * If all data parameters are read, go ahead for header ones.
+           */
+          if (field_index == length) {
+            break;
+          }
+        }
+      } else {
+        /*
+         * P bit set to 0.
+         * Check entity number and drop field if it is not the proposed one or
+         * V42 has not been proposed yet.
+         * field_index is already on p-bit-entity-octet.
+         */
+        CHECK_XID_BUFFER_LEN;
+        if (((sdu->buf[index + field_index] & 0x1f) !=
+            xid_block->v42.ntt) && xid_block->v42.is_set) {
+          /*
+           * Wrong entity number.
+           */
+          /*
+           * Set field_index to length octet.
+           */
+          field_index ++;
+          /*
+           * Set index to next field. Check field length.
+           */
+          CHECK_XID_BUFFER_LEN;
+          field_index += sdu->buf[index + field_index];
+          if (field_index > length) {
+            /*
+             * Field is too long, bad format.
+             */
+            return;
+          }
+          if (field_index == length) {
+            /*
+             * Field is completed but entity number has not been found because in
+             * that case the loop would have been left with break;
+             */
+            xid_block->v42.is_set = FALSE;
+            break;
+          }
+          continue;
+        } else {
+          /*
+           * The entity number of this field equals the entity number in
+           * ththat is already in the xid block or there is no entity in
+           * the xid block yet.
+           */
+          xid_block->v42.is_set = TRUE;
+          xid_block->v42.p_bit = 0;
+          xid_block->v42.ntt =
+            (sdu->buf[index + field_index] & 0x1f);
+
+          mg_decode_v42(sdu,
+                        &index,
+                        &field_index,
+                        xid_block,
+                        &ok,
+                        SNDCP_P_BIT_0);
+          if (!ok) {
+            /*
+             * Decoding was not successful.
+             */
+            return;
+          }
+
+          /*
+           * If all data parameters are read, go ahead for header ones.
+           */
+          if (field_index == length) {
+            break;
+          }
+        }
+      } /* p bit set to 0 */
+    } /* while  */
+    field_index = 0;
+    index = beginning_of_header_comp;
+  }
+
+  /*
+   * Now comes the header compression parameter type 2.
+   * Is it omitted?
+   */
+  if (index == ((sdu->l_buf) >> 3)) {
+    *ret = MG_XID_OK;
+    return;
+  }
+
+  /*
+   * Parameter type should be SNDCP_XID_PARAM_TYPE_2.
+   */
+  CHECK_XID_BUFFER_LEN;
+  if (sdu->buf[index] != SNDCP_XID_PARAM_TYPE_2) {
+    return;
+  }
+  /*
+   * Length of all header compression parameters.
+   */
+  index++;
+  CHECK_XID_BUFFER_LEN;
+  length = sdu->buf[index];
+
+
+  /*
+   * Search header compression parameters for algorithm type 2.
+   */
+  while (length > 0) {
+    /*
+     * Index is now on p-bit-entity-octet for one field.
+     * If the p bit is set to 1 then we read the algorithm
+     * type and drop the field if it is not SNDCP_XID_VJ.
+     * If the p bit is not set to 1 then we read the
+     * entity number and drop the field if it is not the entity number
+     * proposed in req_xid_block.
+     */
+    /*
+     * Set field_index to beginning of next header compression field.
+     */
+    field_index++;
+    CHECK_XID_BUFFER_LEN;
+    if ((sdu->buf[index + field_index] & 0x80) > 0) {
+      UBYTE ntt = 0;
+      /*
+       * P bit set to 1. Check algorithm type and drop field if
+       * type is not known.
+       * Set ntt.
+       */
+      ntt = sdu->buf[index + field_index] & 0x1F;
+
+      /*
+       * Set index to algorithm type.
+       */
+      field_index ++;
+      CHECK_XID_BUFFER_LEN;
+      if (((sdu->buf[index + field_index] & 0xf) != SNDCP_XID_VJ)
+          ||
+          ((sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set) &&
+           (xid_block->vj.is_set == FALSE) &&
+           (ntt != sndcp_data->mg.cur_xid_block[sapi_index].vj.ntt)
+          )
+         ) {
+        /*
+         * Wrong algorithm type or
+         * vj comp is currently used and proposed ntt is not equal to currently
+         * used one.
+         * Add ntt to list of rejected ones.
+         */
+        mg_set_sapi_pntt_rej(sapi, ntt, TRUE);
+        /*
+         * Set index to length octet.
+         */
+        field_index ++;
+        /*
+         * Set index to next field. Check field length.
+         */
+        CHECK_XID_BUFFER_LEN;
+        field_index += sdu->buf[index + field_index];
+        if (field_index > length) {
+          /*
+           * Field is too long, bad format.
+           */
+          return;
+        }
+        if (field_index == length) {
+          /*
+           * Field is completed but entity number has not been found because in
+           * that case the loop would have been left with break;
+           */
+          xid_block->vj.is_set = FALSE;
+          break;
+        }
+        continue;
+      }
+      /*
+       * Correct algorithm type and vj requested.
+       */
+      /*
+       * If no vj comp is currently used and xid_block.vj is not set yet, take
+       * the proposed one.
+       * Also if vj comp is currently used and xid block is not yet set and
+       * proposed ntt is equal to currently used one.
+       */
+      if (((! sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set) &&
+           (xid_block->vj.is_set == FALSE))
+          ||
+          ((sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set) &&
+           (xid_block->vj.is_set == FALSE) &&
+           (ntt == sndcp_data->mg.cur_xid_block[sapi_index].vj.ntt))) {
+
+        xid_block->vj.is_set = TRUE;
+        xid_block->vj.p_bit = 1;
+        xid_block->vj.ntt = ntt;
+
+        mg_decode_vj (sdu,
+                      &index,
+                      &field_index,
+                      xid_block,
+                      &ok,
+                      SNDCP_P_BIT_1);
+        if (!ok) {
+          /*
+           * Decoding was not successful.
+           */
+          return;
+        }
+        /*
+         * If all header parameters are read, go ahead for header ones.
+         */
+        if (field_index == length) {
+          break;
+        }
+        continue;
+      }
+      /*
+       * This is not the first occurrence. Ignore.
+       */
+      /*
+       * Set index to length octet.
+       */
+      field_index ++;
+      /*
+       * Set index to next field. Check field length.
+       */
+      CHECK_XID_BUFFER_LEN;
+      field_index += sdu->buf[index + field_index];
+      if (field_index > length) {
+        /*
+         * Field is too long, bad format.
+         */
+        return;
+      }
+      if (field_index == length) {
+        /*
+         * Field is completed.
+         */
+        break;
+      }
+
+    } else {
+      /*
+       * P bit set to 0.
+       * Check entity number and drop field if it is not the proposed one or
+       * VJ has not been proposed yet.
+       * Index is already on p-bit-entity-octet.
+       */
+      CHECK_XID_BUFFER_LEN;
+      if (((sdu->buf[index + field_index] & 0x1f) !=
+          xid_block->vj.ntt) && xid_block->vj.is_set) {
+        /*
+         * Wrong entity number.
+         * Set index to length octet.
+         */
+        field_index ++;
+        /*
+         * Set index to next field. Check field length.
+         */
+        CHECK_XID_BUFFER_LEN;
+        field_index += sdu->buf[index + field_index];
+        if (field_index > length) {
+          /*
+           * Field is too long, bad format.
+           */
+          return;
+        }
+        if (field_index == length) {
+          /*
+           * Field is completed but entity number has not been found because in
+           * that case the loop would have been left with break;
+           */
+          break;
+        }
+        continue;
+      } else {
+        /*
+         * The entity number of this field equals the entity number in
+         * that is already in the xid_block or there is no entity number
+         * in the block yet.
+         */
+        xid_block->vj.is_set = TRUE;
+        xid_block->vj.p_bit = 0;
+        xid_block->vj.ntt =
+          (sdu->buf[index + field_index] & 0x1f);
+
+        mg_decode_vj (sdu,
+                      &index,
+                      &field_index,
+                      xid_block,
+                      &ok,
+                      SNDCP_P_BIT_0);
+        if (!ok) {
+          /*
+           * Decoding was not successful.
+           */
+          return;
+        }
+        /*
+         * The one field with same entity number as in req_xid_block has been
+         * found and loop of data compression field may be left.
+         * If errors in not used fields are to be detected then we must continue here!
+         */
+        /*
+         * If all header parameters are read, leave.
+         */
+        if (field_index == length) {
+          break;
+        }
+      }
+    }
+  } /* while */
+  /*
+   * It is not checked here whether the sdu is completely read.
+   */
+  *ret = MG_XID_OK;
+
+} /* mg_decode_xid() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_dti_close
++------------------------------------------------------------------------------
+| Description : Closes DTI connection
+| Parameters  : nsapi
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_dti_close (UBYTE nsapi)
+{
+
+#ifdef _SNDCP_DTI_2_
+  UBYTE interfac = SNDCP_INTERFACE_UNACK;
+#ifndef SNDCP_UPM_INCLUDED
+  sndcp_get_nsapi_interface(nsapi, &interfac);
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+  dti_close(sndcp_data->hDTI, /* DTI_HANDLE *hDTI, */
+            0, /* U8 instance, */
+            interfac, /* U8 interface, */
+            nsapi,
+            NULL/* U8 channel); */
+           );
+#else /*_SNDCP_DTI_2_*/
+  UBYTE interfac = SNDCP_INTERFACE_UNACK;
+
+  sndcp_get_nsapi_interface(nsapi, &interfac);
+  dti_close(sndcp_data->hDTI, /* DTI_HANDLE *hDTI, */
+            0, /* U8 instance, */
+            interfac, /* U8 interface, */
+            nsapi /* U8 channel); */
+
+           );
+#endif /*_SNDCP_DTI_2_*/
+
+  /*
+   * The following is done in any case since the callback will not be called.
+   */
+  nu_connection_state(nsapi, FALSE);
+   
+  /*FIXME ! Added newly. To be verified.*/
+#ifdef SNDCP_UPM_INCLUDED 
+  {
+    U32 linkid = 0;
+    PALLOC (sn_dti_cnf, SN_DTI_CNF);
+    sndcp_get_nsapi_linkid(nsapi, &linkid);
+    sn_dti_cnf->dti_linkid = linkid;
+    sn_dti_cnf->dti_conn = NAS_DISCONNECT_DTI;
+    PSEND(hCommMMI, sn_dti_cnf);
+  }
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+} /* mg_dti_close() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_dti_open
++------------------------------------------------------------------------------
+| Description : Opens DTI connection
+| Parameters  : nsapi
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_dti_open (UBYTE nsapi)
+{
+#ifdef _SNDCP_DTI_2_
+  UBYTE* neighbor = NULL;
+  ULONG linkid = 0;
+#ifndef SNDCP_UPM_INCLUDED
+  BOOL ack = FALSE;
+#endif 
+  U8 direction = DTI_CHANNEL_TO_LOWER_LAYER;
+  UBYTE interfac = SNDCP_INTERFACE_UNACK;
+
+  sndcp_get_nsapi_linkid(nsapi, &linkid);
+  sndcp_get_nsapi_neighbor(nsapi, &neighbor);
+#ifndef SNDCP_UPM_INCLUDED
+  sndcp_get_nsapi_ack(nsapi, &ack);
+#endif 
+  sndcp_get_nsapi_direction(nsapi, &direction);
+#ifndef SNDCP_UPM_INCLUDED
+  if (ack) {
+    interfac = SNDCP_INTERFACE_ACK;
+    sndcp_set_nsapi_interface(nsapi, interfac);
+  }
+#endif
+
+  dti_open(sndcp_data->hDTI, /* DTI_HANDLE hDTI */
+           0, /* U8 instance */
+           interfac, /* U8 interface */
+           nsapi, /* U8 channel */
+           0, /* U8 queue_size */
+           direction, /* U8 direction */
+           DTI_QUEUE_WATERMARK, /* U8 link options */
+           DTI_VERSION_10, /* U32 version */
+           neighbor, /* U8 *neighbor_entity */
+           linkid/* U32 link_id */
+           );
+#else /*_SNDCP_DTI_2_*/
+  UBYTE* neighbor = NULL;
+  ULONG linkid = 0;
+  BOOL ack = FALSE;
+  BOOL direction = HOME;
+  UBYTE interfac = SNDCP_INTERFACE_UNACK;
+
+  sndcp_get_nsapi_linkid(nsapi, &linkid);
+  sndcp_get_nsapi_neighbor(nsapi, &neighbor);
+  sndcp_get_nsapi_ack(nsapi, &ack);
+  sndcp_get_nsapi_direction(nsapi, &direction);
+#ifndef SNDCP_UPM_INCLUDED
+  if (ack) {
+    interfac = SNDCP_INTERFACE_ACK;
+    sndcp_set_nsapi_interface(nsapi, interfac);
+  }
+#endif 
+
+  dti_open(sndcp_data->hDTI, /* DTI_HANDLE *hDTI */
+           0, /* U8 instance */
+           interfac, /* U8 interface */
+           nsapi, /* U8 channel */
+           0, /* U8 queue_size */
+           direction, /* BOOL direction */
+           FLOW_CNTRL_ENABLED, /* U8 comm_type */
+           DTI_VERSION_10, /* U32 version */
+           neighbor, /* U8 *neighbor_entity */
+           linkid/* U32 link_id */
+           );
+
+#endif /*_SNDCP_DTI_2_*/
+} /* mg_dti_open() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_init
++------------------------------------------------------------------------------
+| Description : The function mg_init() ....
+|
+| Parameters  :
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_init (void)
+{
+
+  UBYTE sapi_index = 0;
+  UBYTE nsapi = 0;
+  TRACE_FUNCTION( "mg_init" );
+  INIT_STATE(MG, MG_DEFAULT);
+  /*
+   * req_xid_block, cnf_xid_block, cur_xid_block not initialized.
+   */
+  for (sapi_index = 0; sapi_index < SNDCP_NUMBER_OF_SAPIS; sapi_index++) {
+
+    mg_reset_states_n_rej(sapi_index);
+    /*
+     * Init renegotiation counter and cur_xid_block with default values.
+     */
+    sndcp_data->mg.renego[sapi_index] = 0;
+
+    sndcp_reset_xid_block(&sndcp_data->mg.req_xid_block[sapi_index]);
+    sndcp_reset_xid_block(&sndcp_data->mg.cnf_xid_block[sapi_index]);
+    sndcp_reset_xid_block(&sndcp_data->mg.ind_xid_block[sapi_index]);
+    sndcp_reset_xid_block(&sndcp_data->mg.res_xid_block[sapi_index]);
+    sndcp_reset_xid_block(&sndcp_data->mg.cur_xid_block[sapi_index]);
+    sndcp_reset_xid_block(&sndcp_data->mg.new_xid_block[sapi_index]);
+
+  }
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    sndcp_reset_xid_block(&sndcp_data->mg.user_xid_block[nsapi]);
+    sndcp_data->mg.user_xid_block[nsapi].vj.s0_m_1 = 0;
+    sndcp_data->cur_pcomp[nsapi] = 0;
+    sndcp_data->cur_dcomp[nsapi] = 0;
+    sndcp_data->cur_seg_pos[nsapi] = 0;
+    sndcp_data->cur_pdu_ref[nsapi].ref_nsapi = 0;
+    sndcp_data->cur_pdu_ref[nsapi].ref_npdu_num = 0;
+    sndcp_data->cur_pdu_ref[nsapi].ref_seg_num = 0;
+    sndcp_data->big_head[nsapi] = FALSE;
+  }
+
+
+  sndcp_data->mg.mod_expects = MG_MOD_X_NONE;
+  sndcp_data->mg.waiting_nsapis = 0;
+  sndcp_data->mg.suspended_nsapis = 0;
+
+} /* mg_init() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_is_ack
++------------------------------------------------------------------------------
+| Description : This procedure takes the snsm_qos!rely
+|               information:
+|
+| 0 SNSM_RELCLASS_SUB Subscribed reliability class
+| 1 SNSM_GTP_LLC_RLC_PROT Acknowledged GTP, LLC, and RLC; Protected data
+| 2 SNSM_LLC_RLC_PROT Unacknowledged GTP; Acknowledged LLC and RLC, Protected data
+| 3 SNSM_RLC_PROT Unacknowledged GTP and LLC; Acknowledged RLC, Protected data
+| 4 SNSM_PROT Unacknowledged GTP, LLC, and RLC, Protected data
+| 5 SNSM_NO_REL Unacknowledged GTP, LLC, and RLC, Unprotected data
+|
+| and sets "spec" to TRUE, "b" to TRUE in case of SNSM_GTP_LLC_RLC_PROT or
+| SNSM_LLC_RLC_PROT,
+| [should be, is not:["spec" to FALSE in case of SNSM_RELCLASS_SUB]] and "spec"
+| to TRUE, "b" to FALSE else.
+|
+| Important note: in case of SNSM_RELCLASS_SUB "spec" will actually be set to
+| to TRUE, "b" to FALSE, to be robust in case of downlink protocol error!
+|
+| Parameters  : snsm_qos
+|                       BOOL* spec (FALSE for REL_CLASS_SUB),
+|                       BOOL* b)
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_is_ack (T_snsm_qos snsm_qos,
+                       BOOL* spec,
+                       BOOL* b)
+{
+  TRACE_FUNCTION( "mg_is_ack" );
+
+
+#ifdef SNDCP_UPM_INCLUDED 
+  if (snsm_qos.relclass ==  PS_GTP_LLC_RLC_PROT ||
+    snsm_qos.relclass == PS_LLC_RLC_PROT) {
+#else
+  if (snsm_qos.relclass ==  SNSM_GTP_LLC_RLC_PROT ||
+    snsm_qos.relclass == SNSM_LLC_RLC_PROT) {
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+    *spec = TRUE;
+    *b = TRUE;
+   /*  } else if (snsm_qos.relclass == SNSM_RELCLASS_SUB) {
+    *spec = FALSE;
+    */
+  } else {
+    *spec = TRUE;
+    *b = FALSE;
+  }
+
+
+} /* mg_is_ack() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_no_col_no_re
++------------------------------------------------------------------------------
+| Description : The function mg_no_col_no_re represents  the SDL label
+|               NO_COL_NO_RE: an LL_ESTABLISH_IND has been received, we do not
+|               have a collision situation like given in [GSM 4.65, 6.2.1.4],
+|               we do not have a re-establishment situation.
+|
+| Parameters  : the received LL_ESTABLISH_IND
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_no_col_no_re (T_LL_ESTABLISH_IND* ll_establish_ind)
+{
+  UBYTE dec_ret = 0;
+  UBYTE check_ret = 0;
+  UBYTE sapi_index = 0;
+  U8 nsapi = 0;
+  TRACE_FUNCTION( "mg_no_col_no_re" );
+  sndcp_get_sapi_index(ll_establish_ind->sapi, &sapi_index);
+
+  TRACE_EVENT_P3("l3_valid?: %d, N201_I: %d, N201_U: %d", 
+                  ll_establish_ind->xid_valid, ll_establish_ind->n201_i, 
+                  ll_establish_ind->n201_u);
+  /*
+   * Set N201 values in uplink services.
+   */
+  sig_mg_su_n201(ll_establish_ind->sapi, ll_establish_ind->n201_u);
+  sig_mg_sua_n201(ll_establish_ind->sapi, ll_establish_ind->n201_i);
+  /*
+   * If SNDCP XID block is not valid, we are ready.
+   */
+  if (ll_establish_ind->xid_valid == LL_XID_INVALID) {
+
+    PALLOC_SDU (ll_establish_res, LL_ESTABLISH_RES, 0);
+    /*
+     * Set sapi in ll_establish_res.
+     */
+    ll_establish_res->sapi = ll_establish_ind->sapi;
+    ll_establish_res->xid_valid = ll_establish_ind->xid_valid;
+    ll_establish_res->sdu.l_buf = 0;
+
+    /*
+     * Mark the affected sapi as MG_XID_IDLE.
+     */
+    sndcp_unset_sapi_state(ll_establish_ind->sapi, MG_EST);
+
+    sig_mg_sda_end_est(ll_establish_res->sapi, TRUE);
+
+    sndcp_set_sapi_ack(ll_establish_res->sapi, TRUE);
+
+    PSEND(hCommLLC, ll_establish_res);
+
+    /*
+     * All nsapis at this sapi that use ack mode, enter recovery state.
+     */
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+      UBYTE sapi = 0;
+      BOOL ack = FALSE;
+
+      sndcp_get_nsapi_sapi(nsapi, &sapi);
+      sndcp_get_nsapi_ack(nsapi, &ack);
+      if (ack && (sapi == ll_establish_ind->sapi)) {
+        sig_mg_cia_delete_npdus(nsapi);
+        sig_mg_sua_delete_pdus(nsapi, sapi, FALSE);
+        sig_mg_nu_recover(nsapi);
+        sig_mg_nd_recover(nsapi);
+      }
+    } /* for all nsapis */
+
+    return;
+  }
+  /*
+   * SNDCP XID block is valid and checked now.
+   */
+  mg_decode_xid(&(ll_establish_ind->sdu),
+                &(sndcp_data->mg.ind_xid_block[sapi_index]),
+                &dec_ret,
+                ll_establish_ind->sapi);
+  if (dec_ret == MG_XID_OK) {
+    mg_check_ind_xid(&check_ret, ll_establish_ind->sapi);
+    if (check_ret == MG_XID_OK) {
+      /*
+       * Label MG_IND_OK_EST
+       */
+      USHORT res_sdu_bit_len = 0;
+      UBYTE ntt = 0;
+      BOOL v42_rej = FALSE;
+      BOOL vj_rej = FALSE;
+
+      mg_set_res_cur_xid_block(ll_establish_ind->sapi, &res_sdu_bit_len);
+      /*
+       * Add the extra space for ntts with nsapis == 0.
+       */
+      for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+        BOOL rej = FALSE;
+        mg_get_sapi_dntt_rej(ll_establish_ind->sapi, ntt, &rej);
+        if (rej) {
+          /*
+           * length of ntt octet and nsapis.
+           */
+          res_sdu_bit_len += 32;
+          v42_rej = TRUE;
+        }
+        mg_get_sapi_pntt_rej(ll_establish_ind->sapi, ntt, &rej);
+        if (rej) {
+          /*
+           * length of ntt octet and nsapis.
+           */
+          res_sdu_bit_len += 32;
+          vj_rej = TRUE;
+        }
+      }
+      if (! sndcp_data->mg.res_xid_block[sapi_index].v42.is_set &&
+          v42_rej) {
+        /*
+         * Add length of parameter type and length.
+         */
+        res_sdu_bit_len += 16;
+      }
+      if (! sndcp_data->mg.res_xid_block[sapi_index].vj.is_set &&
+          vj_rej) {
+        /*
+         * Add length of parameter type and length.
+         */
+        res_sdu_bit_len += 16;
+      }
+
+      /*
+       * SDL Label MG_CNF_OK_ACK
+       */
+
+      {
+
+        USHORT sapi_state = MG_IDLE;
+
+        PALLOC_SDU (ll_establish_res, LL_ESTABLISH_RES, res_sdu_bit_len);
+        /*
+         * Set sapi in ll_establish_res.
+         */
+        ll_establish_res->sapi = ll_establish_ind->sapi;
+        ll_establish_res->xid_valid = ll_establish_ind->xid_valid;
+        /*
+         * Write res_xid_block struct to sdu byte buffer. Implementation dep..
+         */
+        mg_set_res_xid_params(&ll_establish_res->sdu, ll_establish_res->sapi);
+
+        /*
+         * Mark the affected nsapis and sapi as MG_XID_IDLE.
+         */
+        sndcp_unset_sapi_state(ll_establish_ind->sapi, MG_XID);
+        sndcp_unset_sapi_state(ll_establish_ind->sapi, MG_EST);
+
+        sig_mg_sda_end_est(ll_establish_res->sapi, TRUE);
+
+        sndcp_set_sapi_ack(ll_establish_res->sapi, TRUE);
+
+        PSEND(hCommLLC, ll_establish_res);
+
+        /*
+         * All nsapis at this sapi that use ack mode, enter recovery state.
+         */
+        for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+          UBYTE sapi = 0;
+          BOOL ack = FALSE;
+
+          sndcp_get_nsapi_sapi(nsapi, &sapi);
+          sndcp_get_nsapi_ack(nsapi, &ack);
+          if (ack && (sapi == ll_establish_ind->sapi)) {
+            sig_mg_cia_delete_npdus(nsapi);
+            sig_mg_sua_delete_pdus(nsapi, sapi, FALSE);
+            sig_mg_nu_recover(nsapi);
+            sig_mg_nd_recover(nsapi);
+          }
+        } /* for all nsapis */
+
+        /*
+         * Reset nsapis or ntts that were assigned, but are not any more.
+         */
+        mg_clean_xid(ll_establish_ind->sapi);
+        /*
+         * If there was a collision and xid has not been negotiated
+         * sufficiently.
+         */
+        mg_resend_xid_if_nec(ll_establish_ind->sapi);
+
+        /*
+         * If nsapi has been in state xid_pending or est_pending then
+         * an snsm_activate_res will be sent now.!!!
+         */
+        mg_respond_if_nec(ll_establish_ind->sapi);
+        sndcp_get_sapi_state(ll_establish_ind->sapi, &sapi_state);
+        if ((sapi_state & MG_XID) == 0) {
+          mg_xid_cnf_ok_res(ll_establish_ind->sapi);
+        }
+
+
+      }
+
+    } else {
+      /*
+       * not (check_ret == MG_IND_XID_OK)
+       */
+      /*
+       * Label MG_CHECK_FAIL_EST
+       */
+      USHORT res_sdu_bit_len = 0;
+      UBYTE ntt = 0;
+      BOOL v42_rej = FALSE;
+      BOOL vj_rej = FALSE;
+      /*
+       * Add the extra space for ntts with nsapis == 0.
+       */
+      for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+        BOOL rej = FALSE;
+        mg_get_sapi_dntt_rej(ll_establish_ind->sapi, ntt, &rej);
+        if (rej) {
+          /*
+           * length of ntt octet and nsapis.
+           */
+          res_sdu_bit_len += 32;
+          v42_rej = TRUE;
+        }
+        mg_get_sapi_pntt_rej(ll_establish_ind->sapi, ntt, &rej);
+        if (rej) {
+          /*
+           * length of ntt octet and nsapis.
+           */
+          res_sdu_bit_len += 32;
+          vj_rej = TRUE;
+        }
+      }
+      if (v42_rej) {
+        /*
+         * Add length of parameter type and length.
+         */
+        res_sdu_bit_len += 16;
+      }
+      if (vj_rej) {
+        /*
+         * Add length of parameter type and length.
+         */
+        res_sdu_bit_len += 16;
+      }
+      /*
+       * Allocate response and send it.
+       */
+      {
+
+        PALLOC_SDU (ll_establish_res, LL_ESTABLISH_RES, res_sdu_bit_len);
+        /*
+         * Reset res_xid_block, ind_xid_block.
+         */
+        sndcp_reset_xid_block(&sndcp_data->mg.res_xid_block[sapi_index]);
+        sndcp_reset_xid_block(&sndcp_data->mg.ind_xid_block[sapi_index]);
+        /*
+         * Set sapi in ll_establish_res.
+         */
+        ll_establish_res->sapi = ll_establish_ind->sapi;
+        ll_establish_res->xid_valid = ll_establish_ind->xid_valid;
+        /*
+         * Write res_xid_block struct to sdu byte buffer. Implementation dep..
+         */
+        mg_set_res_xid_params(&ll_establish_res->sdu, ll_establish_ind->sapi);
+        /*
+         * Modify the affected sapi state.
+         */
+        sndcp_unset_sapi_state(ll_establish_ind->sapi, MG_XID);
+        sndcp_unset_sapi_state(ll_establish_ind->sapi, MG_EST);
+
+        sndcp_set_sapi_ack(ll_establish_res->sapi, TRUE);
+        /*
+         * Send the XID block to LLC.
+         */
+        PSEND(hCommLLC, ll_establish_res);
+                /*
+         * All nsapis at this sapi that use ack mode, enter recovery state.
+         */
+        for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi ++) {
+          UBYTE sapi = 0;
+          BOOL ack = FALSE;
+
+          sndcp_get_nsapi_sapi(nsapi, &sapi);
+          sndcp_get_nsapi_ack(nsapi, &ack);
+          if (ack && (sapi == ll_establish_ind->sapi)) {
+            sig_mg_cia_delete_npdus(nsapi);
+            sig_mg_sua_delete_pdus(nsapi, sapi, FALSE);
+            sig_mg_nu_recover(nsapi);
+            sig_mg_nd_recover(nsapi);
+          }
+        } /* for all nsapis */
+
+      }
+
+      /*
+       * Reset nsapis or ntts that were assigned before
+       * but are not anymore.
+       */
+      sndcp_reset_xid_block(&sndcp_data->mg.cur_xid_block[sapi_index]);
+      mg_clean_xid(ll_establish_ind->sapi);
+      /*
+       * Allocate status req and send it  (label MG_SEND_STATUS_REQ_EST).
+       */
+      {
+#ifdef SNDCP_UPM_INCLUDED 
+        PALLOC (snsm_status_req, SN_STATUS_IND);
+#else
+        PALLOC (snsm_status_req, SNSM_STATUS_REQ);
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+        snsm_status_req->sapi = ll_establish_ind->sapi;
+#ifdef SNDCP_UPM_INCLUDED 
+        snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_sndcp;
+        snsm_status_req->ps_cause.value.sn_cause = CAUSE_SN_INVALID_XID;
+        PSEND (hCommUPM, snsm_status_req);
+#else
+        snsm_status_req->status_cause = SNSM_RELCS_INVALID_XID;
+        PSEND (hCommSM, snsm_status_req);
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+      }
+    }
+  } else { /* not if (dec_ret == MG_XID_OK_EST) */
+    /*
+     * Reset nsapis or ntts that were assigned before
+     * but are not anymore.
+     */
+    sndcp_reset_xid_block(&sndcp_data->mg.cur_xid_block[sapi_index]);
+    mg_clean_xid(ll_establish_ind->sapi);
+    /*
+     * Decoding of ll_establish_ind failed (label MG_SEND_STATUS_REQ).
+     * Allocate status req and send it.
+     */
+
+    {
+#ifdef SNDCP_UPM_INCLUDED 
+      PALLOC (snsm_status_req, SN_STATUS_IND);
+      snsm_status_req->sapi = ll_establish_ind->sapi;
+      snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_sndcp;
+      snsm_status_req->ps_cause.value.sn_cause = CAUSE_SN_INVALID_XID;
+      PSEND (hCommUPM, snsm_status_req);
+#else
+      PALLOC (snsm_status_req, SNSM_STATUS_REQ);
+      snsm_status_req->sapi = ll_establish_ind->sapi;
+      snsm_status_req->status_cause = SNSM_RELCS_INVALID_XID;
+      PSEND (hCommSM, snsm_status_req);
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    }
+
+  }
+
+} /* mg_no_col_no_re() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_no_col_re
++------------------------------------------------------------------------------
+| Description : The function mg_no_col_no_re represents  the SDL label
+|               NO_COL_RE: an LL_ESTABLISH_IND has been received, we do not
+|               have a collision situation like given in [GSM 4.65, 6.2.1.4],
+|               we do have a re-establishment situation.
+|
+| Parameters  : the received LL_ESTABLISH_IND
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_no_col_re (T_LL_ESTABLISH_IND* ll_establish_ind)
+{
+
+  TRACE_FUNCTION( "mg_no_col_re" );
+  /*
+   * Do the same things as without collision.
+   */
+  mg_no_col_no_re (ll_establish_ind);
+
+} /* mg_no_col_re() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_re_negotiate
++------------------------------------------------------------------------------
+| Description : The answer to the sent LL_XID_REQ has been invalid
+| (bad format or content). If service var renego < MG_MAX_RENEGO then
+| same LL_XID_REQ is resent, else SNSM_STATUS_REQ is sent.
+| This function represents the SDl label MG_RE_NEGOTIATE.
+|
+| Parameters  : the affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_re_negotiate (UBYTE sapi) {
+  UBYTE sapi_index = 0;
+
+  TRACE_FUNCTION( "mg_re_negotiate" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+
+  /*
+   * If number of re-negotiations is reached, deactivate all pdp contexts for
+   * the affected sapi.
+   */
+  if (sndcp_data->mg.renego[sapi_index] < MG_MAX_RENEGO) {
+    PALLOC_SDU(ll_xid_req, LL_XID_REQ, SNDCP_XID_BLOCK_BIT_LEN);
+    /*
+     * Set sapi in ll_xid_req.
+     */
+    ll_xid_req->sapi = sapi;
+
+    /*
+     * Fill the XID block. Implementation dependent.
+     */
+    mg_set_xid_params(ll_xid_req->sapi,
+                      &ll_xid_req->sdu,
+                      sndcp_data->mg.req_xid_block[sapi_index]);
+    /*
+     * Send the XID block to LLC.
+     */
+
+    sndcp_unset_sapi_state(sapi, MG_XID_NEC);
+    sndcp_set_sapi_state(ll_xid_req->sapi, MG_XID);
+    PSEND(hCommLLC, ll_xid_req);
+    /*
+     * Increment renegotiation counter.
+     */
+    sndcp_data->mg.renego[sapi_index]++;
+  } else {
+
+#ifdef SNDCP_UPM_INCLUDED 
+    PALLOC (snsm_status_req, SN_STATUS_IND);
+#else
+    PALLOC (snsm_status_req, SNSM_STATUS_REQ);
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    /*
+     * Set all ntts and dcomp/pcomp states to "unassigned".
+     */
+    mg_reset_states_n_rej(sapi_index);
+    /*
+     * Set prim parameters.
+     */
+#ifdef SNDCP_UPM_INCLUDED 
+    snsm_status_req->sapi = sapi;
+    snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_sndcp;
+    snsm_status_req->ps_cause.value.sn_cause = CAUSE_SN_INVALID_XID;
+#else
+    snsm_status_req->sapi = sapi;
+    snsm_status_req->status_cause = SNSM_RELCS_INVALID_XID;
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+
+    sndcp_data->mg.renego[sapi_index] = 0;
+    /*
+     * Reset cur_xid_block.
+     */
+    sndcp_reset_xid_block(&sndcp_data->mg.cur_xid_block[sapi_index]);
+    /*
+     * Reset all compression entities for the affected sapi.
+     */
+    mg_clean_xid(sapi);
+
+#ifdef SNDCP_UPM_INCLUDED 
+    PSEND (hCommUPM, snsm_status_req);
+#else
+    PSEND (hCommSM, snsm_status_req);
+#endif 
+  }
+
+
+} /* mg_re_negotiate() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_re_negotiate_ack
++------------------------------------------------------------------------------
+| Description : The answer to the sent LL_ESTABLISH_REQ has been invalid
+| (bad format or content). If service var renego < MG_MAX_RENEGO then
+| same LL_ESTABLISH_REQ is resent, else SNSM_STATUS_REQ is sent.
+| This function represents the SDl label MG_RE_NEGOTIATE_ACK.
+|
+| Parameters  : the affected sapi, cause
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_re_negotiate_ack (UBYTE sapi, U16 cause) {
+  UBYTE sapi_index = 0;
+
+  TRACE_FUNCTION( "mg_re_negotiate_ack" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+
+  /*
+   * If number of re-negotiations is reached, deactivate all pdp contexts for
+   * the affected sapi.
+   */
+  if (sndcp_data->mg.renego[sapi_index] < MG_MAX_RENEGO) {
+    PALLOC_SDU(ll_establish_req,
+               LL_ESTABLISH_REQ,
+               SNDCP_XID_BLOCK_BIT_LEN);
+    /*
+     * Set sapi in ll_establish_req.
+     */
+    ll_establish_req->sapi = sapi;
+
+    /*
+     * Fill the XID block. Implementation dependent.
+     */
+    mg_set_xid_params(ll_establish_req->sapi,
+                      &ll_establish_req->sdu,
+                      sndcp_data->mg.req_xid_block[sapi_index]);
+    /*
+     * Send the XID block to LLC, with establish request.
+     */
+    sig_mg_sda_start_est(sapi);
+
+    PSEND(hCommLLC, ll_establish_req);
+    /*
+     * Increment renegotiation counter.
+     */
+    sndcp_data->mg.renego[sapi_index]++;
+  } else {
+
+#ifdef SNDCP_UPM_INCLUDED
+    PALLOC (snsm_status_req, SN_STATUS_IND);
+#else
+    PALLOC (snsm_status_req, SNSM_STATUS_REQ);
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    /*
+     * Service sda may now leave state SDA_ESTABLISH_REQUESTED.
+     */
+    sig_mg_sda_end_est(sapi, FALSE);
+    /*
+     * Set all ntts and dcomp/pcomp states to "unassigned".
+     */
+    mg_reset_states_n_rej(sapi_index);
+    /*
+     * Set prim parameters.
+     */
+#ifdef SNDCP_UPM_INCLUDED 
+    snsm_status_req->sapi = sapi;
+    snsm_status_req->ps_cause.ctrl_value = CAUSE_is_from_sndcp;
+#else
+    snsm_status_req->sapi = sapi;
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+
+    sndcp_data->mg.renego[sapi_index] = 0;
+    /*
+     * Reset cur_xid_block.
+     */
+    sndcp_reset_xid_block(&sndcp_data->mg.cur_xid_block[sapi_index]);
+    sndcp_reset_xid_block(&sndcp_data->mg.req_xid_block[sapi_index]);
+    /*
+     * Reset all compression entities for the affected sapi.
+     */
+    mg_clean_xid(sapi);
+    /*
+     * The renegotiation is failed. If the cause is NO_PEER_RESPONSE
+     * or DM_RECEIVED, set it to RELCS_NORMAL to make SM deactivate
+     * PDP context. Otherwise the cause is forwarded to SM and the SM
+     * will deactivate PDP context depending on cause.
+     */
+#ifdef SNDCP_UPM_INCLUDED 
+    if((cause == CAUSE_SN_NO_PEER_RESPONSE) ||
+       (cause == CAUSE_SN_DM_RECEIVED) ){
+      snsm_status_req->ps_cause.value.sn_cause = CAUSE_SN_NORMAL_RELEASE;
+#else /* SNDCP_UPM_INCLUDED */    
+#ifdef _SNDCP_DTI_2_
+    if((cause == LL_RELCS_NO_PEER_RES) ||
+       (cause == LL_RELCS_DM_RECEIVED) ){
+      snsm_status_req->ps_cause.value.sn_cause = LL_RELCS_NORMAL;
+#else
+    if((cause == CAUSE_SN_NO_PEER_RESPONSE) ||
+       (cause == CAUSE_SN_DM_RECEIVED) ){
+      snsm_status_req->ps_cause.value.sn_cause = CAUSE_SN_NORMAL_RELEASE;
+#endif 
+#endif  /* SNDCP_UPM_INCLUDED */
+      sig_mg_su_resume(sapi);
+      sig_mg_sua_resume(sapi);
+      mg_resume_affected_nus(sapi);
+      sndcp_unset_sapi_state (sapi, MG_EST);
+    } else {
+#ifdef SNDCP_UPM_INCLUDED 
+      snsm_status_req->ps_cause.value.sn_cause = cause;
+#else      
+      snsm_status_req->status_cause = cause;
+#endif 
+    }
+	
+#ifdef SNDCP_UPM_INCLUDED 
+    PSEND (hCommUPM, snsm_status_req);
+#else
+    PSEND (hCommSM, snsm_status_req);
+#endif 
+
+  }
+
+} /* mg_re_negotiate_ack() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_resend_xid_if_nec
++------------------------------------------------------------------------------
+| Description : This procedure will be called after reception and computation
+| of an LL_XID_IND or LL_ESTABLISH_IND in case of a collision
+| or after receiving LL_XID_CNF or LL_ESTABLISH_CNF and does the
+| following:
+| (GSM 04.65 version 6.5.1 Release 1997), 6.2.1.4:
+| If the
+| LL-ESTABLISH.request or LL-XID.request contains one or more XID parameters,
+| or one or more compression fields
+| in an XID parameter, or one or more parameters in a compression field,
+| that are not negotiated as part of the collision
+| resolution, then negotiation of these XID parameters shall be performed at
+| the earliest opportunity after conclusion of
+| the collision resolution.
+|
+| Parameters  : Affected sapi, out: was LL_XID_REQ sent?
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_resend_xid_if_nec (UBYTE sapi) {
+  UBYTE sapi_index = 0;
+  BOOL resend_necessary = FALSE;
+  USHORT sapi_state = MG_IDLE;
+  T_XID_BLOCK* req_xid_block = NULL;
+  T_XID_BLOCK* cur_xid_block = NULL;
+  T_XID_BLOCK* new_xid_block = NULL;
+
+  TRACE_FUNCTION( "mg_resend_xid_if_nec" );
+
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  req_xid_block = &sndcp_data->mg.req_xid_block[sapi_index];
+  cur_xid_block = &sndcp_data->mg.cur_xid_block[sapi_index];
+  new_xid_block = &sndcp_data->mg.new_xid_block[sapi_index];
+
+  /*
+   * Data compression.
+   */
+  /*
+   * If a context is deactivated, maybe compressors must be switched off.
+   */
+  if (cur_xid_block->v42.is_set) {
+    USHORT nsapis = cur_xid_block->v42.nsapis;
+    UBYTE nsapi = 0;
+
+    /*
+     * XID renegotiation will only be necessary if one of the nsapis
+     * that are requested to use the data compression is in state
+     * MG_DEACT.
+     */
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if (((1 << nsapi) & nsapis) > 0) {
+        USHORT state = MG_IDLE;
+        sndcp_get_nsapi_state(nsapi, &state);
+        if ((state & MG_DEACT) > 0) {
+          UBYTE dntt = cur_xid_block->v42.ntt;
+          resend_necessary = TRUE;
+          mg_set_sapi_dntt_rej(sapi, dntt, TRUE);
+        }
+      }
+    }
+  }
+
+  if (req_xid_block->v42.is_set && ! cur_xid_block->v42.is_set) {
+    UBYTE sapi_index_local = 0;
+    BOOL used = FALSE;
+    /*
+     * If one instance of v42 is used at a different sapi,
+     * we may not use another one here.
+     */
+    for (sapi_index_local = 0;
+         sapi_index_local < SNDCP_NUMBER_OF_SAPIS;
+         sapi_index_local++) {
+
+      if (sndcp_data->mg.cur_xid_block[sapi_index_local].v42.is_set) {
+        used = TRUE;
+      }
+    }
+    if (! used) {
+      USHORT nsapis = req_xid_block->v42.nsapis;
+      UBYTE nsapi = 0;
+
+      /*
+       * XID renegotiation will only be necessary if one of the nsapis
+       * that are requested to use the data compression are not all in state
+       * MG_DEACT.
+       */
+      for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+        if (((1 << nsapi) & nsapis) > 0) {
+          USHORT state = MG_IDLE;
+          sndcp_get_nsapi_state(nsapi, &state);
+          if ((state & MG_DEACT) == 0) {
+            resend_necessary = TRUE;
+          }
+        }
+      }
+
+    }
+  }
+  /*
+   * Header compression.
+   */
+  /*
+   * If a context is deactivated, maybe compressors must be switched off.
+   */
+  if (cur_xid_block->vj.is_set) {
+    USHORT nsapis = cur_xid_block->vj.nsapis;
+    UBYTE nsapi = 0;
+
+    /*
+     * XID renegotiation will only be necessary if one of the nsapis
+     * that are requested to use the header compression is in state
+     * MG_DEACT.
+     */
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if (((1 << nsapi) & nsapis) > 0) {
+        USHORT state = MG_IDLE;
+        sndcp_get_nsapi_state(nsapi, &state);
+        if ((state & MG_DEACT) > 0) {
+          UBYTE pntt = cur_xid_block->vj.ntt;
+          resend_necessary = TRUE;
+          mg_set_sapi_pntt_rej(sapi, pntt, TRUE);
+        }
+      }
+    }
+
+  }
+  /*
+   * If a compressor is requested and not yet negotiated it must be requested
+   * now.
+   */
+  if (req_xid_block->vj.is_set && !cur_xid_block->vj.is_set) {
+    USHORT nsapis = req_xid_block->vj.nsapis;
+    UBYTE nsapi = 0;
+
+    req_xid_block->vj.p_bit = 1;
+
+    /*
+     * XID renegotiation will only be necessary if the affected nsapis
+     * is not currently being deactivated.
+     */
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if (((1 << nsapi) & nsapis) > 0) {
+        USHORT state = MG_IDLE;
+        sndcp_get_nsapi_state(nsapi, &state);
+        if ((state & MG_DEACT) == 0) {
+          resend_necessary = TRUE;
+        }
+      }
+    }
+
+  }
+
+  /*
+   * If in the meantime more compression has been requested,
+   * or compressors must be deactivated,
+   * re-negotiate.
+   */
+  if (new_xid_block->v42.is_set) {
+    if ((! req_xid_block->v42.is_set) ||
+        (req_xid_block->v42.is_set &&
+         (new_xid_block->v42.nsapis != req_xid_block->v42.nsapis))) {
+
+      *req_xid_block = *new_xid_block;
+      resend_necessary = TRUE;
+    }
+  }
+
+  /*
+   * If in the meantime more compression has been requested,
+   * or compressors must be deactivated,
+   * re-negotiate.
+   */
+  if (new_xid_block->vj.is_set) {
+    if ((! req_xid_block->vj.is_set) ||
+        (req_xid_block->vj.is_set &&
+         (new_xid_block->vj.nsapis != req_xid_block->vj.nsapis))) {
+
+      *req_xid_block = *new_xid_block;
+      resend_necessary = TRUE;
+    }
+  }
+
+
+  sndcp_get_sapi_state(sapi, &sapi_state);
+  /*
+   * If re-negotiation is necessary but not possible because MG_REL or
+   * MG_XID, set MG_XID_NEC.
+   */
+  if (resend_necessary
+      &&
+      ((sapi_state & (MG_REL + MG_XID)) > 0))
+  {
+    sndcp_set_sapi_state(sapi, MG_XID_NEC);
+    mg_set_cur_xid_block(sapi);
+    return;
+  }
+
+
+  /*
+   * If renegotiation of XID is necessary, send LL_XID_REQ.
+   */
+  if (! resend_necessary) {
+//    mg_set_cur_xid_block(sapi);
+    return;
+  }
+
+
+  /*
+   * Now req_xid_block is in good shape. Send it.
+   */
+  {
+    PALLOC_SDU(ll_xid_req, LL_XID_REQ, SNDCP_XID_BLOCK_BIT_LEN);
+    /*
+     * Set sapi in ll_xid_req.
+     */
+    ll_xid_req->sapi = sapi;
+    /*
+     * Write data from snsm_activate_ind to service variable req_xid_block.
+     */
+    mg_set_ntt_comp(sapi);
+    /*
+     * Fill the XID block. Implementation dependent.
+     */
+    mg_set_xid_params(ll_xid_req->sapi,
+                      &ll_xid_req->sdu,
+                      sndcp_data->mg.req_xid_block[sapi_index]);
+    /*
+     * Mark the affected sapi as MG_XID.
+     */
+    sndcp_set_sapi_state(sapi, MG_XID);
+    sndcp_unset_sapi_state(sapi, MG_XID_NEC);
+
+    /*
+     * Uplink data transfer on SAPI is completely suspended.
+     */
+    sig_mg_su_suspend(sapi);
+    sig_mg_sua_suspend(sapi);
+    mg_suspend_affected_nus(sapi);
+    /*
+     * Send the XID block to LLC.
+     */
+
+    sndcp_unset_sapi_state(sapi, MG_XID_NEC);
+    sndcp_set_sapi_state(ll_xid_req->sapi, MG_XID);
+    PSEND(hCommLLC, ll_xid_req);
+  }
+
+} /* mg_resend_xid_if_nec() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_resume_affected_nus
++------------------------------------------------------------------------------
+| Description : Resumes all nu service instances affected by
+|               If nsapi is waiting for SNSM_SEQUENCE_IND, fct. returns.
+|
+| Parameters  : sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_resume_affected_nus (UBYTE sapi) {
+  UBYTE nsapi = 0;
+  TRACE_FUNCTION( "mg_resume_affected_nus" );
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    UBYTE local_sapi = 0;
+    sndcp_get_nsapi_sapi(nsapi, &local_sapi);
+    if (local_sapi == sapi) {
+      USHORT nsapi_state = 0;
+      sndcp_get_nsapi_state(nsapi, &nsapi_state);
+      if ((nsapi_state & MG_SEQ) > 0) {
+        return;
+      }
+      if (((1 << nsapi) & sndcp_data->mg.suspended_nsapis) > 0) {
+        sig_mg_nu_resume(nsapi);
+        sndcp_data->mg.suspended_nsapis &= (~ (ULONG)(1 << nsapi));
+      }
+    }
+  }
+} /* mg_resume_affected_nus() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_is_rel_comp_nec
++------------------------------------------------------------------------------
+| Description : This function will be called in course of the deactivation of
+|               the given nsapi. If the nsapi used a certain compressor,
+|               but has been the only one to do this, then with the
+|               compressor entity will also have to
+|               be deactivated and all affected
+|               arrays will be modified.
+| Parameters  : UBYTE nsapi -- the given nsapi
+|               BOOL* nec,  a compressor
+| Post        : An "mg_set_sapi_[p/d]ntt_rej(sapi, pntt, TRUE);" will be called
+|               for
+|               each entity to be released. Later this information may be used
+|               to build up the right xid negotiation.
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_is_rel_comp_nec (UBYTE nsapi, BOOL* nec)
+{
+  UBYTE dntt = 0;
+  UBYTE pntt = 0;
+  UBYTE sapi = 0;
+  UBYTE nsp = 0;
+
+  TRACE_FUNCTION( "mg_is_rel_comp_nec" );
+
+  sndcp_get_nsapi_sapi(nsapi, &sapi);
+
+
+  /*
+   * Which pntt is used?
+   */
+  for (pntt = 0; pntt < MG_MAX_ENTITIES; pntt++) {
+    UBYTE state = MG_UNASSIGNED;
+    BOOL used = FALSE;
+    BOOL another = FALSE;
+    BOOL rej_known = FALSE;
+    /*
+     * Is pntt already known to be deactivated?
+     */
+    mg_get_sapi_pntt_rej(sapi, pntt, &rej_known);
+    if (rej_known) {
+      *nec = TRUE;
+      continue;
+    }
+    /*
+     * Is ntt used?
+     */
+    mg_get_sapi_pntt_state(sapi, pntt, &state);
+    if (state == MG_UNASSIGNED) {
+      continue;
+    }
+    /*
+     * Does the given nsapi use it?
+     */
+    mg_get_sapi_pntt_nsapi(sapi, pntt, nsapi, &used);
+    if (! used) {
+      continue;
+    }
+    /*
+     * Is the given nsapi the only user?
+     */
+    for (nsp = 0; nsp < SNDCP_NUMBER_OF_NSAPIS; nsp++) {
+      mg_get_sapi_pntt_nsapi(sapi, pntt, nsp, &used);
+      if (used && nsapi != nsp) {
+        another = TRUE;
+      }
+    }
+    if (another) {
+      continue;
+    }
+    mg_set_sapi_pntt_rej(sapi, pntt, TRUE);
+    *nec = TRUE;
+  }
+
+  /*
+   * Which dntt is used?
+   */
+  for (dntt = 0; dntt < MG_MAX_ENTITIES; dntt++) {
+    UBYTE state = MG_UNASSIGNED;
+    BOOL used = FALSE;
+    BOOL another = FALSE;
+    BOOL rej_known = FALSE;
+    /*
+     * Is pntt already known to be deactivated?
+     */
+    mg_get_sapi_dntt_rej(sapi, dntt, &rej_known);
+    if (rej_known) {
+      *nec = TRUE;
+      continue;
+    }
+    /*
+     * Is ntt used?
+     */
+    mg_get_sapi_dntt_state(sapi, dntt, &state);
+    if (state == MG_UNASSIGNED) {
+      continue;
+    }
+    /*
+     * Does the given nsapi use it?
+     */
+    mg_get_sapi_dntt_nsapi(sapi, dntt, nsapi, &used);
+    if (! used) {
+      continue;
+    }
+    /*
+     * Is the given nsapi the only user?
+     */
+    for (nsp = 0; nsp < SNDCP_NUMBER_OF_NSAPIS; nsp++) {
+      mg_get_sapi_dntt_nsapi(sapi, dntt, nsp, &used);
+      if (used && nsapi != nsp) {
+        another = TRUE;
+      }
+    }
+    if (another) {
+      continue;
+    }
+
+    mg_set_sapi_dntt_rej(sapi, dntt, TRUE);
+    *nec = TRUE;
+  }
+
+} /* mg_is_rel_comp_nec() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_rel_nsapi_nec
++------------------------------------------------------------------------------
+| Description : The SAPI connected to this NSAPI shall release acknowledged LLC
+|               operation mode if the indicated NSAPI is the last one using
+|               acknowledged mode on this SAPI. If an LL_RELEASE_REQ is sent
+|               then the given NSAPI (the one in parameter!) shall enter state
+|               MG_REL and wait for an LL_RELEASE_CNF. If the affected
+|               NSAPI doesn't use ack mode then the procedure just returns.
+|               If the affected sapi does not use acknowledged LLC operation
+|               mode then the procedure just returns.
+|               If an LL_ESTABLISH_REQ or LL_XID_REQ for the affected sapi is
+|               pending, no LL_RELEASE_REQ primitive will be sent, but the
+|               flag MG_REL_NEC_LOC will be set.
+| Pre         : This procedure is called after receipt of an
+|               SNSM_DEACTIVATE_IND, so the "local" parameter in an
+|               LL_RELEASE_REQ will be set to LL_REL_LOCAL.
+|               The procedure will only be called if the given nsapi is
+|               currently using acknowledged LLC operation mode, so this
+|               does not have to be checked.
+| Parameters  : UBYTE nsapi -- the given nsapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_rel_nsapi_nec (UBYTE nsapi)
+{
+  UBYTE sapi = 0;
+  UBYTE npi = 0;
+  UBYTE spi = 0;
+  USHORT sapi_state = MG_IDLE;
+  /*
+   * Are there other contexts using acknowledged mode on the same SAPI?
+   */
+  BOOL another_ack = FALSE;
+  BOOL sack = FALSE;
+  TRACE_FUNCTION( "mg_rel_nsapi_nec" );
+  /*
+   * Which SAPI is connected to the given NSAPI?
+   */
+  sndcp_get_nsapi_sapi(nsapi, &sapi);
+  sndcp_get_sapi_ack(sapi, &sack);
+  sndcp_get_sapi_state(sapi, &sapi_state);
+
+  if(!sack){
+    if ((sapi_state & MG_EST) != 0) {
+      sndcp_set_sapi_state(sapi, MG_REL_NEC_LOC);
+    }
+    return;
+  }
+  /*
+   * If release is pending, no need to send an other release.
+   */
+  if ((sapi_state & MG_REL) > 0) {
+    return;
+  }
+  /*
+   * Are there other contexts using acknowledged mode on the same SAPI?
+   */
+  for (npi = 0; npi < SNDCP_NUMBER_OF_NSAPIS; npi++) {
+    BOOL used = FALSE;
+    sndcp_is_nsapi_used(npi, &used);
+    if (!used) {
+      continue;
+    }
+    sndcp_get_nsapi_sapi(npi, &spi);
+    if (spi == sapi && npi != nsapi) {
+      BOOL is_ack = FALSE;
+      sndcp_get_nsapi_ack(npi, &is_ack);
+      if (is_ack) {
+        another_ack = TRUE;
+      }
+      break;
+    }
+  }
+  if (!another_ack) {
+
+    if (((sapi_state & MG_EST) == 0)
+        &&
+        ((sapi_state & MG_XID) == 0))
+    {
+      /*
+       * No LL_ESTABLISH_REQ or LL_XID_REQ pending.
+       * LL_RELEASE_REQ may be sent.
+       */
+
+      PALLOC(ll_release_req, LL_RELEASE_REQ);
+      ll_release_req->sapi = sapi;
+      /*
+       * Note: this is always set to TRUE because the preconditions include that
+       * this procedure has been called after an SNSM_DEACTIVATE_IND.
+       * If this precondition changes the local flag will have to be a parameter.
+       * (GSM 4.65, 6.2.2.2).
+       */
+      ll_release_req->local = TRUE;
+      /*
+       * Set the "state" for the affected sapi to MG_REL.
+       */
+      sndcp_set_sapi_state(sapi, MG_REL);
+      sndcp_unset_sapi_state(sapi, MG_EST);
+
+      PSEND(hCommLLC, ll_release_req);
+
+    } else {
+      /*
+       * LL_ESTABLISH_REQ or LL_XID_REQ pending.
+       * LL_RELEASE_REQ may not be sent.
+       */
+      sndcp_set_sapi_state(sapi, MG_REL_NEC_LOC);
+
+    }
+  } /* if (!another_ack)  */
+
+
+} /* mg_rel_nsapi_nec() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_send_empty_xid_req
++------------------------------------------------------------------------------
+| Description : This procedure sets the pending-states of the affected sapi
+|               and nsapi to MG_XID_PENDING and sends an LL_XID_REQ with
+|               the sapi from the given snsm_activate_ind and an empty XID
+|               block.
+|
+| Parameters  : the SNSM_ACTIVATE_IND
+|
++------------------------------------------------------------------------------
+*/
+#ifdef SNDCP_UPM_INCLUDED
+GLOBAL void mg_send_empty_xid_req (T_SN_ACTIVATE_REQ* snsm_activate_ind)
+#else
+GLOBAL void mg_send_empty_xid_req (T_SNSM_ACTIVATE_IND* snsm_activate_ind)
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+{
+  TRACE_FUNCTION( "mg_send_empty_xid_req" );
+  {
+    PALLOC_SDU(ll_xid_req, LL_XID_REQ, SNDCP_XID_BLOCK_BIT_LEN);
+    /*
+     * Set sapi in ll_xid_req.
+     */
+    ll_xid_req->sapi = snsm_activate_ind->sapi;
+    ll_xid_req->sdu.l_buf = 0;
+
+    /*
+     * Mark sapi as pending.
+     */
+    sndcp_set_sapi_state(snsm_activate_ind->sapi, MG_XID);
+    /*
+     * Send the XID block to LLC.
+     */
+
+    sndcp_unset_sapi_state(ll_xid_req->sapi, MG_XID_NEC);
+    sndcp_set_sapi_state(ll_xid_req->sapi, MG_XID);
+    PSEND(hCommLLC, ll_xid_req);
+  }
+} /* mg_send_xid_req() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_send_snsm_activate_res
++------------------------------------------------------------------------------
+| Description : Allocates prim, sets parameters and sends prim
+|
+| Parameters  : the affected nsapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_send_snsm_activate_res (UBYTE nsapi)
+{
+
+  TRACE_FUNCTION( "mg_send_snsm_activate_res" );
+  {
+    UBYTE sapi_index = 0;
+    UBYTE sapi = 0;
+
+#ifdef SNDCP_UPM_INCLUDED 
+    PALLOC(snsm_activate_res, SN_ACTIVATE_CNF);
+#else
+    PALLOC(snsm_activate_res, SNSM_ACTIVATE_RES); 
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+
+    sndcp_get_nsapi_sapi(nsapi, &sapi);
+    sndcp_get_sapi_index(sapi, &sapi_index);
+
+    snsm_activate_res->nsapi = nsapi;
+
+    /*
+     * If nsapi uses data compressor, set dcomp parameter
+     * in snsm_activate_res.
+     */
+    if (sndcp_data->mg.cur_xid_block[sapi_index].v42.is_set &&
+        ((sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis &
+         (1 << nsapi)) > 0)) {
+
+#ifdef SNDCP_UPM_INCLUDED 
+      snsm_activate_res->comp_params.dcomp = 
+        sndcp_data->mg.cur_xid_block[sapi_index].v42.p0;
+#else
+      snsm_activate_res->dcomp =
+        sndcp_data->mg.cur_xid_block[sapi_index].v42.p0; 
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    } else
+    {
+#ifdef SNDCP_UPM_INCLUDED 
+    snsm_activate_res->comp_params.dcomp = 0;
+#else
+    snsm_activate_res->dcomp = 0; 
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    } 
+
+    /*
+     * If nsapi uses header compressor, set hcomp parameter
+     * and msid field in snsm_activate_res.
+     */
+
+#ifdef SNDCP_UPM_INCLUDED 
+    if (sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set &&
+        ((sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis &
+         (1 << nsapi)) > 0)) {
+      snsm_activate_res->comp_params.msid = 
+        sndcp_data->mg.cur_xid_block[sapi_index].vj.s0_m_1 + 1;
+      /*
+       * How is that one negotiated?
+       * Missing in VJ XID block.
+       */
+      snsm_activate_res->comp_params.hcomp = 
+        sndcp_data->mg.cur_xid_block[sapi_index].vj.direction;
+    } else {
+      snsm_activate_res->comp_params.hcomp = 0;
+      snsm_activate_res->comp_params.msid = 0;
+    }
+
+    PSEND(hCommUPM, snsm_activate_res);
+#else  /*#ifdef SNDCP_UPM_INCLUDED*/
+      if (sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set &&
+        ((sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis &
+         (1 << nsapi)) > 0)) {
+      snsm_activate_res->msid =
+        sndcp_data->mg.cur_xid_block[sapi_index].vj.s0_m_1 + 1; 
+      /*
+       * How is that one negotiated?
+       * Missing in VJ XID block.
+       */
+      snsm_activate_res->hcomp =
+        sndcp_data->mg.cur_xid_block[sapi_index].vj.direction;
+    } else {
+      snsm_activate_res->hcomp = 0;
+      snsm_activate_res->msid = 0;
+    }
+    PSEND(hCommSM, snsm_activate_res); 
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+}
+  } /* mg_send_snsm_activate_res() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_send_xid_req
++------------------------------------------------------------------------------
+| Description : This procedure sets the pending-states of the affected sapi
+|               and nsapi to MG_XID_PENDING and sends an LL_XID_REQ with
+|               parameters set according to the compression informations in
+|               the given snsm_activate_ind and according to constants that
+|               determine the capabilities of the data compression entity.
+|               The part of this procedure that deals with the constant
+|               compressor capabilities is implementation dependent.
+|
+| Parameters  : the SNSM_ACTIVATE_IND
+|
++------------------------------------------------------------------------------
+*/
+#ifdef SNDCP_UPM_INCLUDED 
+GLOBAL void mg_send_xid_req (T_SN_ACTIVATE_REQ* snsm_activate_ind)
+#else
+GLOBAL void mg_send_xid_req (T_SNSM_ACTIVATE_IND* snsm_activate_ind)
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+{
+  UBYTE sapi_index = 0;
+  TRACE_FUNCTION( "mg_send_xid_req" );
+  sndcp_get_sapi_index(snsm_activate_ind->sapi, &sapi_index);
+  {
+    PALLOC_SDU(ll_xid_req, LL_XID_REQ, SNDCP_XID_BLOCK_BIT_LEN);
+    /*
+     * Set sapi in ll_xid_req.
+     */
+    ll_xid_req->sapi = snsm_activate_ind->sapi;
+    /*
+     * Write data from snsm_activate_ind to service variable req_xid_block.
+     */
+
+    mg_set_req_xid_block(snsm_activate_ind);
+    /*
+     * Fill the XID block. Implementation dependent.
+     */
+    mg_set_xid_params(ll_xid_req->sapi,
+                      &ll_xid_req->sdu,
+                      sndcp_data->mg.req_xid_block[sapi_index]);
+    /*
+     * Mark the affected sapi as xid pending
+     */
+
+    sndcp_set_sapi_state(snsm_activate_ind->sapi, MG_XID);
+
+    /*
+     * Trace xid block.
+     */
+#ifdef SNDCP_TRACE_ALL
+    TRACE_EVENT("outcoming xid block:");
+    sndcp_trace_sdu(&ll_xid_req->sdu);
+#endif
+    /*
+     * Send the XID block to LLC.
+     */
+
+    sndcp_unset_sapi_state(ll_xid_req->sapi, MG_XID_NEC);
+    sndcp_set_sapi_state(ll_xid_req->sapi, MG_XID);
+    PSEND(hCommLLC, ll_xid_req);
+  }
+} /* mg_send_xid_req() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_send_xid_req_del
++------------------------------------------------------------------------------
+| Description : If mg_get_sapi_pntt_rej() or mg_get_sapi_dntt_rej() indicate
+|               that compressors must be removed, this function will
+|               send an LL_XID_REQ which does this, or if an XID is pending,
+|               the information about the rejected compressors will be stored
+|               to new_xid_block and the MG_XID_NEC will be set.
+|
+| Parameters  : the SNSM_ACTIVATE_IND
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_send_xid_req_del (UBYTE sapi)
+{
+  UBYTE sapi_index = 0;
+  UBYTE ntt = 0;
+  T_XID_BLOCK mt_xid_block;
+  /*
+   * Only length of parameter type 0.
+   */
+  USHORT res_sdu_bit_len = 24;
+  BOOL v42_rej = FALSE;
+  BOOL vj_rej = FALSE;
+
+  TRACE_FUNCTION( "mg_send_xid_req_del" );
+
+  sndcp_reset_xid_block(&mt_xid_block);
+
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  /*
+   * How long will xid_block be?
+   */
+  /*
+   * Add the extra space for ntts with nsapis == 0.
+   */
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    BOOL rej = FALSE;
+    mg_get_sapi_dntt_rej(sapi, ntt, &rej);
+    if (rej) {
+      /*
+       * length of ntt octet and nsapis.
+       */
+      res_sdu_bit_len += 32;
+      v42_rej = TRUE;
+      /*
+       * Change new_xid_block.
+       */
+      sndcp_data->mg.new_xid_block[sapi_index].v42.nsapis = 0;
+      sndcp_data->mg.new_xid_block[sapi_index].v42.nsapis_set = TRUE;
+      sndcp_data->mg.new_xid_block[sapi_index].v42.is_set = TRUE;
+    }
+
+    mg_get_sapi_pntt_rej(sapi, ntt, &rej);
+    if (rej) {
+      /*
+       * length of ntt octet and nsapis.
+       */
+      res_sdu_bit_len += 32;
+      vj_rej = TRUE;
+      /*
+       * Change req_xid_block.
+       */
+      sndcp_data->mg.new_xid_block[sapi_index].vj.nsapis = 0;
+      sndcp_data->mg.new_xid_block[sapi_index].vj.nsapis_set = TRUE;
+      sndcp_data->mg.new_xid_block[sapi_index].vj.is_set = TRUE;
+
+    }
+  }
+  if (v42_rej) {
+    /*
+     * Add length of parameter type and length.
+     */
+    res_sdu_bit_len += 16;
+  }
+  if (vj_rej) {
+    /*
+     * Add length of parameter type and length.
+     */
+    res_sdu_bit_len += 16;
+  }
+
+  if (v42_rej || vj_rej) {
+
+    USHORT state = MG_IDLE;
+
+    sndcp_get_sapi_state(sapi, &state);
+    if ((state & MG_XID) == 0) {
+
+      PALLOC_SDU(ll_xid_req, LL_XID_REQ, res_sdu_bit_len);
+
+      sndcp_data->mg.req_xid_block[sapi_index] =
+        sndcp_data->mg.new_xid_block[sapi_index];
+      /*
+       * Set sapi in ll_xid_req.
+       */
+      ll_xid_req->sapi = sapi;
+      /*
+       * Write data from snsm_activate_ind to service variable req_xid_block.
+       */
+      sndcp_reset_xid_block(&mt_xid_block);
+      sndcp_reset_xid_block(&sndcp_data->mg.new_xid_block[sapi_index]);
+      /*
+       * Fill the XID block. Implementation dependent.
+       */
+      mg_set_xid_params(ll_xid_req->sapi,
+                        &ll_xid_req->sdu,
+                        mt_xid_block);
+      /*
+       * Mark the affected sapi as MG_DEL_XID_PENDING.
+       */
+      sndcp_set_sapi_state(sapi, MG_XID);
+      /*
+       * Send the XID block to LLC.
+       */
+
+      sndcp_unset_sapi_state(sapi, MG_XID_NEC);
+      sndcp_set_sapi_state(ll_xid_req->sapi, MG_XID);
+      PSEND(hCommLLC, ll_xid_req);
+    } else {
+      sndcp_set_sapi_state(sapi, MG_XID_NEC);
+    }
+  }
+} /* mg_send_xid_req_del() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_cur_xid_block
++------------------------------------------------------------------------------
+| Description : This procedure sets the cur_xid_block service variable
+| according to the values given in req_xid_block and cnf_xid_block.
+| It also sets the unassigned, selected, assigned states of the affected
+| dcomp, pcomp, ntt.
+| The p bit in the req_xid_block is unset, if affected.
+| See GSM 4.65, 6.8.2.
+|
+| Parameters  : the affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_set_cur_xid_block (UBYTE sapi) {
+  UBYTE sapi_index = 0;
+  T_XID_BLOCK* cur_xid_block;
+  T_XID_BLOCK* req_xid_block;
+  T_XID_BLOCK* cnf_xid_block;
+  TRACE_FUNCTION( "mg_set_cur_xid_block" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  cur_xid_block = &sndcp_data->mg.cur_xid_block[sapi_index];
+  req_xid_block = &sndcp_data->mg.req_xid_block[sapi_index];
+  cnf_xid_block = &sndcp_data->mg.cnf_xid_block[sapi_index];
+  /*
+   * SNDCP version has been tested to be SNDCP_XID_VERSION.
+   */
+  cur_xid_block->version = SNDCP_XID_VERSION;
+
+  /*
+   * V42bis parameters.
+   */
+  if (req_xid_block->v42.is_set) {
+    cur_xid_block->v42.is_set = TRUE;
+    cur_xid_block->v42.ntt = req_xid_block->v42.ntt;
+    mg_set_sapi_dntt_state(sapi,
+                           req_xid_block->v42.ntt,
+                           MG_ASSIGNED);
+    req_xid_block->v42.p_bit = SNDCP_P_BIT_0;
+
+    /*
+     * Algorithm type and DCOMP are only set in req.
+     */
+    cur_xid_block->v42.algo_type = req_xid_block->v42.algo_type;
+    cur_xid_block->v42.dcomp = req_xid_block->v42.dcomp;
+    mg_set_sapi_dcomp_state(sapi,
+                            req_xid_block->v42.dcomp,
+                            MG_ASSIGNED);
+
+    if (cnf_xid_block->v42.is_set) {
+
+      if (cnf_xid_block->v42.nsapis_set) {
+        cur_xid_block->v42.nsapis = cnf_xid_block->v42.nsapis;
+        cur_xid_block->v42.nsapis_set = TRUE;
+      } else if (req_xid_block->v42.nsapis_set) {
+        cur_xid_block->v42.nsapis = req_xid_block->v42.nsapis;
+        cur_xid_block->v42.nsapis_set = TRUE;
+      }
+      if (cnf_xid_block->v42.p0_set) {
+        cur_xid_block->v42.p0 = cnf_xid_block->v42.p0;
+        cur_xid_block->v42.p0_set = TRUE;
+      } else if (req_xid_block->v42.p0_set) {
+        cur_xid_block->v42.p0 = req_xid_block->v42.p0;
+        cur_xid_block->v42.p0_set = TRUE;
+      }
+      if (cnf_xid_block->v42.p1_set) {
+        cur_xid_block->v42.p1 = cnf_xid_block->v42.p1;
+        cur_xid_block->v42.p1_set = TRUE;
+      } else if (req_xid_block->v42.p1_set) {
+        cur_xid_block->v42.p1 = req_xid_block->v42.p1;
+        cur_xid_block->v42.p1_set = TRUE;
+      }
+      if (cnf_xid_block->v42.p2_set) {
+        cur_xid_block->v42.p2 = cnf_xid_block->v42.p2;
+        cur_xid_block->v42.p2_set = TRUE;
+      } else if (req_xid_block->v42.p2_set) {
+        cur_xid_block->v42.p2 = req_xid_block->v42.p2;
+        cur_xid_block->v42.p2_set = TRUE;
+      }
+
+    } else {
+      /*
+       * NOT cnf_xid_block->v42.is_set.
+       */
+
+      if (req_xid_block->v42.nsapis_set) {
+        cur_xid_block->v42.nsapis = req_xid_block->v42.nsapis;
+        cur_xid_block->v42.nsapis_set = TRUE;
+      }
+      if (req_xid_block->v42.p0_set) {
+        cur_xid_block->v42.p0 = req_xid_block->v42.p0;
+        cur_xid_block->v42.p0_set = TRUE;
+      }
+      if (req_xid_block->v42.p1_set) {
+        cur_xid_block->v42.p1 = req_xid_block->v42.p1;
+        cur_xid_block->v42.p1_set = TRUE;
+      }
+      if (req_xid_block->v42.p2_set) {
+        cur_xid_block->v42.p2 = req_xid_block->v42.p2;
+        cur_xid_block->v42.p2_set = TRUE;
+      }
+
+    }
+  } else {
+    /*
+     * NOT req_xid_block->v42.is_set.
+     */
+    if (cnf_xid_block->v42.is_set) {
+
+      cur_xid_block->v42.is_set = TRUE;
+      if (cnf_xid_block->v42.nsapis_set) {
+        cur_xid_block->v42.nsapis = cnf_xid_block->v42.nsapis;
+        cur_xid_block->v42.nsapis_set = TRUE;
+      }
+      if (cnf_xid_block->v42.p0_set) {
+        cur_xid_block->v42.p0 = cnf_xid_block->v42.p0;
+        cur_xid_block->v42.p0_set = TRUE;
+      }
+      if (cnf_xid_block->v42.p1_set) {
+        cur_xid_block->v42.p1 = cnf_xid_block->v42.p1;
+        cur_xid_block->v42.p1_set = TRUE;
+      }
+      if (cnf_xid_block->v42.p2_set) {
+        cur_xid_block->v42.p2 = cnf_xid_block->v42.p2;
+        cur_xid_block->v42.p2_set = TRUE;
+      }
+
+    } else {
+      /*
+       * Req and cnf are not set, cur_xid_block keeps its values.
+       */
+    }
+  }
+
+
+  /*
+   * VJ parameters.
+   */
+  if (req_xid_block->vj.is_set) {
+    cur_xid_block->vj.is_set = TRUE;
+    cur_xid_block->vj.ntt = req_xid_block->vj.ntt;
+    mg_set_sapi_pntt_state(sapi,
+                           req_xid_block->vj.ntt,
+                           MG_ASSIGNED);
+    req_xid_block->vj.p_bit = SNDCP_P_BIT_0;
+    /*
+     * Algorithm type and PCOMPs are only set in req.
+     * The direction is only set in req.
+     */
+    cur_xid_block->vj.algo_type = req_xid_block->vj.algo_type;
+    cur_xid_block->vj.pcomp1 = req_xid_block->vj.pcomp1;
+    mg_set_sapi_pcomp_state(sapi,
+                            req_xid_block->vj.pcomp1,
+                            MG_ASSIGNED);
+    cur_xid_block->vj.pcomp2 = req_xid_block->vj.pcomp2;
+    mg_set_sapi_pcomp_state(sapi,
+                            req_xid_block->vj.pcomp2,
+                            MG_ASSIGNED);
+    cur_xid_block->vj.direction = req_xid_block->vj.direction;
+    if (cnf_xid_block->vj.is_set) {
+      if (cnf_xid_block->vj.nsapis_set) {
+        cur_xid_block->vj.nsapis = cnf_xid_block->vj.nsapis;
+        cur_xid_block->vj.nsapis_set = TRUE;
+      } else {
+        cur_xid_block->vj.nsapis = req_xid_block->vj.nsapis;
+        cur_xid_block->vj.nsapis_set = TRUE;
+      }
+      if (cnf_xid_block->vj.s0_m_1_set) {
+        cur_xid_block->vj.s0_m_1 = cnf_xid_block->vj.s0_m_1;
+        cur_xid_block->vj.s0_m_1_set = TRUE;
+      } else {
+        cur_xid_block->vj.s0_m_1 = req_xid_block->vj.s0_m_1;
+        cur_xid_block->vj.s0_m_1_set = TRUE;
+      }
+    } else {
+      if (req_xid_block->vj.nsapis_set) {
+        cur_xid_block->vj.nsapis = req_xid_block->vj.nsapis;
+        cur_xid_block->vj.nsapis_set = TRUE;
+      }
+      if (req_xid_block->vj.s0_m_1_set) {
+        cur_xid_block->vj.s0_m_1 = req_xid_block->vj.s0_m_1;
+        cur_xid_block->vj.s0_m_1_set = TRUE;
+      }
+    }
+  } else {
+    /*
+     * NOT req_xid_block->vj.es_set.
+     */
+    if (cnf_xid_block->vj.is_set) {
+      cur_xid_block->vj.is_set = TRUE;
+      if (cnf_xid_block->vj.nsapis_set) {
+        cur_xid_block->vj.nsapis = cnf_xid_block->vj.nsapis;
+        cur_xid_block->vj.nsapis_set = TRUE;
+      }
+      if (cnf_xid_block->vj.s0_m_1_set) {
+        cur_xid_block->vj.s0_m_1 = cnf_xid_block->vj.s0_m_1;
+        cur_xid_block->vj.s0_m_1_set = TRUE;
+      }
+    } else {
+      /*
+       * Req and cnf are not set, cur_xid_block keeps it's values.
+       */
+    }
+  }
+
+  /*
+   * If nsapis are 0, deactivate compressor.
+   */
+  if (cur_xid_block->v42.nsapis == 0 ||
+      cur_xid_block->v42.nsapis_set == FALSE) {
+
+    /*
+     * Find the affected compressor entity.
+     */
+    UBYTE dntt = 0;
+    mg_get_sapi_dcomp_dntt(sapi, req_xid_block->v42.dcomp, &dntt);
+
+    cur_xid_block->v42.is_set = FALSE;
+    mg_set_sapi_dcomp_state(sapi,
+                            req_xid_block->v42.dcomp,
+                            MG_UNASSIGNED);
+    mg_set_sapi_dntt_state(sapi,
+                           dntt,
+                           MG_UNASSIGNED);
+    /*
+     * One compressor less, something like sndcp_data->v42_count--;
+     * should come here!
+     */
+
+  }
+  if (cur_xid_block->vj.nsapis == 0 ||
+      cur_xid_block->vj.nsapis_set == FALSE) {
+
+    /*
+     * Find the affected compressor entity.
+     */
+    UBYTE pntt = 0;
+    mg_get_sapi_pcomp_pntt(sapi, req_xid_block->vj.pcomp1, &pntt);
+    mg_get_sapi_pcomp_pntt(sapi, req_xid_block->vj.pcomp2, &pntt);
+    cur_xid_block->vj.is_set = FALSE;
+    mg_set_sapi_pcomp_state(sapi,
+                            req_xid_block->vj.pcomp1,
+                            MG_UNASSIGNED);
+    mg_set_sapi_pcomp_state(sapi,
+                            req_xid_block->vj.pcomp2,
+                            MG_UNASSIGNED);
+    mg_set_sapi_pntt_state(sapi,
+                           pntt,
+                           MG_UNASSIGNED);
+    /*
+     * One compressor less.
+     */
+    if (sndcp_data->vj_count > 0) {
+      sndcp_data->vj_count--;
+    }
+  }
+
+
+  /*
+   * Send new block to service cia.
+   */
+  sig_mg_cia_new_xid(cur_xid_block);
+
+} /* mg_set_cur_xid_block() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_new_xid_block
++------------------------------------------------------------------------------
+| Description : This procedure reads data from the given snsm_activate_ind and
+|               from the already requested xid block and
+|               writes them to the service variable new_xid_block.
+|               When the pending establishment or xid negotiation is finished
+|               this new_xid_block will be newly evaluated.
+|
+| Parameters  :
+|               the new SNSM_ACTIVATE_IND
+|
++------------------------------------------------------------------------------
+*/
+#ifdef SNDCP_UPM_INCLUDED
+GLOBAL void mg_set_new_xid_block (T_SN_ACTIVATE_REQ* snsm_activate_ind)
+#else
+GLOBAL void mg_set_new_xid_block (T_SNSM_ACTIVATE_IND* snsm_activate_ind)
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+{
+  UBYTE sapi_index = 0;
+  TRACE_FUNCTION( "mg_set_new_xid_block" );
+  sndcp_get_sapi_index(snsm_activate_ind->sapi, &sapi_index);
+  /*
+   * Set the version number.
+   */
+  sndcp_data->mg.new_xid_block[sapi_index].version = SNDCP_XID_VERSION;
+  /*
+   * Set the V42.bis parameters,
+   */
+#ifdef TI_PS_FF_V42BIS
+  sndcp_data->mg.new_xid_block[sapi_index].v42.is_set =
+#ifdef SNDCP_UPM_INCLUDED
+    (snsm_activate_ind->comp_params.dcomp != NAS_DCOMP_NEITHER_DIRECT);
+#else
+    (snsm_activate_ind->dcomp != SNSM_COMP_NEITHER_DIRECT);
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p_bit = SNDCP_P_BIT_1;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.ntt = SNDCP_NTT_0;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.algo_type = SNDCP_XID_V42;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.dcomp = SNDCP_DCOMP1;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.nsapis =
+    1 << (snsm_activate_ind->nsapi);
+  sndcp_data->mg.new_xid_block[sapi_index].v42.nsapis_set = TRUE;
+#ifdef SNDCP_UPM_INCLUDED
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p0 = snsm_activate_ind->comp_params.dcomp;
+#else
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p0 = snsm_activate_ind->dcomp;
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p0_set = TRUE;
+
+  /*
+   * Set p1 and p2 to default values.
+   */
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p1 = SNDCP_V42_DEFAULT_P1;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p1_set = TRUE;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p2 =
+    SNDCP_V42_DEFAULT_P2;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p2_set = TRUE;
+
+  /*
+   * Set affected entities and dcomp/pcomp values.
+   */
+  mg_set_ntt_comp(snsm_activate_ind->sapi);
+
+#else /* !TI_PS_FF_V42BIS */
+
+
+  sndcp_data->mg.new_xid_block[sapi_index].v42.is_set = FALSE;
+
+  sndcp_data->mg.new_xid_block[sapi_index].v42.nsapis = 0;
+
+  sndcp_data->mg.new_xid_block[sapi_index].v42.nsapis_set = FALSE;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p0_set = FALSE;
+
+  /*
+   * Set p1 and p2 to default values.
+   */
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p1 = SNDCP_V42_DEFAULT_P1;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p1_set = TRUE;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p2 =
+    SNDCP_V42_DEFAULT_P2;
+  sndcp_data->mg.new_xid_block[sapi_index].v42.p2_set = TRUE;
+
+#endif /* TI_PS_FF_V42BIS */
+
+  /*
+   * Set the Van Jacobson parameters,
+   */
+  sndcp_data->mg.new_xid_block[sapi_index].vj.is_set =
+#ifdef SNDCP_UPM_INCLUDED 
+    (snsm_activate_ind->comp_params.hcomp != NAS_HCOMP_OFF) ||
+#else
+    (snsm_activate_ind->hcomp != SNSM_COMP_NEITHER_DIRECT) ||
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    sndcp_data->mg.new_xid_block[sapi_index].vj.is_set ||
+    sndcp_data->mg.req_xid_block[sapi_index].vj.is_set;
+
+  if (! sndcp_data->mg.req_xid_block[sapi_index].vj.is_set) {
+    sndcp_data->mg.new_xid_block[sapi_index].vj.p_bit = SNDCP_P_BIT_1;
+  } else {
+    sndcp_data->mg.new_xid_block[sapi_index].vj.p_bit = SNDCP_P_BIT_0;
+  }
+
+  sndcp_data->mg.new_xid_block[sapi_index].vj.ntt = SNDCP_NTT_0;
+  sndcp_data->mg.new_xid_block[sapi_index].vj.algo_type = SNDCP_XID_VJ;
+  sndcp_data->mg.new_xid_block[sapi_index].vj.pcomp1 = SNDCP_PCOMP1;
+  sndcp_data->mg.new_xid_block[sapi_index].vj.pcomp2 = SNDCP_PCOMP2;
+
+  sndcp_data->mg.new_xid_block[sapi_index].vj.nsapis |=
+    (sndcp_data->mg.req_xid_block[sapi_index].vj.nsapis |
+     1 << (snsm_activate_ind->nsapi));
+  sndcp_data->mg.new_xid_block[sapi_index].vj.nsapis_set = TRUE;
+  
+#ifdef SNDCP_UPM_INCLUDED
+  sndcp_data->mg.new_xid_block[sapi_index].vj.s0_m_1 = 
+    snsm_activate_ind->comp_params.msid - 1;
+#else
+  sndcp_data->mg.new_xid_block[sapi_index].vj.s0_m_1 =
+    snsm_activate_ind->msid - 1;
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+  sndcp_data->mg.new_xid_block[sapi_index].vj.s0_m_1_set = TRUE;
+  /*
+   * Only used internally, not in XID block.
+   * Not: it is assumed that the indicated values match the existing ones!
+   */
+#ifdef SNDCP_UPM_INCLUDED
+  sndcp_data->mg.new_xid_block[sapi_index].vj.direction = 
+    snsm_activate_ind->comp_params.hcomp;
+#else
+  sndcp_data->mg.new_xid_block[sapi_index].vj.direction = 
+    snsm_activate_ind->hcomp;
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+
+} /* mg_set_new_xid_block() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_req_xid_block
++------------------------------------------------------------------------------
+| Description : This procedure reads data from the given snsm_activate_ind and
+|               writes it to the service variable req_xid_block.
+|
+| Parameters  :
+|               the SNSM_ACTIVATE_IND that caused the negotiation.
+|
++------------------------------------------------------------------------------
+*/
+#ifdef SNDCP_UPM_INCLUDED
+GLOBAL void mg_set_req_xid_block (T_SN_ACTIVATE_REQ* snsm_activate_ind)
+#else
+GLOBAL void mg_set_req_xid_block (T_SNSM_ACTIVATE_IND* snsm_activate_ind)
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+{
+  UBYTE sapi_index = 0;
+  BOOL vio;
+  TRACE_FUNCTION( "mg_set_req_xid_block" );
+  sndcp_get_sapi_index(snsm_activate_ind->sapi, &sapi_index);
+  /*
+   * Set the version number.
+   */
+  sndcp_data->mg.req_xid_block[sapi_index].version = SNDCP_XID_VERSION;
+  /*
+   * Set the V42.bis parameters,
+   */
+#ifdef TI_PS_FF_V42BIS
+
+#ifdef SNDCP_UPM_INCLUDED
+    sndcp_data->mg.req_xid_block[sapi_index].v42.is_set =
+      (snsm_activate_ind->comp_params.dcomp != NAS_DCOMP_NEITHER_DIRECT);
+#else
+    sndcp_data->mg.req_xid_block[sapi_index].v42.is_set = 
+      (snsm_activate_ind->dcomp != SNSM_COMP_NEITHER_DIRECT);
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p_bit = SNDCP_P_BIT_1;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.ntt = SNDCP_NTT_0;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.algo_type = SNDCP_XID_V42;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.dcomp = SNDCP_DCOMP1;
+
+    sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis =
+      1 << (snsm_activate_ind->nsapi);
+    sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis_set = TRUE;
+#ifdef SNDCP_UPM_INCLUDED
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p0 = snsm_activate_ind->comp_params.dcomp;
+#else
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p0 = snsm_activate_ind->dcomp;
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p0_set = TRUE;
+
+    /*
+     * Set p1 and p2 to default values.
+     */
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p1 = SNDCP_V42_DEFAULT_P1;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p1_set = TRUE;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p2 =
+      SNDCP_V42_DEFAULT_P2;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p2_set = TRUE;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.is_set =
+  #ifdef SNDCP_UPM_INCLUDED
+      (snsm_activate_ind->comp_params.dcomp != NAS_DCOMP_NEITHER_DIRECT);
+  #else
+      (snsm_activate_ind->dcomp != SNSM_COMP_NEITHER_DIRECT);
+  #endif /*#ifdef SNDCP_UPM_INCLUDED*/
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p_bit = SNDCP_P_BIT_1;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.ntt = SNDCP_NTT_0;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.algo_type = SNDCP_XID_V42;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.dcomp = SNDCP_DCOMP1;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.nsapis =
+      1 << (snsm_activate_ind->nsapi);
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.nsapis_set = TRUE;
+  #ifdef SNDCP_UPM_INCLUDED
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p0 = snsm_activate_ind->comp_params.dcomp;
+  #else
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p0 = snsm_activate_ind->dcomp;
+  #endif /*#ifdef SNDCP_UPM_INCLUDED*/
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p0_set = TRUE;
+
+    /*
+     * Set p1 and p2 to default values.
+     */
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p1 = SNDCP_V42_DEFAULT_P1;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p1_set = TRUE;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p2 =
+      SNDCP_V42_DEFAULT_P2;
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].v42.p2_set = TRUE;
+
+    /*
+     * Set affected entities and dcomp/pcomp values.
+     */
+    mg_set_ntt_comp(snsm_activate_ind->sapi);
+
+
+#else /* !TI_PS_FF_V42BIS */
+
+    sndcp_data->mg.req_xid_block[sapi_index].v42.is_set = FALSE;
+
+    sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis = 0;
+
+    sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis_set = FALSE;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p0_set = FALSE;
+
+    /*
+     * Set p1 and p2 to default values.
+     */
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p1 = SNDCP_V42_DEFAULT_P1;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p1_set = TRUE;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p2 =
+      SNDCP_V42_DEFAULT_P2;
+    sndcp_data->mg.req_xid_block[sapi_index].v42.p2_set = TRUE;
+
+#endif /* TI_PS_FF_V42BIS */
+
+  /*
+   * Set the Van Jacobson parameters.
+   * Note:
+   * If number of state slots is set to 0, do not request VJ in XID request.
+   */
+#ifdef SNDCP_UPM_INCLUDED
+  if (snsm_activate_ind->comp_params.msid == 0) {
+#else
+  if (snsm_activate_ind->msid == 0) {
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+    sndcp_data->mg.req_xid_block[sapi_index].vj.is_set = FALSE;
+    return;
+  }
+
+  sndcp_data->mg.req_xid_block[sapi_index].vj.is_set =
+  #ifdef SNDCP_UPM_INCLUDED 
+    (snsm_activate_ind->comp_params.hcomp != NAS_HCOMP_OFF);
+  #else
+    (snsm_activate_ind->hcomp != SNSM_COMP_NEITHER_DIRECT);
+  #endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+  if (!sndcp_data->mg.req_xid_block[sapi_index].vj.is_set) {
+    return;
+  }
+  /*
+   * This function will only be called after snsm_activate_ind. So the
+   * user_xid_block will be set for the affected nsapi.
+   */
+  if (sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set) {
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.p_bit = 
+      SNDCP_P_BIT_0;
+  } else {
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.p_bit = 
+      SNDCP_P_BIT_1;
+  }
+    
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.ntt = 
+    SNDCP_NTT_0;
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.algo_type = 
+    SNDCP_XID_VJ;
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.pcomp1 = 
+    SNDCP_PCOMP1;
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.pcomp2 = 
+    SNDCP_PCOMP2;
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.nsapis +=
+    1 << (snsm_activate_ind->nsapi);
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.nsapis_set = TRUE;
+#ifdef SNDCP_UPM_INCLUDED
+  if (snsm_activate_ind->comp_params.msid > SNDCP_MAX_NUMBER_OF_VJ_SLOTS) { 
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.s0_m_1 = 
+      SNDCP_MAX_NUMBER_OF_VJ_SLOTS - 1;
+  } else {
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.s0_m_1 = 
+      snsm_activate_ind->comp_params.msid - 1;
+  }
+#else
+  if (snsm_activate_ind->msid > SNDCP_MAX_NUMBER_OF_VJ_SLOTS) {
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.s0_m_1 =
+      SNDCP_MAX_NUMBER_OF_VJ_SLOTS - 1;
+  } else {
+    sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.s0_m_1 =
+      snsm_activate_ind->msid - 1;
+  }
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.s0_m_1_set = TRUE;
+  /*
+   * Only used internally, not in XID block.
+   */
+#ifdef SNDCP_UPM_INCLUDED
+  sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.direction = 
+    snsm_activate_ind->comp_params.hcomp;
+#else
+   sndcp_data->mg.user_xid_block[snsm_activate_ind->nsapi].vj.direction = 
+   snsm_activate_ind->hcomp;
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+
+  /*
+   * Set affected entities and dcomp/pcomp values.
+   */
+  mg_set_ntt_comp(snsm_activate_ind->sapi);
+
+  mg_detect_mode_clash ((USHORT)
+                         (sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis +
+                         (1 << (snsm_activate_ind->nsapi))),
+                        &vio);
+  if (vio) {
+    return;
+  }
+
+  if (sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set) {
+    sndcp_data->mg.req_xid_block[sapi_index].vj.p_bit = SNDCP_P_BIT_0;
+  } else {
+    sndcp_data->mg.req_xid_block[sapi_index].vj.p_bit = SNDCP_P_BIT_1;
+  }
+  sndcp_data->mg.req_xid_block[sapi_index].vj.ntt = SNDCP_NTT_0;
+  sndcp_data->mg.req_xid_block[sapi_index].vj.algo_type = SNDCP_XID_VJ;
+  sndcp_data->mg.req_xid_block[sapi_index].vj.pcomp1 = SNDCP_PCOMP1;
+  sndcp_data->mg.req_xid_block[sapi_index].vj.pcomp2 = SNDCP_PCOMP2;
+
+  /*
+   * All the nsapis that currently use the compressor and the new one
+   * shall be set in the nsapis field of the XID block.
+   */
+  sndcp_data->mg.req_xid_block[sapi_index].vj.nsapis = 
+    (sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis | 
+     (1 << (snsm_activate_ind->nsapi)));
+
+  sndcp_data->mg.req_xid_block[sapi_index].vj.nsapis_set = TRUE;
+#ifdef SNDCP_UPM_INCLUDED
+  if (snsm_activate_ind->comp_params.msid > SNDCP_MAX_NUMBER_OF_VJ_SLOTS) { 
+    sndcp_data->mg.req_xid_block[sapi_index].vj.s0_m_1 = 
+      SNDCP_MAX_NUMBER_OF_VJ_SLOTS - 1;
+  } else {
+    sndcp_data->mg.req_xid_block[sapi_index].vj.s0_m_1 = 
+      snsm_activate_ind->comp_params.msid - 1;
+  }
+#else
+  if (snsm_activate_ind->msid > SNDCP_MAX_NUMBER_OF_VJ_SLOTS) {
+    sndcp_data->mg.req_xid_block[sapi_index].vj.s0_m_1 =
+      SNDCP_MAX_NUMBER_OF_VJ_SLOTS - 1;
+  } else {
+    sndcp_data->mg.req_xid_block[sapi_index].vj.s0_m_1 =
+      snsm_activate_ind->msid - 1;
+  }
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+  sndcp_data->mg.req_xid_block[sapi_index].vj.s0_m_1_set = TRUE;
+  /*
+   * Only used internally, not in XID block.
+   */
+#ifdef SNDCP_UPM_INCLUDED
+  sndcp_data->mg.req_xid_block[sapi_index].vj.direction = 
+    snsm_activate_ind->comp_params.hcomp;
+#else
+  sndcp_data->mg.req_xid_block[sapi_index].vj.direction = 
+    snsm_activate_ind->hcomp;
+#endif /*#ifdef SNDCP_UPM_INCLUDED*/
+  /*
+   * Set affected entities and dcomp/pcomp values.
+   */
+  mg_set_ntt_comp(snsm_activate_ind->sapi);
+
+} /* mg_set_req_xid_block() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_res_cur_xid_block
++------------------------------------------------------------------------------
+| Description : This procedure sets the service variables res_xid_block and
+| cur_xid_block. The needed data comes from the service variable ind_xid_block,
+| and from default settings.
+| Note: if the indicated compressors do not match with compressors requested
+| or currently used then they will be unset by adding them to the list of
+| rejected compressors.
+|
+|
+| Parameters  :
+|               the affected sapi,
+|               the necessary bit length of an sdu that will later store the
+|               xid block derived from res_xid_block.
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_set_res_cur_xid_block (UBYTE sapi, USHORT* res_sdu_bit_len)
+{
+  UBYTE sapi_index = 0;
+  UBYTE nsapi = 0;
+  /*
+   * Which compressors are indicated?
+   */
+  BOOL v42_ind, vj_ind;
+  /*
+   * Which compressors are possible?
+   * (The indicated set of nsapis must overlap with the
+   * currently used one.)
+   */
+  BOOL v42_possible, vj_possible;
+  /*
+   * Is compressor going to rejected? In this case the compressor should not
+   * be requested.
+   */
+  BOOL v42_rejected, vj_rejected;
+
+  TRACE_FUNCTION( "mg_set_res_cur_xid_block" );
+
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  sndcp_reset_xid_block(&(sndcp_data->mg.res_xid_block[sapi_index]));
+
+  /*
+   * Set bit length to "only version", 3 bytes.
+   */
+  *res_sdu_bit_len = 24;
+  /*
+   * Set the version number.
+   */
+  sndcp_data->mg.res_xid_block[sapi_index].version = SNDCP_XID_VERSION;
+
+  v42_ind = sndcp_data->mg.ind_xid_block[sapi_index].v42.is_set;
+  v42_possible = FALSE;
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    if ((sndcp_data->mg.user_xid_block[nsapi].v42.nsapis & 
+        sndcp_data->mg.ind_xid_block[sapi_index].v42.nsapis) > 0) {
+
+      U8 local_sapi = 0;
+      sndcp_get_nsapi_sapi(nsapi, &local_sapi);
+      if (local_sapi == sapi) {
+        v42_possible = TRUE;
+      }
+    }
+  }
+
+
+  if (v42_ind && ! v42_possible) {
+    sndcp_data->mg.res_xid_block[sapi_index].v42.is_set = FALSE;
+    mg_set_sapi_dntt_rej (sapi,
+                          sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt,
+                          TRUE);
+  }
+
+  mg_get_sapi_dntt_rej (sapi,
+                        sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt,
+                        &v42_rejected);
+
+
+  if (v42_ind && ! v42_rejected) {
+    /*
+     * Data compression will be included, increment bit len (+ 10 bytes).
+     */
+    *res_sdu_bit_len += 80;
+
+    /*
+     * Set the V42.bis parameters,
+     */
+    sndcp_data->mg.res_xid_block[sapi_index].v42.is_set = TRUE;
+
+    sndcp_data->mg.res_xid_block[sapi_index].v42.p_bit = SNDCP_P_BIT_0;
+
+    sndcp_data->mg.res_xid_block[sapi_index].v42.ntt =
+      sndcp_data->mg.ind_xid_block[sapi_index].v42.ntt;
+
+
+    sndcp_data->mg.res_xid_block[sapi_index].v42.algo_type = SNDCP_XID_V42;
+
+    sndcp_data->mg.res_xid_block[sapi_index].v42.dcomp =
+      sndcp_data->mg.ind_xid_block[sapi_index].v42.dcomp;
+
+    /*
+     * Set the 'nsapis' parameter in res_xid_block:
+     * Check rules in 4.65, subclause 6.8.1, compare with cur_xid_block.
+     */
+    mg_set_xid_nsapis(sapi, MG_XID_V42_NSAPIS);
+
+    /*
+     * It is assumed that the values desired by the user / the
+     * values possible with the current implementation are written in
+     * req_xid_block, the responded values are then the minimum of
+     * req and ind values:
+     */
+    /*
+     * For the direction parameter p0 take the logical AND:
+     */
+    sndcp_data->mg.res_xid_block[sapi_index].v42.p0 =
+      (sndcp_data->mg.req_xid_block[sapi_index].v42.p0 &
+       sndcp_data->mg.ind_xid_block[sapi_index].v42.p0);
+    sndcp_data->mg.res_xid_block[sapi_index].v42.p0_set = TRUE;
+
+    /*
+     * For p1 and p2 take minimum.
+     */
+    sndcp_data->mg.res_xid_block[sapi_index].v42.p1 =
+      (sndcp_data->mg.req_xid_block[sapi_index].v42.p1 <
+       sndcp_data->mg.ind_xid_block[sapi_index].v42.p1)?
+       sndcp_data->mg.req_xid_block[sapi_index].v42.p1 :
+        sndcp_data->mg.ind_xid_block[sapi_index].v42.p1;
+    sndcp_data->mg.res_xid_block[sapi_index].v42.p1_set = TRUE;
+
+    sndcp_data->mg.res_xid_block[sapi_index].v42.p2 =
+      (sndcp_data->mg.req_xid_block[sapi_index].v42.p2 <
+       sndcp_data->mg.ind_xid_block[sapi_index].v42.p2)?
+       sndcp_data->mg.req_xid_block[sapi_index].v42.p2 :
+        sndcp_data->mg.ind_xid_block[sapi_index].v42.p2;
+    sndcp_data->mg.res_xid_block[sapi_index].v42.p2_set = TRUE;
+
+  } /* v42.is_set */
+
+
+  /*
+   * Header compression,
+   */
+
+  
+  vj_ind = sndcp_data->mg.ind_xid_block[sapi_index].vj.is_set;
+  vj_possible = FALSE;
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    if ((sndcp_data->mg.user_xid_block[nsapi].vj.nsapis & 
+        sndcp_data->mg.ind_xid_block[sapi_index].vj.nsapis) > 0) {
+
+      U8 local_sapi = 0;
+      sndcp_get_nsapi_sapi(nsapi, &local_sapi);
+      if (local_sapi == sapi) {
+        vj_possible = TRUE;
+      }
+    }
+  }
+
+  if (vj_ind && ! vj_possible) {
+    sndcp_data->mg.res_xid_block[sapi_index].vj.is_set = FALSE;
+    mg_set_sapi_pntt_rej (sapi,
+                          sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                          TRUE);
+  }
+
+  mg_get_sapi_pntt_rej (sapi,
+                        sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt,
+                        &vj_rejected);
+
+  if (vj_ind && ! vj_rejected) {
+    /*
+     * Header compression will be included, increment bit len (+ 7 bytes).
+     */
+    *res_sdu_bit_len += 56;
+
+    /*
+     * Set the VJ parameters,
+     */
+    sndcp_data->mg.res_xid_block[sapi_index].vj.is_set = TRUE;
+
+    sndcp_data->mg.res_xid_block[sapi_index].vj.p_bit = SNDCP_P_BIT_0;
+
+    sndcp_data->mg.res_xid_block[sapi_index].vj.ntt =
+      sndcp_data->mg.ind_xid_block[sapi_index].vj.ntt;
+
+    sndcp_data->mg.res_xid_block[sapi_index].vj.algo_type = SNDCP_XID_VJ;
+
+    if (sndcp_data->mg.ind_xid_block[sapi_index].vj.p_bit == SNDCP_P_BIT_1) {
+      sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp1 =
+        sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp1;
+      sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp2 =
+        sndcp_data->mg.ind_xid_block[sapi_index].vj.pcomp2;
+    } else {
+      sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp1 =
+        sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp1;
+      sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp2 =
+        sndcp_data->mg.cur_xid_block[sapi_index].vj.pcomp2;
+    }
+
+    /*
+     * Set the 'nsapis' parameter in res_xid_block:
+     * Check rules in 4.65, subclause 6.8.1, compare with cur_xid_block.
+     * State slots and direction are also set here.
+     */
+    mg_set_xid_nsapis(sapi, MG_XID_VJ_NSAPIS);
+
+
+  } /* vj.is_set */
+
+
+  /*
+   * Set affected entities and dcomp/pcomp values.
+   */
+  if (v42_ind && v42_possible) {
+    mg_set_sapi_dntt_state(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].v42.ntt,
+                           MG_ASSIGNED);
+
+    mg_set_sapi_dcomp_state(sapi,
+                            sndcp_data->mg.res_xid_block[sapi_index].v42.dcomp,
+                            MG_ASSIGNED);
+    mg_set_sapi_dcomp_dntt(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].v42.dcomp,
+                           sndcp_data->mg.res_xid_block[sapi_index].v42.ntt);
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if (((1 << nsapi) & sndcp_data->mg.ind_xid_block[sapi_index].v42.nsapis) > 0) {
+        mg_set_sapi_dntt_nsapi(sapi,
+                              sndcp_data->mg.res_xid_block[sapi_index].v42.ntt,
+                               nsapi,
+                               TRUE);
+      } /* if nsapi is selected */
+    } /* for loop over all nsapis */
+
+  }
+  /*
+   * If VJ is indicated and possible, switch on compressor.
+   */
+  if (vj_ind && vj_possible) {
+    mg_set_sapi_pntt_state(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.ntt,
+                           MG_ASSIGNED);
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp1,
+                            MG_ASSIGNED);
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp2,
+                            MG_ASSIGNED);
+    mg_set_sapi_pcomp_pntt(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp1,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.ntt);
+    mg_set_sapi_pcomp_pntt(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp2,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.ntt);
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if (((1 << nsapi) & sndcp_data->mg.ind_xid_block[sapi_index].v42.nsapis) > 0) {
+        mg_set_sapi_pntt_nsapi(sapi,
+                             sndcp_data->mg.res_xid_block[sapi_index].vj.ntt,
+                             nsapi,
+                             TRUE);
+      } /* if nsapi is selected */
+    } /* for loop over all nsapis */
+  }
+
+  /*
+   * If VJ has been switched on and is now indicated to be switched off:
+   * switch off compressor.
+   */
+  if (vj_ind
+      &&
+      sndcp_data->mg.ind_xid_block[sapi_index].vj.nsapis == 0
+      &&
+      sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis > 0)
+  {
+    mg_set_sapi_pntt_state(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.ntt,
+                           MG_UNASSIGNED);
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp1,
+                            MG_UNASSIGNED);
+    mg_set_sapi_pcomp_state(sapi,
+                            sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp2,
+                            MG_UNASSIGNED);
+/*    mg_set_sapi_pcomp_pntt(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp1,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.ntt);
+    mg_set_sapi_pcomp_pntt(sapi,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.pcomp2,
+                           sndcp_data->mg.res_xid_block[sapi_index].vj.ntt);
+*/
+    for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+      if (((1 << nsapi) & sndcp_data->mg.ind_xid_block[sapi_index].v42.nsapis) > 0) {
+        mg_set_sapi_pntt_nsapi(sapi,
+                             sndcp_data->mg.cur_xid_block[sapi_index].vj.ntt,
+                             nsapi,
+                             FALSE);
+      } /* if nsapi is selected */
+    } /* for loop over all nsapis */
+  }
+
+
+  /*
+   * Add same values for cur_xid_block.
+   */
+
+  if (sndcp_data->mg.res_xid_block[sapi_index].v42.is_set) {
+    if (sndcp_data->mg.cur_xid_block[sapi_index].v42.is_set) {
+      sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis =
+        sndcp_data->mg.res_xid_block[sapi_index].v42.nsapis;
+      if (sndcp_data->mg.cur_xid_block[sapi_index].v42.p0_set) {
+        sndcp_data->mg.cur_xid_block[sapi_index].v42.p0 =
+          sndcp_data->mg.res_xid_block[sapi_index].v42.p0;
+      }
+      if (sndcp_data->mg.cur_xid_block[sapi_index].v42.p1_set) {
+        sndcp_data->mg.cur_xid_block[sapi_index].v42.p1 =
+          sndcp_data->mg.res_xid_block[sapi_index].v42.p1;
+      }
+      if (sndcp_data->mg.cur_xid_block[sapi_index].v42.p2_set) {
+        sndcp_data->mg.cur_xid_block[sapi_index].v42.p2 =
+          sndcp_data->mg.res_xid_block[sapi_index].v42.p2;
+      }
+    } else {
+      sndcp_data->mg.cur_xid_block[sapi_index].v42 =
+        sndcp_data->mg.res_xid_block[sapi_index].v42;
+    }
+  }
+
+  if (sndcp_data->mg.res_xid_block[sapi_index].vj.is_set) {
+    if (sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set) {
+      sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis =
+        sndcp_data->mg.res_xid_block[sapi_index].vj.nsapis;
+      if (sndcp_data->mg.cur_xid_block[sapi_index].vj.s0_m_1_set) {
+        sndcp_data->mg.cur_xid_block[sapi_index].vj.s0_m_1 =
+          sndcp_data->mg.res_xid_block[sapi_index].vj.s0_m_1;
+      }
+    } else {
+      sndcp_data->mg.cur_xid_block[sapi_index].vj =
+        sndcp_data->mg.res_xid_block[sapi_index].vj;
+    }
+  }
+
+
+  if (vj_rejected) {
+    sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis = 0;
+  }
+  if (sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis == 0) {
+    sndcp_data->mg.cur_xid_block[sapi_index].vj.is_set = FALSE;
+  }
+
+  if (v42_rejected) {
+    sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis = 0;
+  }
+  if (sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis == 0) {
+    sndcp_data->mg.cur_xid_block[sapi_index].v42.is_set = FALSE;
+  }
+
+  sig_mg_cia_new_xid(& sndcp_data->mg.cur_xid_block[sapi_index]);
+
+
+} /* mg_set_res_cur_xid_block */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_res_xid_params
++------------------------------------------------------------------------------
+| Description : This procedure fills the XID block. It is implementation
+|               dependent. In the current version V42bis and VanJacobson
+|               header compression are applied.
+|
+| Parameters  :
+|               the sdu that will be filled,
+| Post        : Reset arrays with reject information to all FALSE.
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_set_res_xid_params (T_sdu* sdu, UBYTE sapi)
+{
+  /*
+   * Byte index in destination sdu.
+   */
+  UBYTE index = 3;
+  UBYTE type_2_header_index = 0;
+  UBYTE sapi_index = 0;
+  UBYTE ntt = 0;
+  BOOL type_1_header_set = FALSE;
+  BOOL type_2_header_set = FALSE;
+  TRACE_FUNCTION( "mg_set_res_xid_params" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  /*
+   * Set the values for parameter type 0 (version number).
+   */
+  sdu->buf[0] = SNDCP_XID_PARAM_TYPE_0;
+  /*lint -e{415} (Warning -- access of out-of-bounds pointer)*/
+  sdu->buf[1] = SNDCP_XID_0_LEN;
+  /*lint -e{415, 416} (Warning -- access/creation of out-of-bounds pointer)*/
+  sdu->buf[2] =
+    sndcp_data->mg.res_xid_block[sapi_index].version;
+
+  sdu->l_buf = 3 * 8;
+  sdu->o_buf = 0;
+  /*
+   * Set the values for data compression, if necessary.
+   */
+  /*lint -e{415, 416} (Warning -- access/creation of out-of-bounds pointer)*/
+  if (sndcp_data->mg.res_xid_block[sapi_index].v42.is_set) {
+    sdu->buf[3] = SNDCP_XID_PARAM_TYPE_1;
+    sdu->buf[4] = SNDCP_XID_1_LEN_RES;
+    sdu->buf[5] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].v42.p_bit << 7) +
+            sndcp_data->mg.res_xid_block[sapi_index].v42.ntt;
+    sdu->buf[6] = SNDCP_XID_V42_LEN_RES;
+    sdu->buf[7] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].v42.nsapis >> 8);
+    sdu->buf[8] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].v42.nsapis & 0xff);
+    sdu->buf[9] = sndcp_data->mg.res_xid_block[sapi_index].v42.p0;
+    sdu->buf[10] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].v42.p1 >> 8);
+    sdu->buf[11] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].v42.p1 & 0xff);
+    sdu->buf[12] = sndcp_data->mg.res_xid_block[sapi_index].v42.p2;
+
+    index = 13;
+    sdu->l_buf = 13 * 8;
+
+    type_1_header_set = TRUE;
+  }
+  /*
+   * Add rejected data compression entities.
+   */
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    BOOL rej = FALSE;
+    mg_get_sapi_dntt_rej(sapi, ntt, &rej);
+    /*lint -e{661, 662} (Warning -- Possible access/creation of out-of-bounds pointer)*/
+    if (rej) {
+      if (! type_1_header_set) {
+        sdu->buf[index] = SNDCP_XID_PARAM_TYPE_1;
+        index++;
+        sdu->buf[index] = 0;
+        index++;
+        type_1_header_set = TRUE;
+        sdu->l_buf += 16;
+      }
+
+      sdu->buf[index] = ntt;
+      index++;
+      /*
+       * Length of field.
+       */
+      sdu->buf[index] = 2;
+      index++;
+      /*
+       * Set 2 'nsapis' octets to 0.
+       */
+      sdu->buf[index] = 0;
+      index++;
+      sdu->buf[index] = 0;
+      index++;
+      /*
+       * Increment sdu length.
+       */
+      sdu->l_buf = sdu->l_buf + 32;
+      /*
+       * Increment parameter type 1 length octet.
+       */
+       /*lint -e{415, 416} (Warning -- access/creation of out-of-bounds pointer)*/
+      sdu->buf[4] += 4;
+    }
+  }
+  type_2_header_index = index;
+
+  /*
+   * Set the values for header compression, if requested.
+   */
+   /*lint -e{661, 662} (Warning -- Possible access/creation of out-of-bounds pointer)*/
+  if (sndcp_data->mg.res_xid_block[sapi_index].vj.is_set) {
+    sdu->buf[index] = SNDCP_XID_PARAM_TYPE_2;
+    index++;
+    sdu->buf[index] = SNDCP_XID_2_LEN_RES;
+    index++;
+    sdu->buf[index] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].vj.p_bit << 7) +
+       sndcp_data->mg.res_xid_block[sapi_index].vj.ntt;
+    index++;
+    sdu->buf[index] = SNDCP_XID_VJ_LEN_RES;
+    index++;
+    sdu->buf[index] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].vj.nsapis >> 8);
+    index++;
+    sdu->buf[index] =
+      (UBYTE)(sndcp_data->mg.res_xid_block[sapi_index].vj.nsapis & 0xff);
+    index++;
+    sdu->buf[index] =
+      sndcp_data->mg.res_xid_block[sapi_index].vj.s0_m_1;
+    index++;
+
+    sdu->l_buf = sdu->l_buf + 7 * 8;
+
+    type_2_header_set = TRUE;
+  }
+  /*
+   * Add rejected header compression entities.
+   */
+   /*lint -e{661, 662} (Warning -- Possible access/creation of out-of-bounds pointer)*/
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    BOOL rej = FALSE;
+    mg_get_sapi_pntt_rej(sapi, ntt, &rej);
+    if (rej) {
+      if (! type_2_header_set) {
+        sdu->buf[index] = SNDCP_XID_PARAM_TYPE_2;
+        index++;
+        sdu->buf[index] = 0;
+        index++;
+        type_2_header_set = TRUE;
+        sdu->l_buf += 16;
+      }
+      sdu->buf[index] = ntt;
+      index++;
+      /*
+       * Length of field.
+       */
+      sdu->buf[index] = 2;
+      index++;
+      /*
+       * Set 2 'nsapis' octets to 0.
+       */
+      sdu->buf[index] = 0;
+      index++;
+      sdu->buf[index] = 0;
+      index++;
+      /*
+       * Increment sdu length.
+       */
+      sdu->l_buf = sdu->l_buf + 32;
+      /*
+       * Increment parameter type 2 length octet.
+       */
+      sdu->buf[type_2_header_index + 1] += 4;
+    }
+  }
+  /*
+   * Set sdu offset to 0.
+   */
+  sdu->o_buf = 0;
+  /*
+   * Reset the arrays with rejected params to all FALSE.
+   */
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    sndcp_data->mg.sapi_dntt_rej_ra[sapi_index][ntt] = FALSE;
+    sndcp_data->mg.sapi_pntt_rej_ra[sapi_index][ntt] = FALSE;
+  }
+
+} /* mg_set_res_xid_params() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_set_xid_params
++------------------------------------------------------------------------------
+| Description : This procedure fills the XID block. It is implementation
+|               dependent. In the current version V42bis and VanJacobson
+|               header compression are applied.
+|
+| Parameters  :
+|               sapi and sdu from the LL_XID_REQ that will be filled and
+|               xid_block that defines the desired compressors
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_set_xid_params (UBYTE sapi, T_sdu* sdu, T_XID_BLOCK xid_block)
+{
+  /*
+   * Byte index in destination sdu.
+   */
+  UBYTE index = 3;
+  UBYTE sapi_index = 0;
+  UBYTE ntt = 0;
+  BOOL type_1_header_set = FALSE;
+  BOOL type_2_header_set = FALSE;
+  UBYTE type_2_header_index = 0;
+  UBYTE type_1_header_index = 3;
+  USHORT p1 = SNDCP_V42_DEFAULT_P1;
+  TRACE_FUNCTION( "mg_set_xid_params" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  /*
+   * Set the values for parameter type 0 (version number).
+   */
+  sdu->buf[0] = SNDCP_XID_PARAM_TYPE_0;
+  /*lint -e{415} (Warning -- access of out-of-bounds pointer)*/
+  sdu->buf[1] = SNDCP_XID_0_LEN;
+  /*lint -e{415, 416} (Warning -- access/creation of out-of-bounds pointer)*/
+  sdu->buf[2] = SNDCP_XID_VERSION;
+
+  sdu->l_buf = 24; /* 3 * 8 */
+  sdu->o_buf = 0;
+  /*
+   * Set the values for data compression, if necessary.
+   */
+   /*lint -e{415, 416} (Warning -- access/creation of out-of-bounds pointer)*/
+  if (xid_block.v42.is_set &&
+      #ifdef SNDCP_UPM_INCLUDED 
+       xid_block.v42.p0 != NAS_DCOMP_OFF &&
+      #else
+       xid_block.v42.p0 != SNSM_COMP_NEITHER_DIRECT &&
+      #endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+      xid_block.v42.nsapis_set &&
+      xid_block.v42.nsapis > 0) {
+
+    if (xid_block.v42.p_bit > 0) {
+      sdu->buf[3] = SNDCP_XID_PARAM_TYPE_1;
+      sdu->buf[4] = SNDCP_XID_1_LEN;
+      sdu->buf[5] = (UBYTE)(xid_block.v42.p_bit << 7) + xid_block.v42.ntt;
+      sdu->buf[6] = xid_block.v42.algo_type;
+      sdu->buf[7] = SNDCP_XID_V42_LEN;
+      sdu->buf[8] = (UBYTE)(xid_block.v42.dcomp << 4);
+      sdu->buf[9] = (UBYTE)(xid_block.v42.nsapis >> 8);
+      sdu->buf[10] = (UBYTE)(xid_block.v42.nsapis & 0xff);
+      sdu->buf[11] = xid_block.v42.p0;
+      /*
+       * P1, P2
+       */
+      sdu->buf[12] = (p1 & 0xff00) >> 8;
+      sdu->buf[13] = p1 & 0x00ff;
+      sdu->buf[14] = SNDCP_V42_DEFAULT_P2;
+
+      index = 15;
+      sdu->l_buf = 15 * 8;
+    } else {
+      sdu->buf[3] = SNDCP_XID_PARAM_TYPE_1;
+      sdu->buf[4] = SNDCP_XID_1_LEN_RES;
+      sdu->buf[5] = xid_block.v42.ntt;
+      sdu->buf[6] = SNDCP_XID_V42_LEN_RES;
+      sdu->buf[7] = (UBYTE)(xid_block.v42.nsapis >> 8);
+      sdu->buf[8] = (UBYTE)(xid_block.v42.nsapis & 0xff);
+      sdu->buf[9] = xid_block.v42.p0;
+      /*
+       * P1, P2
+       */
+      sdu->buf[10] = (p1 & 0xff00) >> 8;
+      sdu->buf[11] = p1 & 0x00ff;
+      sdu->buf[12] = SNDCP_V42_DEFAULT_P2;
+
+      index = 13;
+      sdu->l_buf = 13 * 8;
+
+    }
+  }
+  type_2_header_index = index;
+  /*
+   * Set the values for header compression, if requested.
+   */
+   /*lint -e{661, 662} (Warning -- Possible access/creation of out-of-bounds pointer)*/
+  if (xid_block.vj.is_set &&
+      #ifdef SNDCP_UPM_INCLUDED
+       xid_block.vj.direction != NAS_HCOMP_OFF &&
+      #else
+       xid_block.vj.direction != SNSM_COMP_NEITHER_DIRECT &&
+      #endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+      xid_block.vj.nsapis_set &&
+      xid_block.vj.nsapis > 0) {
+
+    if (xid_block.vj.p_bit > 0) {
+
+      sdu->buf[index] = SNDCP_XID_PARAM_TYPE_2;
+      sdu->buf[index + 1] = SNDCP_XID_2_LEN;
+      sdu->buf[index + 2] =
+        (UBYTE)(xid_block.vj.p_bit << 7) + xid_block.vj.ntt;
+      sdu->buf[index + 3] = SNDCP_XID_VJ;
+      sdu->buf[index + 4] = SNDCP_XID_VJ_LEN;
+      sdu->buf[index + 5] =
+        (UBYTE)(xid_block.vj.pcomp1 << 4) + xid_block.vj.pcomp2;
+      sdu->buf[index + 6] =
+        (UBYTE)(xid_block.vj.nsapis >> 8);
+      sdu->buf[index + 7] =
+        (UBYTE)(xid_block.vj.nsapis & 0xff);
+      sdu->buf[index + 8] = xid_block.vj.s0_m_1;
+
+      sdu->l_buf = sdu->l_buf + 9 * 8;
+
+      type_2_header_set = TRUE;
+    } else {
+      sdu->buf[index] = SNDCP_XID_PARAM_TYPE_2;
+      sdu->buf[index + 1] = SNDCP_XID_2_LEN_RES;
+      sdu->buf[index + 2] = xid_block.vj.ntt;
+
+      sdu->buf[index + 3] = SNDCP_XID_VJ_LEN_RES;
+
+      sdu->buf[index + 4] =
+        (UBYTE)(xid_block.vj.nsapis >> 8);
+      sdu->buf[index + 5] =
+        (UBYTE)(xid_block.vj.nsapis & 0xff);
+      sdu->buf[index + 6] = xid_block.vj.s0_m_1;
+
+      sdu->l_buf = sdu->l_buf + 7 * 8;
+
+      type_2_header_set = TRUE;
+    }
+  }
+  /*
+   * Add rejected data compression entities.
+   */
+   /*lint -e{661, 662} (Warning -- Possible access/creation of out-of-bounds pointer)*/
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    BOOL rej = FALSE;
+    mg_get_sapi_dntt_rej(sapi, ntt, &rej);
+    if (rej) {
+      if (! type_1_header_set) {
+        sdu->buf[index] = SNDCP_XID_PARAM_TYPE_1;
+        index++;
+        sdu->buf[index] = 0;
+        index++;
+        type_1_header_set = TRUE;
+        sdu->l_buf += 16;
+      }
+      sdu->buf[index] = ntt;
+      index++;
+      /*
+       * Length of field.
+       */
+      sdu->buf[index] = 2;
+      index++;
+      /*
+       * Set 2 'nsapis' octets to 0.
+       */
+      sdu->buf[index] = 0;
+      index++;
+      sdu->buf[index] = 0;
+      index++;
+      /*
+       * Increment sdu length.
+       */
+      sdu->l_buf = sdu->l_buf + 32;
+      /*
+       * Increment parameter type 2 length octet.
+       */
+       /*lint -e{415, 416} (Warning -- access/creation of out-of-bounds pointer)*/
+      sdu->buf[type_1_header_index + 1] += 4;
+    }
+  } /* for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++)  */
+  /*
+   * Add rejected header compression entities.
+   */
+   /*lint -e{661, 662} (Warning -- Possible access/creation of out-of-bounds pointer)*/
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    BOOL rej = FALSE;
+    mg_get_sapi_pntt_rej(sapi, ntt, &rej);
+    if (rej) {
+      if (! type_2_header_set) {
+        sdu->buf[index] = SNDCP_XID_PARAM_TYPE_2;
+        index++;
+        sdu->buf[index] = 0;
+        index++;
+        type_2_header_set = TRUE;
+        sdu->l_buf += 16;
+      }
+      sdu->buf[index] = ntt;
+      index++;
+      /*
+       * Length of field.
+       */
+      sdu->buf[index] = 2;
+      index++;
+      /*
+       * Set 2 'nsapis' octets to 0.
+       */
+      sdu->buf[index] = 0;
+      index++;
+      sdu->buf[index] = 0;
+      index++;
+      /*
+       * Increment sdu length.
+       */
+      sdu->l_buf = sdu->l_buf + 32;
+      /*
+       * Increment parameter type 2 length octet.
+       */
+      sdu->buf[type_2_header_index + 1] += 4;
+    }
+  } /* for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++)  */
+  /*
+   * Set sdu offset to 0.
+   */
+  sdu->o_buf = 0;
+  /*
+   * Reset the arrays with rejected params to all FALSE.
+   */
+  for (ntt = 0; ntt < MG_MAX_ENTITIES; ntt++) {
+    sndcp_data->mg.sapi_dntt_rej_ra[sapi_index][ntt] = FALSE;
+    sndcp_data->mg.sapi_pntt_rej_ra[sapi_index][ntt] = FALSE;
+  }
+
+} /* mg_set_xid_params() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_del_comp_pdus_ack
++------------------------------------------------------------------------------
+| Description : The function mg_del_comp_pdus_ack()
+|               GSM 4.65, 5.1.2.7:
+|               "compressed N-PDUs queuing to be forwarded to the affected
+|               SAPI are deleted from the SNDCP layer."
+|               Assumption: It is assumed here that acknowledged and
+|               unacknowledged npdus are deleted the same.
+|
+| Parameters  : UBYTE sapi: the affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_del_comp_pdus_ack (UBYTE sapi)
+{
+  UBYTE nsapi = 0;
+
+  TRACE_FUNCTION( "mg_del_comp_pdus_ack" );
+
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    UBYTE sp = 0;
+    sndcp_get_nsapi_sapi(nsapi, &sp);
+    if (sp == sapi) {
+      sig_mg_cia_delete_npdus(nsapi);
+      sig_mg_su_delete_pdus(nsapi, sapi);
+      sig_mg_sua_delete_pdus(nsapi, sapi, TRUE);
+      sig_mg_sd_delete_npdus(nsapi, sapi);
+      sig_mg_sda_delete_npdus(nsapi, sapi);
+    }
+  }
+} /* mg_del_comp_pdus_ack() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_delete_npdus
++------------------------------------------------------------------------------
+| Description : The function mg_delete_npdus() sends signals to all affected
+|               services to delete the buffered npdus.
+|
+| Parameters  : UBYTE nsapi: the affected nsapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_delete_npdus (UBYTE nsapi)
+{
+  UBYTE sapi = 0;
+  TRACE_FUNCTION( "mg_delete_npdus" );
+  sndcp_get_nsapi_sapi(nsapi, &sapi);
+
+  sig_mg_cia_delete_npdus(nsapi);
+  sig_mg_su_delete_pdus(nsapi, sapi);
+  sig_mg_sua_delete_pdus(nsapi, sapi, TRUE);
+  sig_mg_sd_delete_npdus(nsapi, sapi);
+  sig_mg_sda_delete_npdus(nsapi, sapi);
+
+  sig_mg_nu_delete_npdus(nsapi);
+
+} /* mg_delete_npdus() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_suspend_affected_nus
++------------------------------------------------------------------------------
+| Description : Suspends all nu service instances affected by XID negotiation
+|               Sets service variable 'suspended_nsapis'.
+|
+| Parameters  : sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_suspend_affected_nus (UBYTE sapi) {
+  UBYTE nsapi = 0;
+  UBYTE sapi_index = 0;
+  TRACE_FUNCTION( "mg_resume_affected_nus" );
+  sndcp_get_sapi_index(sapi, &sapi_index);
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    if (1 << nsapi & sndcp_data->mg.req_xid_block[sapi_index].vj.nsapis ||
+        1 << nsapi & sndcp_data->mg.cur_xid_block[sapi_index].vj.nsapis ||
+        1 << nsapi & sndcp_data->mg.req_xid_block[sapi_index].v42.nsapis ||
+        1 << nsapi & sndcp_data->mg.cur_xid_block[sapi_index].v42.nsapis) {
+
+      sndcp_data->mg.suspended_nsapis |= (1 << nsapi);
+      sig_mg_nu_suspend(nsapi);
+    }
+  }
+} /* mg_suspend_affected_nus() */
+
+
+
+
+
+
+/*
+ * Getters and setters for the organizing arrays.
+ */
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_dntt_rej
++------------------------------------------------------------------------------
+| Description : The procedures informs about if a given data
+|               compression entity on a given SAPI is to be rejected in
+|               LL_XID_REQ because it cannot be set up.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN dntt UBYTE,
+|               IN/OUT rej BOOL
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_get_sapi_dntt_rej (UBYTE sapi, UBYTE dntt, BOOL* rej)
+{
+  TRACE_FUNCTION( "mg_get_sapi_dntt_rej" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *rej = sndcp_data->mg.sapi_dntt_rej_ra[sapi_index][dntt];
+  }
+} /* mg_get_sapi_dntt_rej() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_pntt_rej
++------------------------------------------------------------------------------
+| Description : The procedures informs about if a given header
+|               compression entity on a given SAPI is to be rejected in
+|               LL_XID_REQ because it cannot be set up.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pntt UBYTE,
+|               IN/OUT rej BOOL
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_get_sapi_pntt_rej (UBYTE sapi, UBYTE pntt, BOOL* rej)
+{
+  TRACE_FUNCTION( "mg_get_sapi_pntt_rej" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *rej = sndcp_data->mg.sapi_pntt_rej_ra[sapi_index][pntt];
+  }
+} /* mg_get_sapi_pntt_rej() */
+
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_pntt_nsapi
++------------------------------------------------------------------------------
+| Description : The procedure informs if a given nsapi uses a given pntt on a
+|               given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pntt UBYTE,
+|               IN nsapi UBYTE,
+|               IN/OUT used BOOL
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_get_sapi_pntt_nsapi (UBYTE sapi, UBYTE pntt, UBYTE nsapi, BOOL* used)
+{
+  TRACE_FUNCTION( "mg_get_sapi_pntt_nsapi" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *used = sndcp_data->mg.sapi_pntt_nsapi_set_ra[sapi_index][pntt][nsapi];
+  }
+} /* mg_get_sapi_pntt_nsapi() */
+
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_sapi_pcomp_pntt
++------------------------------------------------------------------------------
+| Description : The procedures indicates the pntt assigned to a given pcomp
+|               for a given sapi.
+|
+| Parameters  : FPAR IN sapi UBYTE,
+|               IN pcomp UBYTE,
+|               IN/OUT dntt UBYTE
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_get_sapi_pcomp_pntt (UBYTE sapi, UBYTE pcomp, UBYTE* pntt)
+{
+  TRACE_FUNCTION( "mg_get_sapi_pcomp_pntt" );
+  {
+    UBYTE sapi_index = 0;
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    *pntt = sndcp_data->mg.sapi_pcomp_pntt_ra[sapi_index][pcomp];
+  }
+} /* mg_get_sapi_pcomp_pntt() */
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_xid_cnf_ok_res
++------------------------------------------------------------------------------
+| Description :
+| After an LL_XID_REQ has been sent there are contexts in state MG_XID.
+| These are now reset after reception of the LL_XID_CNF.
+| The "applicable nsapis" in req_xid_block.v42 and req_xid_block.vj, each one
+| only once.
+| SIG_MG_NU_RESET(nsapi, discard_ready) is used.
+| In every nu instance: N-PDU number is set to 0 for this instance and an
+| SN_UNITREADY_IND is sent. State is set to NU_UNACK_SU_RECEPTIVE
+| Then the SNSM_ACTIVATE_RES is sent for each one of these.
+|
+| Parameters  : affected sapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_xid_cnf_ok_res (UBYTE sapi)
+{
+  UBYTE nsapi = 0;
+
+  TRACE_FUNCTION( "mg_xid_cnf_ok_res" );
+  for (nsapi = 0; nsapi < SNDCP_NUMBER_OF_NSAPIS; nsapi++) {
+    USHORT nsapi_state = MG_IDLE;
+    USHORT sapi_state = MG_IDLE;
+    UBYTE sapi_index = 0;
+    UBYTE func_sapi = 0;
+    sndcp_get_nsapi_sapi(nsapi, &func_sapi);
+    if (func_sapi != sapi) {
+      continue;
+    }
+    sndcp_get_sapi_index(sapi, &sapi_index);
+    sndcp_get_nsapi_state(nsapi, &nsapi_state);
+    sndcp_get_sapi_state(func_sapi, &sapi_state);
+
+
+    if (((sapi_state & MG_XID_NEC) > 0)
+        &&
+        ((sapi_state & MG_REL) == 0)) {
+      mg_resend_xid_if_nec(sapi);
+
+      sndcp_get_sapi_state(func_sapi, &sapi_state);
+      /*
+       * If now XID is sent, no further actions for this nsapi.
+       */
+      if ((sapi_state & MG_XID) > 0) {
+        continue;
+      }
+
+    } else if ((nsapi_state & MG_ACT) > 0 &&
+        (sapi_state & MG_EST) == 0) {
+
+      BOOL ack = FALSE;
+
+      sndcp_get_nsapi_ack(nsapi, &ack);
+      /*
+       * Open DTI connection.
+       */
+#ifndef SNDCP_UPM_INCLUDED 
+      mg_dti_open(nsapi);
+#endif 
+      if (ack) {
+        sig_mg_nu_reset_ack(nsapi, 0, 0, FALSE);
+        sig_mg_sda_getdata(sapi, nsapi);
+      } else {
+        sig_mg_nu_reset(nsapi, FALSE);
+        sig_mg_sd_getunitdata(sapi, nsapi);
+      }
+
+      if ((sapi_state & MG_XID) == 0) {
+        mg_send_snsm_activate_res(nsapi);
+        /*
+         * Set nsapi state to MG_IDLE.
+         */
+        sndcp_unset_nsapi_state(nsapi, MG_ACT);
+      }
+    } /* if state is MG_ACT and not MG_EST  */
+
+    if ((nsapi_state & MG_DEACT) > 0) {
+
+      USHORT local_sapi_state = MG_IDLE;
+
+      sndcp_get_sapi_state(sapi, &local_sapi_state);
+
+      if ((local_sapi_state &
+            (MG_REL_NEC_LOC + MG_REL_NEC_PEER + MG_XID_NEC + MG_XID))
+          == 0)
+      {
+        /*
+         * No LL_RELEASE_REQ necessary. Notify sndcp.
+         */
+#ifdef SNDCP_UPM_INCLUDED 
+        PALLOC(snsm_deactivate_res, SN_DEACTIVATE_CNF);
+#else
+        PALLOC(snsm_deactivate_res, SNSM_DEACTIVATE_RES);
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+        /*
+         * Now the NSAPI is not in use anymore:
+         */
+        sndcp_set_nsapi_used(nsapi, FALSE);
+        sndcp_set_nsapi_ack(nsapi, FALSE);
+
+        snsm_deactivate_res->nsapi = nsapi;
+        sndcp_unset_nsapi_state(nsapi, MG_DEACT);
+#ifdef SNDCP_UPM_INCLUDED 
+        PSEND(hCommUPM, snsm_deactivate_res);
+#else
+        PSEND(hCommSM, snsm_deactivate_res);
+#endif  /*#ifdef SNDCP_UPM_INCLUDED*/
+        /*
+         * Resume nsapi.
+         */
+        mg_resume_affected_nus(sapi);
+
+      } else if ((local_sapi_state & (MG_REL_NEC_LOC + MG_REL_NEC_PEER)) > 0) {
+        /*
+         * LL_RELEASE_REQ must be sent.
+         */
+
+        PALLOC(ll_release_req, LL_RELEASE_REQ);
+
+        sndcp_unset_sapi_state(sapi, MG_REL_NEC_LOC);
+        ll_release_req->sapi = sapi;
+        ll_release_req->local = TRUE;
+        /*
+         * Set the "state" for the affected and sapi to MG_REL_PENDING.
+         */
+        sndcp_set_sapi_state(sapi, MG_REL);
+
+        PSEND(hCommLLC, ll_release_req);
+      } else {
+
+        UBYTE local_sapi = 0;
+        UBYTE local_nsapi = 0;
+        BOOL local_nec = FALSE;
+        for (local_nsapi = 0;
+             local_nsapi < SNDCP_NUMBER_OF_NSAPIS;
+             local_nsapi++) {
+
+          sndcp_get_nsapi_sapi(local_nsapi, &local_sapi);
+          if (sapi == local_sapi) {
+            /*
+             * is compressor deactivation necessary?
+             */
+            sndcp_get_nsapi_state(local_nsapi, &nsapi_state);
+            if ((nsapi_state & MG_DEACT) > 0) {
+              mg_is_rel_comp_nec(local_nsapi, &local_nec);
+            }
+          }
+        }
+
+        /*
+         * Negotiate possible deactivation of compressors.
+         */
+        if (local_nec) {
+          mg_send_xid_req_del(sapi);
+        }
+      }
+
+    }
+
+  }
+
+} /* mg_xid_cnf_ok_res */
+
+
+#ifdef TI_DUAL_MODE
+/*
++------------------------------------------------------------------------------
+| Function    : mg_get_unsent_unconfirmed_npdus
++------------------------------------------------------------------------------
+| Description : This procedure retrieves any unsent or unconfirmed acknowledged
+|               NPDU from SNDCP's internal buffers. ANY retrieved NPDU is packed
+|               the primitive SN_GET_PENDING_PDU_CNF data.
+|
+| Parameters  : nsapi, pointer to the primitive.
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL T_SN_GET_PENDING_PDU_CNF* mg_get_unsent_unconfirmed_npdus
+                             (U8 nsapi, 
+                              T_SN_GET_PENDING_PDU_CNF* sn_get_pending_pdu_cnf)
+{
+
+  int count = 0;
+  U8 used_sapi=0, sapi_index=0;
+  T_NPDU_BUFFER* help = NULL;
+
+  TRACE_FUNCTION( "mg_get_unsent_unconfirmed_npdus" );
+
+  /*
+   * set service instance according to nsapi in primitive
+   */
+  sndcp_data->nu = & sndcp_data->nu_base[nsapi];
+
+  /*
+   * Find number of unconfirmed NPDUs
+   */
+  help = sndcp_data->nu->first_buffered_npdu;
+  while(help != NULL)
+  {
+    count++;
+    help = help->next;
+  }
+
+  sn_get_pending_pdu_cnf->ul_pdus[nsapi].ptr_desc_list2 = 
+           (T_SN_desc_list2*)DRP_ALLOC( count * sizeof( T_SN_desc_list2 ), 0 );
+
+  sn_get_pending_pdu_cnf->ul_pdus[nsapi].nsapi = nsapi;
+  sn_get_pending_pdu_cnf->ul_pdus[nsapi].dl_sequence_number = 
+                                           sndcp_data->nu->rec_npdu_number_ack;
+  sn_get_pending_pdu_cnf->ul_pdus[nsapi].c_desc_list2 = count;
+
+  count = 0;
+
+  /*
+   * Check if there are buffered any acknowledged type NPDUs.
+   */
+  help = sndcp_data->nu->first_buffered_npdu;
+  while(help != NULL)
+  {
+
+    sn_get_pending_pdu_cnf->ul_pdus[nsapi].ptr_desc_list2[count].first = 
+                                        help->sn_data_req->desc_list2.first;
+    sn_get_pending_pdu_cnf->ul_pdus[nsapi].ptr_desc_list2[count].list_len = 
+                                        help->sn_data_req->desc_list2.list_len;
+    count++;
+    help = help->next;
+  }
+  return sn_get_pending_pdu_cnf;
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_clean_ack_npdu_queues_leave_data
++------------------------------------------------------------------------------
+| Description : This procedure deletes SNDCP's internal buffers containing
+|               unconfirmed acknowledged type NPDU's.
+|               The data stored in the queues are not deleted.
+|
+| Parameters  : nsapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_clean_ack_npdu_queues_leave_data(U8 nsapi)
+{
+
+  U8 used_sapi=0, sapi_index=0;
+  T_NPDU_BUFFER* help = NULL;
+  T_SN_DATA_REQ* sn_data_req = NULL;
+
+  TRACE_FUNCTION( "mg_clean_ack_npdu_queues_leave_data" );
+
+   /*
+    * set service instance according to sapi
+    */
+  sndcp_get_nsapi_sapi(nsapi, &used_sapi);
+  sndcp_get_sapi_index(used_sapi, &sapi_index);
+  sndcp_data->sua = & sndcp_data->sua_base[sapi_index];
+
+  if (sndcp_data->sua->sn_data_q_write != sndcp_data->sua->sn_data_q_read) 
+  {
+    /*
+     * remove unhandled sn_data_req from queue.
+     */
+    sn_data_req = sndcp_data->sua->sn_data_q[sndcp_data->sua->sn_data_q_read];
+    FREE(sn_data_req);
+  }
+
+  /*
+   * set service instance according to nsapi
+   */
+
+  sndcp_data->nu = & sndcp_data->nu_base[nsapi];
+
+  /*
+   * clean buffer with unconfirmed NPDUs
+   */
+
+  while(sndcp_data->nu->first_buffered_npdu != NULL)
+  {
+    help = sndcp_data->nu->first_buffered_npdu;
+    sndcp_data->nu->first_buffered_npdu = help->next;
+    MFREE(help->sn_data_req);
+    MFREE(help);
+  }
+}
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : mg_clean_unack_npdu_queues_including_data
++------------------------------------------------------------------------------
+| Description : This procedure deletes SNDCP's internal buffers containing
+|               unacknowledged type NPDU's.
+|               The data stored in the queues are also deleted.
+|
+| Parameters  : nsapi
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void mg_clean_unack_npdu_queues_including_data(U8 nsapi)
+{
+  /*
+   * Delete affected N-PDUS from sn_unitdata_q.
+   */
+  BOOL still = TRUE;
+  U8 index = sndcp_data->su->sn_unitdata_q_read;
+
+  while (still) 
+  {
+    if (index == sndcp_data->su->sn_unitdata_q_write) {
+      break;
+    }
+    if (sndcp_data->su->sn_unitdata_q[index]->nsapi == nsapi) {
+      /*
+       * The index for the prims to be shifted when 1 entry is deleted.
+       */
+      U8 i = 0;
+
+      if (sndcp_data->su->sn_unitdata_q[index] != NULL) {
+        PFREE_DESC2(sndcp_data->su->sn_unitdata_q[index]);
+        sndcp_data->su->sn_unitdata_q[index] = NULL;
+      }
+
+      for (i = index;
+           i != sndcp_data->su->sn_unitdata_q_write;
+           i = (i + 1) % SN_UNITDATA_Q_LEN) 
+           {
+              sndcp_data->su->sn_unitdata_q[i] =
+                sndcp_data->su->sn_unitdata_q[(i + 1) % SN_UNITDATA_Q_LEN];
+
+              sndcp_data->su->sn_unitdata_q[(i + 1) % SN_UNITDATA_Q_LEN]=NULL;
+           }
+      sndcp_data->su->sn_unitdata_q_write =
+        (sndcp_data->su->sn_unitdata_q_write - 1
+         + SN_UNITDATA_Q_LEN) % SN_UNITDATA_Q_LEN;
+    } 
+    else 
+    {
+      index = (index + 1) % SN_UNITDATA_Q_LEN;
+    } /* else (sndcp_data->su->sn_unitdata_q[index]->nsapi == nsapi) */
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : sm_make_test_pending_pdu_cnf
++------------------------------------------------------------------------------
+| Description : Initialize SN_TEST_GET_PENDING_PDU_CNF primitive
+| Parameters  : sn_get_pending_pdu_cnf - primitive  
+|               sn_test_get_pending_pdu_cnf - primitive 
+|
++------------------------------------------------------------------------------
+*/
+
+GLOBAL void sm_make_test_pending_pdu_cnf
+                   (T_SN_GET_PENDING_PDU_CNF* sn_get_pending_pdu_cnf,
+                    T_SN_TEST_GET_PENDING_PDU_CNF* sn_test_get_pending_pdu_cnf)
+{
+  int i,j;
+
+  for (i = 0; i < SN_SIZE_NSAPI; i++) {
+    sn_test_get_pending_pdu_cnf->c_test_ul_pdus = 
+                         sn_get_pending_pdu_cnf->c_ul_pdus;
+    sn_test_get_pending_pdu_cnf->test_ul_pdus[i].nsapi = 
+                         sn_get_pending_pdu_cnf->ul_pdus[i].nsapi;
+    sn_test_get_pending_pdu_cnf->test_ul_pdus[i].test_dl_sequence_number = 
+                         sn_get_pending_pdu_cnf->ul_pdus[i].dl_sequence_number;
+    sn_test_get_pending_pdu_cnf->test_ul_pdus[i].c_test_desc_list2 = 
+                         sn_get_pending_pdu_cnf->ul_pdus[i].c_desc_list2;
+
+    if (sn_get_pending_pdu_cnf->ul_pdus[i].c_desc_list2) {
+      for(j = 0; j < sn_get_pending_pdu_cnf->ul_pdus[i].c_desc_list2; j++) {
+        sn_test_get_pending_pdu_cnf->test_ul_pdus[i].c_test_desc_list2 = 
+                 sn_get_pending_pdu_cnf->ul_pdus[i].c_desc_list2;
+        sn_test_get_pending_pdu_cnf->test_ul_pdus[i].test_desc_list2[j].c_test_pending_pdu = 
+             (U8)sn_get_pending_pdu_cnf->ul_pdus[i].ptr_desc_list2[j].list_len;
+        memcpy(
+          sn_test_get_pending_pdu_cnf->test_ul_pdus[i].test_desc_list2[j].test_pending_pdu,
+          ((T_desc2 *)sn_get_pending_pdu_cnf->ul_pdus[i].ptr_desc_list2[j].first)->buffer, 
+          sn_get_pending_pdu_cnf->ul_pdus[i].ptr_desc_list2[j].list_len);
+      }
+    }
+  }
+}
+
+#endif /*#ifdef TI_DUAL_MODE*/