view src/aci2/alr/alr_em.c @ 636:57e67ca2e1cb

pcmdata.c: default +CGMI to "FreeCalypso" and +CGMM to model The present change has no effect whatsoever on Falconia-made and Openmoko-made devices on which /pcm/CGMI and /pcm/CGMM files have been programmed in FFS with sensible ID strings by the respective factories, but what should AT+CGMI and AT+CGMM queries return when the device is a Huawei GTM900 or Tango modem that has been converted to FreeCalypso with a firmware change? Before the present change they would return compiled-in defaults of "<manufacturer>" and "<model>", respectively; with the present change the firmware will self-identify as "FreeCalypso GTM900-FC" or "FreeCalypso Tango" on the two respective targets. This firmware identification will become important if someone incorporates an FC-converted GTM900 or Tango modem into a ZeroPhone-style smartphone where some high-level software like ofono will be talking to the modem and will need to properly identify this modem as FreeCalypso, as opposed to some other AT command modem flavor with different quirks. In technical terms, the compiled-in default for the AT+CGMI query (which will always be overridden by the /pcm/CGMI file in FFS if one is present) is now "FreeCalypso" in all configs on all targets; the compiled-in default for the AT+CGMM query (likewise always overridden by /pcm/CGMM if present) is "GTM900-FC" if CONFIG_TARGET_GTM900 or "Tango" if CONFIG_TARGET_TANGO or the original default of "<model>" otherwise.
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 19 Jan 2020 20:14:58 +0000
parents 93999a60b835
children
line wrap: on
line source

/*
+-----------------------------------------------------------------------------
|  Project :
|  Modul   :
+-----------------------------------------------------------------------------
|  Copyright 2002 Texas Instruments Berlin, AG
|                 All rights reserved.
|
|                 This file is confidential and a trade secret of Texas
|                 Instruments Berlin, AG
|                 The receipt of or possession of this file does not convey
|                 any rights to reproduce or disclose its contents or to
|                 manufacture, use, or sell anything it may describe, in
|                 whole, or in part, without the specific written consent of
|                 Texas Instruments Berlin, AG.
+-----------------------------------------------------------------------------
|  Purpose :  This Module defines the engineering mode (EM) device driver for the
|             G23 protocol stack. This driver is used to control all engineering
|             mode related functions.
+-----------------------------------------------------------------------------
*/

#ifndef ALR_EM_C
#define ALR_EM_C

#define ENTITY_PL

/*==== INCLUDES ===================================================*/
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "typedefs.h"
#include "pconst.cdg"
#include "mconst.cdg"
#include "message.h"
#include "ccdapi.h"
#include "vsi.h"
#include "custom.h"
#include "gsm.h"
#include "prim.h"
#include "cnf_alr.h"
#include "mon_alr.h"
#include "pei.h"
#include "tok.h"
#include "pcm.h"

#ifdef GPRS
#include "alr_gprs.h"
#endif

#ifdef GPRS
#ifdef _TARGET_
#include "inth/iq.h"
#endif
/*
 *	obsolete (msb / 2002-04-25)
#include "armio/armio.h"
 */
#endif

#include "alr.h"
#include "alr_em.h"


/*==== IMPORT =====================================================*/

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

/*==== PRIVAT =====================================================*/

/*==== VARIABLES ==================================================*/
#if defined (FF_EM_MODE) AND defined (ALR)

/* Event tracing flags for EM */
GLOBAL BOOL alr_v[EM_MAX_ALR_EVENTS];

LOCAL  UBYTE             em_alr_trace_occured = 0;


/*
  These variables are used between entities. Even this is not a clean solution it is a straigth forward
  way to reduce the overhead to a minimum. A clean solution would be based on an only usage of primitives
  which would stress the os with no aditional advantage!!
*/
GLOBAL volatile  UBYTE             em_l1_sem_buffer [EM_L1_SEM_SIZE];    /*lint -esym(765,em_l1_sem_buffer) | external could be made static | used externally  */
GLOBAL volatile  UBYTE             em_l1_sem_index  = 0;								 /*lint -esym(765,em_l1_sem_index)  | external could be made static | used externally  */

static T_HANDLE  sem_EM_L1;

#define ENTER_CRITICAL_SECTION(sem) if (alr_em_enter_critical_section(sem))return FALSE;
#define LEAVE_CRITICAL_SECTION(sem) if (alr_em_leave_critical_section(sem))return FALSE;

