view src/g23m-gsm/dl/dl_dph.c @ 275:79cfefc1e2b4

audio mode load: gracefully handle mode files of wrong AEC version Unfortunately our change of enabling L1_NEW_AEC (which is necessary in order to bring our Calypso ARM fw into match with the underlying DSP reality) brings along a change in the audio mode file binary format and file size - all those new tunable AEC parameters do need to be stored somewhere, after all. But we already have existing mode files in the old format, and setting AEC config to garbage when loading old audio modes (which is what would happen without the present change) is not an appealing proposition. The solution implemented in the present change is as follows: the audio mode loading code checks the file size, and if it differs from the active version of T_AUDIO_MODE, the T_AUDIO_AEC_CFG structure is cleared - set to the default (disabled AEC) for the compiled type of AEC. We got lucky in that this varying T_AUDIO_AEC_CFG structure sits at the end of T_AUDIO_MODE!
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 30 Jul 2021 02:55:48 +0000
parents fa8dc04885d8
children
line wrap: on
line source

/*
+-----------------------------------------------------------------------------
|  Project :  GSM-PS
|  Modul   :  DL_DPH
+-----------------------------------------------------------------------------
|  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 defines the functions for distributing
|             all primitives of the lower layers.
+-----------------------------------------------------------------------------
*/

#ifndef DL_DPH_C
#define DL_DPH_C

#define ENTITY_DL

/*==== INCLUDES ===================================================*/

#include "typedefs.h"
#include <string.h>
#include "pconst.cdg"
#include "vsi.h"
#include "pconst.cdg"
#include "custom.h"
#include "gsm.h"
#include "mon_dl.h"
#include "prim.h"
#include "pei.h"
#include "tok.h"
#include "ccdapi.h"
#include "dl.h"
#include "dl_trc.h"

/*==== EXPORT =====================================================*/

/*==== PRIVAT =====================================================*/
#if defined(_SIMULATION_) && !defined(DL_2TO1)
LOCAL void dph_ph_data_req (T_PH_DATA_REQ * data_req);
#endif /* _SIMULATION_ && !DL_2TO1 */

#if defined(DL_2TO1) || defined(USE_L1M_GS001_1)
LOCAL U8 convert_dcch_ch_type (U8 channel_type);
#endif  /* DL_2TO1 || USE_L1M_GS001_1 */

LOCAL void dl_process_downlink (UBYTE error_flag, UBYTE channel_type,
                                UBYTE * frame, ULONG fn);

/*==== VARIABLES ==================================================*/

/*==== FUNCTIONS ==================================================*/
#if defined(DL_2TO1)
#if defined(_SIMULATION_)
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dph_ph_ready_to_send       |
+--------------------------------------------------------------------+

  PURPOSE : Reception of a PH_READY_TO_SEND primitive.
            Uplink opportunity for simulation.

*/

GLOBAL void l1test_call_mphc_read_dcch (T_L1TEST_CALL_MPHC_READ_DCCH * ready)
{
  UBYTE  no_signalling_flag = NO_SIGNALLING;
  T_RADIO_FRAME *frame = NULL;

  GET_INSTANCE_DATA;  
  dl_data->dl_active = FALSE;

  switch (ready->chn_mode)
  {
    case CM_SIGNALLING_ONLY:
      /*
      * Take over the behaviour of dll_read_dcch():
      * No ch_type is given by the layer 1 for SDCCH and FACCH,
      * the first parameter ch_type of the fuction dl1_uplink_ind() get a
      * value set to zero.
      */
      no_signalling_flag = SIG_ONLY;
      break;
    default:
      break;
  }

  frame = dl1_uplink_ind (0, no_signalling_flag);

  if (frame)
  {
    l1test_return_mphc_read_dcch (frame);
  }

  MY_PFREE (ready);
}

