//***************************************************************************** /// \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; }
//***************************************************************************** /// \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 ; } } }