#endif /* FF_EM_MODE */

/*==== FUNCTIONS ==================================================*/
#if defined (FF_EM_MODE) AND defined (ALR)

LOCAL  UBYTE em_l1_sem       (UBYTE length, UBYTE * data);
LOCAL  int   em_l1_sem_clear (void);
LOCAL  void  alr_em_first_event_check (void); /*Check for ACI - Notification*/

static void alr_em_semaphore_err (void);

#if !defined(SYST_TRACE)
#define SYST_TRACE(a) vsi_o_ttrace(0, TC_SYSTEM, a);
#endif  /* !SYST_TRACE */

static int alr_em_enter_critical_section (T_HANDLE sem);
static int alr_em_leave_critical_section (T_HANDLE sem);


/*
+------------------------------------------------------------------------------
|  Function     : em_init_l1_event_trace
+------------------------------------------------------------------------------
|  Description  :  Initialize the event tracing flags
|
|  Parameters   :
|
|  Return       :
|
+------------------------------------------------------------------------------
*/
GLOBAL void em_init_l1_event_trace(void)
{
 UBYTE i;

 TRACE_FUNCTION("em_init_l1_event_trace ()");

 for(i=0; i<EM_MAX_ALR_EVENTS; i++)
   alr_v[i] = 0;
}

/*
+------------------------------------------------------------------------------
|  Function     : l1_em_l1_event_req
+------------------------------------------------------------------------------
|  Description  :  Set the event tracing flags according the bitmask
|
|  Parameters   :  Primitive    - Bitmask
|
|  Return       :
|
+------------------------------------------------------------------------------
*/

GLOBAL const void l1_em_l1_event_req (T_EM_L1_EVENT_REQ *em_l1_event_req)
{
 UBYTE i;

 TRACE_FUNCTION("l1_em_l1_event_req ()");

 /*
  *  The event tracing flags are set according the bitmask. alr_v[i] are
  *  the flags belonging to the event number described in 8443.601
 */
 for(i=1; i<33; i++)  {
   alr_v[i] = ((em_l1_event_req->bitmask_l1_l & (0x01<<(i-1))) > 0) ? TRUE : FALSE;
 }

 for(i=33; i<(EM_MAX_ALR_EVENTS); i++)  {
   alr_v[i] = ((em_l1_event_req->bitmask_l1_h & (0x01<<(i-1))) > 0) ? TRUE : FALSE;
 }

 /*
  * A new event trace is generated therefor the flag is set to zero.
 */
 em_alr_trace_occured = 0;

 PFREE(em_l1_event_req);
}

/*
+------------------------------------------------------------------------------
|  Function     : em_write_buffer_2
+------------------------------------------------------------------------------
|  Description  :  Perform buffer check and store corresponding data in it.
|
|  Parameters   :  Event number
|
|  Return       :  TRUE/FALSE
|
+------------------------------------------------------------------------------
*/
GLOBAL UBYTE em_write_buffer_2 (UBYTE event_no)
{
 UBYTE em_l1_event_buffer[2];
 UBYTE em_l1_buffer_write = 0;
 UBYTE length = 2;

 TRACE_FUNCTION("alr_em_write_buffer_2 ()");

 /*
   ACI is informed about the first event trace, used for later data processing.
 */
 alr_em_first_event_check();

 memset(em_l1_event_buffer, 0, 2);

 em_l1_event_buffer[em_l1_buffer_write++] = event_no;             /* Event number */
 em_l1_event_buffer[em_l1_buffer_write++] = length-2;             /* Value length - 0 equals no data */

 return (em_l1_sem (length, em_l1_event_buffer));               /* Data is stored inside buffer, reset flag */
}