GLOBAL void l1test_call_mphc_read_sacch (T_L1TEST_CALL_MPHC_READ_SACCH * ready)
{
  T_RADIO_FRAME *frame = NULL;

  GET_INSTANCE_DATA;
  dl_data->dl_active = FALSE;

  frame = dl1_uplink_ind (L2_CHANNEL_SACCH, SIG_ONLY);
  if (frame)
  {
    l1test_return_mphc_read_sacch (frame);
  }

  MY_PFREE (ready);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dph_ph_data_req            |
+--------------------------------------------------------------------+

  PURPOSE : Sending of a PH_DATA_REQ primitive.
            Uplink for simulation.

*/

GLOBAL void l1test_return_mphc_read_dcch (T_RADIO_FRAME * frame)
{
  PALLOC(data_req, L1TEST_RETURN_MPHC_READ_DCCH);

  TRACE_FUNCTION ("l1test_return_mphc_read_dcch()");

  memcpy(data_req->l2_frame.frame_array, frame->frame_array, sizeof(data_req->l2_frame));
  PSEND (hCommPL, data_req);
}

GLOBAL void l1test_return_mphc_read_sacch (T_RADIO_FRAME * frame)
{
  PALLOC(data_req, L1TEST_RETURN_MPHC_READ_SACCH);

  TRACE_FUNCTION ("l1test_return_mphc_read_sacch()");

  memcpy(data_req->l2_frame.frame_array, frame->frame_array, sizeof(data_req->l2_frame));
  PSEND (hCommPL, data_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : l1test_call_mphc_dcch_downlink            |
+--------------------------------------------------------------------+

  PURPOSE : Reception of a L1TEST_CALL_MPHC_DCCH_DOWNLINK primitive.

*/

GLOBAL void l1test_call_mphc_dcch_downlink (T_L1TEST_CALL_MPHC_DCCH_DOWNLINK * data_ind)
{
  /*
  * Take over the behaviour of dll_dcch_downlink():
  * No ch_type is given by the layer 1 for SDCCH and FACCH,
  * the second parameter ch_type of the function dl_process_downlink() get a
  * value set to zero.
  */
  dl_data->dl_active = FALSE;

  dl_process_downlink (data_ind->valid_flag, 0, data_ind->l2_frame.frame_array, NOT_PRESENT_32BIT);

  MY_PFREE (data_ind);
}
#endif  /* _SIMULATION_ */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dph_ph_data_ind            |
+--------------------------------------------------------------------+

  PURPOSE : Reception of a PH_DATA_IND primitive.
            This function is only available in stacks >= TCS5 (DL_2TO1).
            A function with the same name exist for the old GSM/GPRS stack.

            It is used for SACCH downlink on target as well as on simulation.
            In opposite to the old GSM/GPRS stack, a functional interface
            (l1test_call_mphc_dcch_downlink) is used by the dual mode stack
            implementation for SDCCH and FACCH during simulation. Therefore
            this function is only used for SACCH.

*/

GLOBAL void dph_ph_data_ind (T_MPHC_PH_DATA_IND * data_ind)
{
  /*
  * Take over the behaviour of dll_dcch_downlink():
  * No ch_type is given by the layer 1 for SDCCH and FACCH,
  * the second parameter ch_type of the function dl_process_downlink() get a
  * value set to zero.
  */

  TRACE_FUNCTION ("dph_ph_data_ind() 2TO1");

  if (data_ind->l2_channel_type EQ L2_CHANNEL_SACCH)
    dl_process_downlink (data_ind->error_cause,
                         L2_CHANNEL_SACCH,
                         data_ind->l2_frame.frame_array,
                         NOT_PRESENT_32BIT);

  MY_PFREE (data_ind);
}

#else /* DL_2TO1 */

#if defined(_SIMULATION_)
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dph_ph_ready_to_send       |
+--------------------------------------------------------------------+

  PURPOSE : Reception of a PH_READY_TO_SEND primitive.
            Uplink opportunity for simulation.

*/

GLOBAL void dph_ph_ready_to_send (T_PH_READY_TO_SEND * ready)
{
  UBYTE   no_signalling_flag = SIG_ONLY;
  T_RADIO_FRAME *frame;
  UBYTE   ch_type;
  switch (ready->ch_type)
  {
    case L2_CHANNEL_FACCH_F:
    case L2_CHANNEL_FACCH_H:
      no_signalling_flag = NO_SIGNALLING;
      /*lint -fallthrough */
    case L2_CHANNEL_SDCCH:
      /*
      * Take over the behaviour of dll_read_dcch():
      * No ch_type is given by the layer 1 for SDCCH and FACCH,
      * the first parameter ch_type of the function dl1_uplink_ind() get a
      * value set to zero.
      */
      ch_type = 0;
      break;
    default:
      ch_type = ready->ch_type;
      break;
  }

  frame = dl1_uplink_ind (ch_type, no_signalling_flag);
  if (frame)
  {
    PALLOC_SDU (data, PH_DATA_REQ, 23*BITS_PER_BYTE);/* T_PH_DATA_REQ */

    /*
     * In case the value of ready->ch_type was set to zero above it has to set
     * to the value of dcch0_ch_type corresponding the behaviour of the
     * function dl1_uplink_ind().
    if (ready->ch_type EQ 0)
    {
      T_DL_DATA *dl_data = dl_get_data ();
      ready->ch_type = dl_data->dcch0_ch_type ? dl_data->dcch0_ch_type : L2_CHANNEL_SDCCH;
    }
    */

    memcpy (data->sdu.buf, frame, 23);/*lint !e419 (Warning -- Apparent data overrun) */
    if (ready->ch_type EQ L2_CHANNEL_SACCH)
    {
      data->sdu.buf[0] = 0;/* layer 1 header occupies 2 bytes */
      data->sdu.buf[1] = 0;/*lint !e415 (Warning -- access of out-of-bounds pointer) */
      data->sdu.o_buf = 2 * BITS_PER_BYTE;
      data->sdu.l_buf = 21 * BITS_PER_BYTE;
    }
    else
    {
      data->sdu.o_buf = 0;
      data->sdu.l_buf = 23 * BITS_PER_BYTE;
    }
    data->ch_type = ready->ch_type;
    dph_ph_data_req (data);
  }

  MY_PFREE (ready);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dph_ph_data_req            |
+--------------------------------------------------------------------+

  PURPOSE : Sending of a PH_DATA_REQ primitive.
            Uplink for simulation.

*/

LOCAL void dph_ph_data_req (T_PH_DATA_REQ * data_req)
{
  TRACE_FUNCTION ("dph_ph_data_req()");

#if defined(DL_TRACE_WIN32)
  if (data_req->ch_type EQ L2_CHANNEL_SACCH)
  {
    /*lint -e416 (Warning -- creation of out-of-bounds pointer) */
    FTRC (data_req->ch_type, data_req->sdu.buf+2, 1); /* uplink SACCH */
    /*lint +e416 (Warning -- creation of out-of-bounds pointer) */
  }
  else
  {
    FTRC (data_req->ch_type, data_req->sdu.buf, 1); /* uplink other */
  }
#endif  /* DL_TRACE_WIN32 */

  PSENDX (PL, data_req);
}
#endif  /* _SIMULATION */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dph_ph_data_ind            |
+--------------------------------------------------------------------+

  PURPOSE : Reception of a PH_DATA_IND primitive.
            This function is only available in the old GSM/GPRS stack (<= TCS4).
            A function with the same name exist for the dual mode stack.

            It can be used for SACCH downlink on target as well as on simulation.
            During simulation the old GSM/GPRS stack uses this primitive
            function for SDCCH and FACCH also. In this case it takes over the
            functional interface dll_dcch_downlink().
            In the current implementation of the old GSM/GPRS stack the ALR
            queue is exclusively used for incoming PH_DATA_IND primitives from
            L1 for target builds. Only Acknowledged frames (SAPI=3) and frames
            with Bter format (short PD header) are forwarded to DL and handled
            by this function.

*/

GLOBAL void dph_ph_data_ind (T_PH_DATA_IND * ph_data_ind)
{
  if (ph_data_ind)
  {
    #if defined(_SIMULATION_)
      /*
      * Take over the behaviour of dll_dcch_downlink():
      * No ch_type is given by the layer 1 for SDCCH and FACCH,
      * the first parameter ch_type of the function dl_process_downlink() get a
      * value set to zero.
      */
      switch (ph_data_ind->l2_channel_type)
      {
        case L2_CHANNEL_SDCCH:
        case L2_CHANNEL_FACCH_F:
        case L2_CHANNEL_FACCH_H:
          ph_data_ind->l2_channel_type = 0;
          break;
        default:
          break;
      }
    #else  /* _SIMULATION */
      if (ph_data_ind->l2_channel_type EQ L2_CHANNEL_SACCH)
    #endif  /* _SIMULATION */
        dl_process_downlink (ph_data_ind->error_cause,
                             ph_data_ind->l2_channel_type,
                             ph_data_ind->l2_frame.A,
                             NOT_PRESENT_32BIT);

    MY_PFREE (ph_data_ind);
  }
}
#endif /* DL_2TO1 */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dl_process_downlink        |
+--------------------------------------------------------------------+

  PURPOSE : really processing of layer 2 frame downlink.

*/
LOCAL void dl_process_downlink (UBYTE error_flag, UBYTE channel_type, UBYTE * frame, ULONG fn)
{
  GET_INSTANCE_DATA; 

  TRACE_FUNCTION ("dll_process_downlink()");

  /* set the active dedicated channel type if necessary */
  if (channel_type EQ 0)
  {
    TRACE_EVENT_WIN_P3 ("dl_process_downlink(%u,) -> ch=%u FN=%d", channel_type, dl_data->dcch0_ch_type, ((int)fn));
    channel_type = dl_data->dcch0_ch_type  ? dl_data->dcch0_ch_type : L2_CHANNEL_SDCCH;
  }
  else
  {
    TRACE_EVENT_WIN_P1 ("dl_process_downlink(%u,)", channel_type);
  }

  if (channel_type NEQ L2_CHANNEL_SACCH)
    dl_data->interrupt_context = TRUE;

  if (fn NEQ NOT_PRESENT_32BIT)
    dl_data->fn = fn;

#if defined(DL_TRACE_ENABLED)
  {
    UCHAR trace_channel = TRACE_CH_UNKNOWN;
    UCHAR frame_sapi;

    switch (channel_type)
    {
    case L2_CHANNEL_SACCH:
      frame_sapi = ((*(frame + 2)) & 0x1c) >> 2;
      if (frame_sapi EQ PS_SAPI_0)
        trace_channel = C_DCCH0;
      else if (frame_sapi EQ PS_SAPI_3)
        trace_channel = C_DCCH3;
      break;
    case L2_CHANNEL_SDCCH:
      frame_sapi = ((*frame) & 0x1c) >> 2;
      if (frame_sapi EQ PS_SAPI_0)
        trace_channel = C_DCCH0;
      else if (frame_sapi EQ PS_SAPI_3)
        trace_channel = C_DCCH3;
      break;
    case L2_CHANNEL_FACCH_F:
    case L2_CHANNEL_FACCH_H:
      frame_sapi = ((*frame) & 0x1c) >> 2;
      if (frame_sapi EQ PS_SAPI_0)
        trace_channel = C_DCCH0;
      break;
    default:
      break;
    }/* endswitch chan */
    if (error_flag EQ VALID_BLOCK)
    {
      DL_OFFLINE_TRACE (TRACE_DOWNLINK, trace_channel, channel_type, &frame[0]);
    }
  }
#endif /* DL_TRACE_ENABLED */

#if defined(DL_TRACE_WIN32)
  if (error_flag EQ VALID_BLOCK)
  {
    if (channel_type EQ L2_CHANNEL_SACCH)
      FTRC (channel_type, frame+2, 0); /* downlink SACCH */
    else
      FTRC (channel_type, frame, 0); /* downlink other */
  }
#endif /* DL_TRACE_WIN32 */

  if (channel_type EQ 0)
  {
    DL_OFFLINE_TRACE (TRACE_DL_EVENT, TRACE_CH_UNKNOWN, channel_type, "DL:no valid channel type");
  }
  else
  {
    dl_downlink (error_flag, channel_type, &frame[0], fn);
  }

  dl_data->interrupt_context = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dl1_uplink_ind             |
+--------------------------------------------------------------------+

  PURPOSE : Functional Interface for the uplink direction of the
            logical channels SACCH/SDCCH/FACCH.
            (only used by the target)

*/
GLOBAL T_RADIO_FRAME * dl1_uplink_ind (UBYTE channel_type, UBYTE no_signalling_flag)
{
  T_RADIO_FRAME * pRadioFrame;
  UCHAR   channel;
  UCHAR   sapi;
  UCHAR   signalling = SIG_ONLY;

  GET_INSTANCE_DATA; 

  dl_data->interrupt_context = TRUE;

  /* set the active dedicated channel type if necessary */
  if (channel_type EQ 0)
    channel_type = dl_data->dcch0_ch_type;

  TRACE_EVENT_WIN_P1 ("dl1_uplink_ind(ch_type=%u,)", channel_type);

  switch (channel_type)
  {
    case L2_CHANNEL_SACCH:
      /*
       * The priority arrangement on the SACCH must ensure that if a SAPI = 3
       * frame is awaiting transmission, two SAPI = 0 frames are not sent in
       * consecutive SACCH frames. In addition, for the mobile to network
       * direction it must also be ensured that any SAPI = 3 frame is followed
       * by at least one SAPI = 0 frame.
       *
       * SAPI = 3 is set as default value. The function dl_uplink() together with
       * the variable 'sacch_last_uplink_sapi' determind the actual value.
       * e.g. if last uplinked SACCH frame was one with SAPI=3
       *       or
       *      if no SACCH SAPI=3 frame is awaiting transmission
       *      then a SACCH SAPI=0 frame should be uplinked
       */
      channel = C_SACCH0;
      sapi = PS_SAPI_3;
      TRACE_EVENT_WIN_P2 ("dl1_uplink_ind(%s, %s)",
        CH_TYPE_NAME[channel_type], signalling EQ SIG_ONLY?"SIG_ONLY":"NO_SIGNALLING");
      break;

    default:
      TRACE_ERROR ("dl1_uplink_ind():no valid channel type, use SDCCH instead");
      channel_type = L2_CHANNEL_SDCCH;
      /*lint -fallthrough*/
    case L2_CHANNEL_FACCH_F:
    case L2_CHANNEL_FACCH_H:
    case L2_CHANNEL_SDCCH:
      /*
       * build frame for SAPI = 3 will be called (with lower priority)
       * if no data is waiting for SAPI = 0.
       */
      channel = C_DCCH0;
      sapi = PS_SAPI_0;
      dl_data->cch[channel].ch_type = channel_type;
      signalling = no_signalling_flag;
      TRACE_EVENT_WIN_P3 ("dl1_uplink_ind(%s, %s) SAPI=%u",
        CH_TYPE_NAME[channel_type], signalling EQ SIG_ONLY?"SIG_ONLY":"NO_SIGNALLING",
        sapi);
      break;
  }

  pRadioFrame= dl_uplink (channel, sapi, signalling, FALSE);
  if (pRadioFrame)
  {
#ifndef DL_2TO1
    DL_OFFLINE_TRACE (TRACE_UPLINK, channel, channel_type, &pRadioFrame->A[0]);
#else
    DL_OFFLINE_TRACE (TRACE_UPLINK, channel, channel_type, &pRadioFrame->frame_array[0]);
#endif
  }

  dl_data->interrupt_context = FALSE;
  return pRadioFrame;  /* return pointer to frame to layer 1 */
}

#if defined(DL_2TO1) || defined(USE_L1M_GS001_1)
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : convert_dcch_ch_type       |
+--------------------------------------------------------------------+

  PURPOSE : Converts dedicated channel types to layer 2 channel types
            according to L1M_GS001_1 and L1M_GS001_3.

*/
LOCAL U8 convert_dcch_ch_type (U8 channel_type)
{
  UBYTE ch_type;
  switch (channel_type)
  {
    case MPHC_CH_TCH_F:  ch_type = L2_CHANNEL_FACCH_F;break;
    case MPHC_CH_TCH_H:  ch_type = L2_CHANNEL_FACCH_H;break;
    case MPHC_CH_SDCCH_4:
    case MPHC_CH_SDCCH_8:ch_type = L2_CHANNEL_SDCCH;break;
  }
  return ch_type;
}
#endif  /* DL_2TO1 || USE_L1M_GS001_1 */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dll_read_dcch              |
+--------------------------------------------------------------------+

  PURPOSE : Functional Interface for the uplink direction of
            SDCCH/FACCH. Only used by the TI target, look into
            TI interface S922 or L1M_GS001_1.

*/
#if defined(DL_2TO1) || defined(USE_L1M_GS001_1)
GLOBAL T_RADIO_FRAME * dll_read_dcch (U8 chn_mode, U8 channel_type)
{
  return dl1_uplink_ind(convert_dcch_ch_type(channel_type), chn_mode);
}
#else  /* DL_2TO1 || USE_L1M_GS001_1 */
GLOBAL T_RADIO_FRAME * dll_read_dcch (U8 chn_mode)
{
  /* 0 stands for the currently active SDCCH and FACCH channel type */
  return dl1_uplink_ind(0, chn_mode);
}
#endif  /* DL_2TO1 || USE_L1M_GS001_1 */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dll_read_sacch             |
+--------------------------------------------------------------------+

  PURPOSE : Functional Interface for the uplink direction of SACCH.
            Only used by the TI target, look into
            TI interface S922 or L1M_GS001_1.

*/
GLOBAL T_RADIO_FRAME * dll_read_sacch (UBYTE chn_mode)
{
  return dl1_uplink_ind (L2_CHANNEL_SACCH, SIG_ONLY);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : DL_DPH                     |
| STATE   : code                ROUTINE : dll_dcch_downlink          |
+--------------------------------------------------------------------+

  PURPOSE : Functional Interface for the downlink direction of
            FACCH/DCCH. Only used by the TI target, look into
            TI interface S922 or L1M_GS001_1.

*/
#if defined(DL_2TO1) || defined(USE_L1M_GS001_1)
GLOBAL void dll_dcch_downlink(U32 * data_ptr, U8 valid_flag, U8 channel_type, U32 fn)
{
  if ((data_ptr NEQ NULL) AND (valid_flag EQ DATA_VALID))
  {
    dl_process_downlink (VALID_BLOCK, convert_dcch_ch_type(channel_type),
                         (UBYTE *)data_ptr, fn);
  }
}
#else  /* DL_2TO1 || USE_L1M_GS001_1 */
#if defined(SEND_FN_TO_L2_IN_DCCH) && (SEND_FN_TO_L2_IN_DCCH == 1)
  GLOBAL void dll_dcch_downlink(U32 * data_ptr, U8 valid_flag, U32 fn)
  {
    if ((data_ptr NEQ NULL) AND valid_flag)
    {
      /*
       * channel type 0 stands for currently active dedicated
       * SDCCH or FACCH channel type
       */
      dl_process_downlink (VALID_BLOCK, 0, (UBYTE *)data_ptr, fn);
    }
  }
#else /* SEND_FN_TO_L2_IN_DCCH == 1 */
  GLOBAL void dll_dcch_downlink(U32 * data_ptr, U8 valid_flag)
  {
    if ((data_ptr NEQ NULL) AND valid_flag)
    {
      /*
       * channel type 0 stands for currently active dedicated
       * SDCCH or FACCH channel type
       */
      dl_process_downlink (VALID_BLOCK, 0, (UBYTE *)data_ptr, NOT_PRESENT_32BIT);
    }
  }
#endif /* SEND_FN_TO_L2_IN_DCCH == 1 */
#endif  /* DL_2TO1 || USE_L1M_GS001_1 */
#endif /* DL_DPH_C */