//*****************************************************************************
/// \brief
///      RRLP PDU delivery in.
/// \details
///      Delivers a RRLP PDU from an external entity.
///      <p> This function is called in response to data being sent over an
///      RRLP Control Plane connection.
///      <p> For the RRLP PDU delivery the Host software provides a
///      Handle which is used in subsequent exchanges to tie up the RRLP
///      sequence.
///      <ul>
///         <li><var>#GN_SUCCESS \copydoc GN_SUCCESS</var>\n
///            p_Status should be set to this value when the return value
///            indicated success.</li>
///         <li><var>#GN_ERR_NO_RESOURCE \copydoc GN_ERR_NO_RESOURCE</var>\n
///            p_Status should be set to this value when there are not
///            enough resources available to the library to perform the
///            requested function.</li>
///      </ul>
/// \attention
///      The calling party is responsible for managing the memory referenced by
///      p_Status and p_PDU.
/// \returns
///      Flag to indicate success or failure of the posting of the request.
/// \retval #TRUE Flag indicating success.
/// \retval #FALSE Flag indicating failure and that the status should be checked.
BL GN_RRLP_PDU_Delivery_In(
   void        *Handle,       ///< [in] Opaque Handle used to coordinate requests.
   U2          PDU_Size,      ///< [in] Size of data at p_PDU in bytes.
   U1          *p_PDU,        ///< [in] Pointer to data.
   U4          PDU_TimeStamp  ///< [in] Timestamp of reception of PDU.
)
{
   s_RRLP_Instance   *p_RRLP_Instance;

   GN_RRLP_Log( "+GN_RRLP_PDU_Delivery_In:" );
   GN_RRLP_Log( "GN_RRLP_api_call:    RRLP<=SUPL [label=\"GN_RRLP_PDU_Delivery_In: Handle=%p\"];", Handle );
   p_RRLP_Instance = RRLP_Instance_From_Handle( Handle );
   if(p_RRLP_Instance != NULL)
   {
        s_PDU_Encoded     *p_POS_Payload    = GN_Calloc( 1, sizeof( s_PDU_Encoded ) );

        p_POS_Payload->Length = PDU_Size;
        p_POS_Payload->p_PDU_Data = GN_Calloc( 1, PDU_Size );

        memcpy( p_POS_Payload->p_PDU_Data, p_PDU, PDU_Size );

        RRLP_Send_PDU_Delivery( p_RRLP_Instance,
                               NULL,
                               p_RRLP_Instance->Handle,
                               p_POS_Payload,
                               PDU_TimeStamp,
                               NULL );
           GN_RRLP_Log( "GN_RRLP_api_call: PDU Delivery Successful" );

   }

   GN_RRLP_Log( "GN_RRLP_PDU_Delivery_In-:" );
   return TRUE;
}
//*****************************************************************************
/// \brief
///      RRLP Sequence Start in.
/// \details
///      Delivers the first RRLP PDU in the sequence from an external entity.
///      <p> This function is called in response to data being sent over an
///      RRLP Control Plane connection.
///      <p> For the RRLP Sequence Start the RRLP subsystem provides a
///      Handle which is used in subsequent exchanges to tie up the RRLP
///      sequence.
///      <ul>
///         <li><var>#GN_SUCCESS \copydoc GN_SUCCESS</var>\n
///            p_Status should be set to this value when the return value
///            indicated success.</li>
///         <li><var>#GN_ERR_NO_RESOURCE \copydoc GN_ERR_NO_RESOURCE</var>\n
///            p_Status should be set to this value when there are not
///            enough resources available to the library to perform the
///            requested function.</li>
///      </ul>
/// \attention
///      The calling party is responsible for managing the memory referenced by
///      p_Status and p_PDU.
/// \returns
///      Flag to indicate success or failure of the posting of the request.
/// \retval #TRUE Flag indicating success.
/// \retval #FALSE Flag indicating failure and that the status should be checked.
BL GN_RRLP_Sequence_Start_In(
   void           **p_Handle,    ///< [out] Opaque Handle used to coordinate requests.
   U2             PDU_Size,      ///< [in] Size of data at p_PDU in bytes.
   U1             *p_PDU,        ///< [in] Pointer to data.
   U4             PDU_TimeStamp, ///< [in] Timestamp of reception of PDU.
   s_GN_RRLP_QoP  *p_GN_RRLP_QoP, ///< [in] QoP if available.
   BL              LoggingDisabled ///< [in] This is used to enable/disable logging from the RRLP module
)
{
   s_RRLP_Instance   *p_RRLP_Instance;
   s_PDU_Encoded     *p_POS_Payload    = GN_Calloc( 1, sizeof( s_PDU_Encoded ) );
   s_GN_RRLP_QoP     *p_Temp_Qop;

   GN_RRLP_Log( "+GN_RRLP_Sequence_Start_In:" );
   GN_RRLP_Log( "GN_RRLP_api_call:    RRLP<=SUPL [label=\"GN_RRLP_Sequence_Start_In:\"];" );
   p_RRLP_Instance                  = RRLP_Instance_Request_New();
   *p_Handle                        = p_RRLP_Instance->Handle;
   p_RRLP_Instance->p_RRLP->State   = state_RRLP_Transaction_In_Progress;
   p_RRLP_Instance->p_RRLP->LoggingDisabled = LoggingDisabled;

   // POS_Handle not set, this is the first in the sequence.
   if ( p_GN_RRLP_QoP != NULL )
   {
      p_Temp_Qop = GN_Calloc( 1, sizeof( s_GN_RRLP_QoP ) );
      memcpy( p_Temp_Qop, p_GN_RRLP_QoP, sizeof( s_GN_RRLP_QoP ) );
   }
   else
   {
      p_Temp_Qop = NULL;
   }

   p_POS_Payload->Length      = PDU_Size;
   p_POS_Payload->p_PDU_Data  = GN_Calloc( 1, PDU_Size );

   memcpy( p_POS_Payload->p_PDU_Data, p_PDU, PDU_Size );

   RRLP_Send_PDU_Delivery( p_RRLP_Instance,
                           NULL,
                           p_RRLP_Instance->Handle,
                           p_POS_Payload,
                           PDU_TimeStamp,
                           p_Temp_Qop );
   if ( p_Temp_Qop != NULL )
   {
      GN_Free( p_Temp_Qop );
   }
   GN_RRLP_Log( "GN_RRLP_api_call:    RRLP>>SUPL [label=\"GN_RRLP_Sequence_Start_In: Handle=%p\"];", p_RRLP_Instance->Handle );
   GN_RRLP_Log( "-GN_RRLP_Sequence_Start_In:" );
   return TRUE;
}
//*************************************************************************
/// \brief
///      Allocates a new unique Instance.
/// \returns
///      Pointer to an Instance ID.
//*************************************************************************
s_SUPL_Instance *SUPL_Instance_Request_New( void )
{
   s_SUPL_Instance *p_SUPL_Instance = SUPL_Instance_Base_Request_New( &SUPL_Instances );

   if ( p_SUPL_Instance != NULL )
   {
         U1 Config_Major, Config_Minor, Config_Service_Indicator;

         e_SetIdType SetIdType = supl_config_get_SUPL_SetIdType();
         supl_config_get_SUPL_version( &Config_Major, &Config_Minor, &Config_Service_Indicator );
         
         p_SUPL_Instance->p_SUPL               = GN_Calloc( 1, sizeof( s_SUPL_InstanceData ) );
         p_SUPL_Instance->p_SUPL->SetSessionId = p_SUPL_Instance->ThisInstanceId;
         p_SUPL_Instance->Handle =  &p_SUPL_Instance->ThisInstanceId; // Use the Instance ID as a Handle for the time being.
         p_SUPL_Instance->p_SUPL->V2_Data.p_ApplicationID  = NULL;
         p_SUPL_Instance->p_SUPL->V2_Data.p_ThirdPartyData = NULL;
         p_SUPL_Instance->p_SUPL->SetId.type  = SetIdType;
         p_SUPL_Instance->p_SUPL->TransactionSuplVersion   = Config_Major;  // This is to ensure if SUPL_INIT decoding has failed and we would need to send SUPL END with appropriate version field

         switch ( SetIdType )
         {
         case GN_SETId_PR_msisdn:
            memcpy(  p_SUPL_Instance->p_SUPL->SetId.u.msisdn,
                     supl_config_get_SUPL_msisdn(),
                     sizeof( p_SUPL_Instance->p_SUPL->SetId.u.msisdn ) );
            break;
         case GN_SETId_PR_mdn:
            memcpy(  p_SUPL_Instance->p_SUPL->SetId.u.mdn,
                     supl_config_get_SUPL_mdn(),
                     sizeof( p_SUPL_Instance->p_SUPL->SetId.u.mdn ) );
            break;
         case GN_SETId_PR_min:
            //memcpy(  p_SUPL_Instance->p_SUPL->SetId.u.min,
            //         supl_config_get_SUPL_min(),
            //         sizeof( p_SUPL_Instance->p_SUPL->SetId.u.min ) );
            break;
         case GN_SETId_PR_imsi:
            memcpy(  p_SUPL_Instance->p_SUPL->SetId.u.imsi,
                     supl_config_get_SUPL_imsi(),
                     sizeof( p_SUPL_Instance->p_SUPL->SetId.u.imsi ) );
            break;
         case GN_SETId_PR_nai:
            break;
         case GN_SETId_PR_iPAddressV4:
            break;
         case GN_SETId_PR_iPAddressV6:
            break;
      /* Added to remove warning */
      case GN_SETId_PR_NOTHING:
         GN_SUPL_Log( "SUPL_Instance_Request_New:   No SETId Configured" );
         break;
      }
      GN_SUPL_Log_SessionStarted( p_SUPL_Instance->Handle );
   }
   else
   {
      GN_SUPL_Log( "GN_SUPL:    --- [label=\"Handle Creation Failed!\"];" );
   }
   return p_SUPL_Instance;
}
Пример #4
0
//*****************************************************************************
/// \brief
///      Allocates memory for a Buffer store and initialises variables.
/// \returns
///      Pointer to #s_PDU_Buffer_Store
//*****************************************************************************
s_PDU_Buffer_Store *asn1_PDU_Buffer_Store_Alloc
(
   U2 Raw_PDU_Size ///< size to allocate for the encoded PDU.
)
{
   s_PDU_Buffer_Store *p_PDU_Buffer_Store;

   p_PDU_Buffer_Store = GN_Calloc( 1, sizeof( s_PDU_Buffer_Store ) );
   if ( Raw_PDU_Size != 0 )
   {
      p_PDU_Buffer_Store->PDU_Encoded.p_PDU_Data = GN_Calloc( 1, Raw_PDU_Size );
   }
   p_PDU_Buffer_Store->AvailSize = Raw_PDU_Size;
   p_PDU_Buffer_Store->PDU_Encoded.Length = 0;

   return p_PDU_Buffer_Store;
}
//*****************************************************************************
/// \brief
///      Requests a new message structure and initialises it as a RRLP Agent
///      message.
/// \returns
///      Pointer to partially completed message structure.
//*****************************************************************************
s_RRLP_Message* RRLP_Message_Init(
   s_RRLP_Instance *p_RRLP_Instance,///< RRLP Agent instance to process
                                    ///  the message.
   s_RRLP_Instance *p_SrcInstance   ///< Entity instance where the message 
                                    ///  originated.
)
{
   s_RRLP_Message *p_Message;

   p_Message = GN_Calloc( 1, sizeof( s_RRLP_Message ) );

   if ( p_Message == NULL )
   {
      return NULL;
   }
   else
   {
      p_Message->MsgHdr.p_InstanceOfDest = p_RRLP_Instance;

      p_Message->MsgHdr.p_InstanceOfSrc = p_SrcInstance;

      return p_Message;
   }
}
//*************************************************************************
/// \brief
///      Request a new non specific instance from an instance container.
/// \returns
///      Pointer to an instance.
//*************************************************************************
s_SUPL_Instance *SUPL_Instance_Base_Request_New
(
   s_SUPL_Instances *p_Instances   ///< Instance container from which to
                                   /// obtain an instance.
)
{
   s_SUPL_Instance *p_Instance_Unused;

   if ( p_Instances == NULL )
   {
      return NULL;
   }
   else
   {
      t_SUPL_InstanceId    NewInstanceId;
      BL InstanceId_Unique;
      BL InstanceId_Found;
      U2 i;

      for ( i = 0 ; i < p_Instances->MaxInstanceCount ; i++ )
      {
         if ( p_Instances->InstanceList[i] == NULL )
         {
            break ;
         }
      }
      if ( i != p_Instances->MaxInstanceCount ) // We found a gap.
      {
         // We found an unused instance entry. Allocate storage.
         p_Instances->InstanceList[i] = GN_Calloc( 1, sizeof( s_SUPL_Instance ) );

         p_Instance_Unused = p_Instances->InstanceList[i] ;

         InstanceId_Unique = FALSE;
         while ( ! InstanceId_Unique )
         {
            // Calculate a new instance id.
            if ( p_Instances->InstanceIdHighWaterMark < INSTANCE_SUPL_LIMIT - INSTANCE_SUPL_MAX )
            {
               NewInstanceId = p_Instances->InstanceIdHighWaterMark + 1 ;
               p_Instances->InstanceIdHighWaterMark = NewInstanceId ;
            }
            else
            {
               NewInstanceId = 1;
               p_Instances->InstanceIdHighWaterMark = NewInstanceId ;
            }

            // Make sure new instance id is not in use.
            InstanceId_Found = FALSE;
            for ( i = 0 ; i < p_Instances->MaxInstanceCount ; i++ )
            {
               if( p_Instances->InstanceList[i] != NULL &&
                   p_Instances->InstanceList[i]->ThisInstanceId == NewInstanceId )
              {
                  InstanceId_Found = TRUE;
                  break;
              }
            }
            if ( ! InstanceId_Found ) InstanceId_Unique = TRUE ;
         }
         p_Instances->InstanceIdHighWaterMark = NewInstanceId ;

         // Store the new instance id.
         p_Instance_Unused->ThisInstanceId = NewInstanceId ;
         return p_Instance_Unused ;
      }
      else
      {
         return NULL ;
      }
   }
}