/*
+------------------------------------------------------------------------------
|  Function     : em_write_buffer_3
+------------------------------------------------------------------------------
|  Description  :  Perform buffer check and store corresponding data in it.
|
|  Parameters   :  Event number, data value
|
|  Return       :  TRUE/FALSE
|
+------------------------------------------------------------------------------
*/
GLOBAL UBYTE em_write_buffer_3  (UBYTE event_no, UBYTE value)
{
 UBYTE em_l1_event_buffer[3];
 UBYTE em_l1_buffer_write = 0;
 UBYTE length = 3;

 TRACE_FUNCTION("alr_em_write_buffer_3 ()");

 /*
   ACI is informed about the first event trace, used for later data processing.
 */
 alr_em_first_event_check();

 memset(em_l1_event_buffer, 0, 3);

 em_l1_event_buffer[em_l1_buffer_write++] = event_no;               /* Event number */
 em_l1_event_buffer[em_l1_buffer_write++] = length-2;               /* Value length - 0 equals no value */
 em_l1_event_buffer[em_l1_buffer_write++] = value;                  /* Data to be stored */

 return (em_l1_sem (length, em_l1_event_buffer));                 /* Data is stored inside buffer, reset flag */
}

/*
+------------------------------------------------------------------------------
|  Function     : em_write_buffer_3a
+------------------------------------------------------------------------------
|  Description  :  Perform buffer check and store corresponding data in it.
|
|  Parameters   :  Event number, data value (USHORT)
|
|  Return       :  TRUE/FALSE
|
+------------------------------------------------------------------------------
*/
GLOBAL UBYTE em_write_buffer_3a (UBYTE event_no, USHORT value)
{
 UBYTE em_l1_event_buffer[4];
 UBYTE em_l1_buffer_write = 0;
 UBYTE length = 4;

 TRACE_FUNCTION("alr_em_write_buffer_4 ()");

 /*
   ACI is informed about the first event trace, used for later data processing.
 */
 alr_em_first_event_check();

 memset(em_l1_event_buffer, 0, 4);

 em_l1_event_buffer[em_l1_buffer_write++] = event_no;              /* Event number */
 em_l1_event_buffer[em_l1_buffer_write++] = length-2;              /* Value length - 0 equals no value */
 em_l1_event_buffer[em_l1_buffer_write++] = (UBYTE)(value >> 8);   /* Data to be stored - MSB first */
 em_l1_event_buffer[em_l1_buffer_write++] = (UBYTE)(value);        /* LSB second */

 return (em_l1_sem (length, em_l1_event_buffer));                /* Data is stored inside buffer, reset flag */
}

/*
+------------------------------------------------------------------------------
|  Function     : em_write_buffer_4
+------------------------------------------------------------------------------
|  Description  :  Perform buffer check and store corresponding data in it.
|
|  Parameters   :  Event number, data value1 & value2
|
|  Return       :  TRUE/FALSE
|
+------------------------------------------------------------------------------
*/
GLOBAL UBYTE em_write_buffer_4  (UBYTE event_no, UBYTE value1, UBYTE value2)
{
 UBYTE em_l1_event_buffer[4];
 UBYTE em_l1_buffer_write = 0;
 UBYTE length = 4;

 TRACE_FUNCTION("alr_em_write_buffer_4 ()");

 /*
   ACI is informed about the first event trace, used for later data processing.
 */
 alr_em_first_event_check();

 memset(em_l1_event_buffer, 0, 4);

 em_l1_event_buffer[em_l1_buffer_write++] = event_no;               /* Event number */
 em_l1_event_buffer[em_l1_buffer_write++] = length-2;               /* Value length - 0 equals no value */
 em_l1_event_buffer[em_l1_buffer_write++] = value1;                 /* Data to be stored */
 em_l1_event_buffer[em_l1_buffer_write++] = value2;                 /* Data to be stored */

 return (em_l1_sem (length, em_l1_event_buffer));                 /* Data is stored inside buffer, reset flag */
}

/*
+------------------------------------------------------------------------------
|  Function     : em_l1_sem_init
+------------------------------------------------------------------------------
|  Description  :  Initialize the semaphor for alr event traces.
|
|  Parameters   :  void
|
|  Return       :  void
|
+------------------------------------------------------------------------------
*/
GLOBAL void em_l1_sem_init (void)
{
  sem_EM_L1  = vsi_s_open (VSI_CALLER "EM_L1_SEM",1);

  if (sem_EM_L1 NEQ VSI_ERROR)
    em_l1_sem_clear ();
  else
    SYST_TRACE ("D1:canīt open semaphore \"EM_D1_SEM\"");
}

/*
+------------------------------------------------------------------------------
|  Function     : em_l1_sem_exit
+------------------------------------------------------------------------------
|  Description  :  Close the semaphor for alr event traces.
|
|  Parameters   :  void
|
|  Return       :  void
|
+------------------------------------------------------------------------------
*/
GLOBAL void em_l1_sem_exit (void)
{
  if (sem_EM_L1 NEQ VSI_ERROR)
    vsi_s_close (VSI_CALLER sem_EM_L1);
}

/*
+------------------------------------------------------------------------------
|  Function     : em_l1_sem_clear
+------------------------------------------------------------------------------
|  Description  :  Reset the index of the semaphor.
|
|  Parameters   :  void
|
|  Return       :  UBYTE
|
+------------------------------------------------------------------------------
*/
LOCAL int em_l1_sem_clear (void)
{
  ENTER_CRITICAL_SECTION (sem_EM_L1);
  em_l1_sem_index = 0;
  LEAVE_CRITICAL_SECTION (sem_EM_L1);

  SYST_TRACE ("L1:em_l1_sem_index cleared");
  return TRUE;
}

/*
+------------------------------------------------------------------------------
|  Function     : em_l1_sem_reset
+------------------------------------------------------------------------------
|  Description  :  Clears the content of the semaphor, must called after em_l1_sem_read.
|
|  Parameters   :  void
|
|  Return       :  UBYTE
|
+------------------------------------------------------------------------------
*/
GLOBAL int em_l1_sem_reset (void)  /*lint -esym(765,em_l1_sem_reset) | external could be made static | used externally  */
{
/*  ENTER_CRITICAL_SECTION (sem_EM_L1); */
  em_l1_sem_index = 0;
  LEAVE_CRITICAL_SECTION (sem_EM_L1);

  SYST_TRACE ("L1:em_l1_sem_index reseted");
  return TRUE;
}

/*
+------------------------------------------------------------------------------
|  Function     : em_l1_sem_read
+------------------------------------------------------------------------------
|  Description  :  Reads the content of the semaphor.
|
|  Parameters   :  void
|
|  Return       :  UBYTE
|
+------------------------------------------------------------------------------
*/
GLOBAL int em_l1_sem_read (void)  /*lint -esym(765,em_l1_sem_read) | external could be made static | used externally  */
{
  USHORT    semCount;
  TRACE_FUNCTION ("em_l1_sem_read()");

  if (vsi_s_status (VSI_CALLER sem_EM_L1, &semCount) NEQ VSI_OK)
  {
    alr_em_semaphore_err();
    return TRUE;
  }
  if (semCount EQ 0)
  {
    vsi_o_ttrace(VSI_CALLER TC_EVENT, "semCount = %d", semCount);
    SYST_TRACE ("semCount EQ 0");
    return TRUE;
  }

  ENTER_CRITICAL_SECTION (sem_EM_L1);
  /*
   * The l1/alr semaphor will be read by the engineering mode via aci,
   * therefore the functions em_l1_sem_read and em_l1_sem_reset are defined
   * as global. To ensure that during reading only aci has access to the
   * semaphor the macro LEAVE_CRITICAL_SECTION is called after the read process
   * toke place - in the em_l1_sem_resest function.
   */
  return TRUE;
}

/*
  Return value TRUE/FALSE - TRUE keeps the event flag valid, FALSE indicates a successful flag handle
*/
/*
+------------------------------------------------------------------------------
|  Function     : em_l1_sem
+------------------------------------------------------------------------------
|  Description  :  Writes the data inside the semaphor.
|
|  Parameters   :  void
|
|  Return       :  UBYTE
|
+------------------------------------------------------------------------------
*/
LOCAL UBYTE em_l1_sem (UBYTE length, UBYTE *data)
{
 USHORT    semCount;
 USHORT    write_index;
 UBYTE     i;

 TRACE_FUNCTION ("em_l1_sem()");


 if (vsi_s_status (VSI_CALLER sem_EM_L1, &semCount) NEQ VSI_OK)
 {
   alr_em_semaphore_err();
   return TRUE;
 }
 if (semCount EQ 0)
 {
   vsi_o_ttrace(VSI_CALLER TC_EVENT, "semCount = %d", semCount);
   SYST_TRACE ("semCount EQ 0");
   return TRUE;
 }

 /*
 *  buffer overflow protection
 */
 if ( ((write_index = em_l1_sem_index) + length) > EM_L1_SEM_SIZE )
 {
   TRACE_FUNCTION ("alr buffer full");
   return FALSE;
 }

 ENTER_CRITICAL_SECTION(sem_EM_L1);

 for (i=0; i<length; i++)
   em_l1_sem_buffer[em_l1_sem_index++] = *(data++);


 LEAVE_CRITICAL_SECTION (sem_EM_L1);
 return FALSE;                                           /* indicates that flag was handled */
} /* endfunc em_l1_sem */

/*
+------------------------------------------------------------------------------
|  Function     : alr_em_semaphore_err
+------------------------------------------------------------------------------
|  Description  :  Semaphor error
|
|
|  Parameters   :  void
|
|  Return       :  void
|
+------------------------------------------------------------------------------
*/
static void alr_em_semaphore_err (void)
{
 static UCHAR out = 0;
  if (!out)
  {
    out = 1;
    vsi_o_ttrace(VSI_CALLER TC_EVENT, "semaphore error");
  }
}

/*
+------------------------------------------------------------------------------
|  Function     : alr_em_enter_critical_section
+------------------------------------------------------------------------------
|  Description  :  Check on critical section entrance
|
|
|  Parameters   :  Handle
|
|  Return       :  -1  semaphore error
|					0  Ok.
|
+------------------------------------------------------------------------------
*/

#if defined (NEW_FRAME)
static int alr_em_enter_critical_section (T_HANDLE sem)
#else
static int alr_em_enter_critical_section (T_VSI_SHANDLE sem)
#endif /* NEW_FRAME */
{
 if (vsi_s_get (VSI_CALLER sem) NEQ VSI_OK)
 {
  alr_em_semaphore_err();
  return -1;
 }
 else
 {
  return 0;
 }
}/* endfunc rr_enter_critical_section */


/*
+------------------------------------------------------------------------------
|  Function     : alr_em_leave_critical_section
+------------------------------------------------------------------------------
|  Description  :  Check on critical section exit
|
|
|  Parameters   :  Handle
|
|  Return       :  -1  semaphore error
|					0  Ok.
|
+------------------------------------------------------------------------------
*/
#if defined (NEW_FRAME)
static int alr_em_leave_critical_section (T_HANDLE sem)
#else
static int alr_em_leave_critical_section (T_VSI_SHANDLE sem)
#endif /* NEW_FRAME */
{
 if (vsi_s_release (VSI_CALLER sem) NEQ VSI_OK)
 {
  alr_em_semaphore_err();
  return -1;
 }
 else
 {
  return 0;
 }
}/* endfunc rr_leave_critical_section */

/*
+------------------------------------------------------------------------------
|  Function     : alr_em_error_cause
+------------------------------------------------------------------------------
|  Description  :  Check the error cause and store it in the event buffer
|
|  Parameters   :  Cause
|
|  Return       :  None
|
+------------------------------------------------------------------------------
*/

GLOBAL void alr_em_error_cause (UBYTE cause, USHORT arfcn)

{
  switch(cause)
  {
  case CS_BCCH_READ_ERROR:
    {  /* Power measurement request */
      ALR_EM_BCCH_READ_ERROR;
      break;
    }
  case CS_DOWN_LINK_FAIL:
  {  /* Downlink signalling failure */
    ALR_EM_DOWNLINK_FAILURE;
    break;
  }
  case CS_NO_BCCH_AVAIL:
    {  /* neighbourcell BCCH not available */
      ALR_EM_NEIGHBOURCELL_BCCH(EM_NOT_AVAIL);
      break;
    }
  }/*switch*/
}/* alr_em_error_cause */


/*
+------------------------------------------------------------------------------
|  Function     : alr_em_first_event_check()
+------------------------------------------------------------------------------
|  Description  :  Checks if first EM-Event ocured
|
|  Parameters   :  None
|
|  Return       :  None
|
+------------------------------------------------------------------------------
*/

 /*
   ACI is informed about the first event trace, used for later data processing.
 */
LOCAL void alr_em_first_event_check (void)

{
 TRACE_FUNCTION("alr_em_first_event_check()");
 if(em_alr_trace_occured EQ 0)
 {
  PALLOC(em_notification, EM_DATA_IND);
  em_notification->entity = EM_L1;
  PSENDX(MMI, em_notification);
  em_alr_trace_occured++;
 }
}/* alr_em_first_event_check */



#endif /* FF_EM_MODE */



#endif /* ALR_EM_C */