/*===================================================================================================================
File: sm_network_func.c
Description:
This file implements detailed functions of network control state machine.
Copyright (C) 2005-2007 MobilePeak Holdings, Ltd.
Initial Author:
Initial Version Date:
Revision History :
===================================================================================================================*/
#include "sm_common.h"
#include "sm_timer.h"
#include "sm_qos.h"
#include "sm_tft.h"
#include "sm_pdp_address.h"
#include "sm_context_ctrl.h"
#include "sm_mm_api_func.h"
#include "sm_network_func.h"
#if 0
/*-------------------------------------------------------------------------------------------------------------------
Function: SM_APN_Convert
Description: Convert APN value to air message format.
Parameters: pDst - APN value output
pSrc - APN value input
Return: void
-------------------------------------------------------------------------------------------------------------------*/
static void SM_APN_Convert(APN_t *pDst, APN_t *pSrc)
{
U8 i;
U8 *pDstBuf = pDst->APN_Buf;
U8 *pSrcBuf = pSrc->APN_Buf;
U8 Counter = 0;
U8 *pLen;
pDst->LengthAPN_Buf = pSrc->LengthAPN_Buf+1;
pLen = pDstBuf;
for (i=0; i<pSrc->LengthAPN_Buf; i++)
{
pDstBuf++;
if (*pSrcBuf == '.')
{
*pLen = Counter;
Counter = 0;
pLen = pDstBuf;
}
else
{
Counter++;
*pDstBuf = *pSrcBuf;
}
pSrcBuf++;
}
*pLen = Counter;
}
#endif
/*-------------------------------------------------------------------------------------------------------------------
Function: SM_GetLinkTI
Description: Get TI of primary context.
Parameters: Nsapi - NSAPI value of the primary context
Return: U8
-------------------------------------------------------------------------------------------------------------------*/
static U8 SM_GetLinkTI(U8 Nsapi)
{
SM_ContextData_t *pContext = g_SM_Data.SM_ContextArray[Nsapi - NSAPI5];
if (pContext->Flags & CONTEXT_SECONDARY)
{
return pContext->LinkedTI;
}
else
{
return pContext->TI;
}
}
/*-------------------------------------------------------------------------------------------------------------------
Function: SM_GetFreeTI
Description: Search all the contexts and find the lowest useable TI.
Parameters: pSM_ContextData - Pointer to the context data
Return: U8
-------------------------------------------------------------------------------------------------------------------*/
static U8 SM_GetFreeTI(SM_ContextData_t *pSM_ContextData)
{
U8 Nsapi;
U8 Index = 0;
U16 FreeTI_Set = 0x07ff;
/* First, mark all the useable TI. */
for (Nsapi=NSAPI5; Nsapi<MAX_NUM_NSAPI; Nsapi++)
{
SM_ContextData_t *pContext = NULL;
pContext = g_SM_Data.SM_ContextArray[Nsapi - NSAPI5];
if (pContext != NULL
&& pContext != pSM_ContextData
&& (pContext->TI & TI_FLAG_MASK) == 0)
{
FreeTI_Set &= 0x07ff ^ (1 << pContext->TI);
}
}
/* Then, find the lowest useable TI value base on the above search. */
TRACE_ASSERT(FreeTI_Set != 0); /* Number of context allocated TI must less 11, */
/* Find the lowest useable TI value base on the above search. */
while((Index<MAX_NSAPIS) && ((FreeTI_Set & (1<<Index)) == 0))
{
Index++;
}
return Index;
}
/*-------------------------------------------------------------------------------------------------------------------
Function: SM_NW_StartDeact
Description: Start the deactivation procedure for the context.
Parameters: pSM_ContextData - Pointer to the context data
pData - SM_AAL_PDP_DeactivateReq_t * or NULL
Return: void
-------------------------------------------------------------------------------------------------------------------*/
static void SM_NW_StartDeact(SM_ContextData_t *pSM_ContextData, void *pData)
{
SDU_t *pPCO = NULL;
SM_AAL_PDP_DeactivateReq_t *pPrim = (SM_AAL_PDP_DeactivateReq_t *)pData;
/* Stop the active timer. */
SM_TimerStop(pSM_ContextData);
/* Build DEACTIVATE REQUEST message to network. */
if (pPrim)
{
if (pPrim->PCO.L_Buf)
{
pPCO = &pPrim->PCO;
}
SM_BuildDeactivatePDP_ContextRequest(pSM_ContextData, pPCO, pPrim->TeardownInd);
}
else
{
SM_BuildDeactivatePDP_ContextRequest(pSM_ContextData, NULL, FALSE);
}
if (g_SM_Data.GMM_ConnectionStatus == GMM_CONNECTION_ACTIVE)
{
/* Start timer T3390. */
SM_TimerStart(pSM_ContextData, SM_TIMER_T3390);
/* Send the built message to network. */
SM_SendBuiltDataToNW(pSM_ContextData->pCodedMsg);
}
else if (g_SM_Data.GMM_ConnectionStatus == GMM_CONNECTION_PENDING)
{
/* Do nothing. */
}
else
{/* GMM_CONNECTION_INACTIVE */
if (g_SM_Data.OutOfServiceFlag == 0)
{
SM_SendMM_EstablishReq(MM_EST_CAUSE_MO_HIGH_PRIO_SIGNALLING);
}
else
{
/* Procedure is the same to T3390 timeout. */
SM_NW_T3390_Max(pSM_ContextData, NULL);
}
}
}
/*-------------------------------------------------------------------------------------------------------------------
Function: SM_StoreD_ModifyReqestParms
Description: Store the parameters from the D_ModifyPDP_ContextRequest_t message, and
return flags to indicate which parameters need update.
Parameters: pSM_ContextData - Pointer to the context data
pMsg - D_ModifyPDP_ContextRequest_t
pUpdateFlags - Pointer to update flags
Return: void
-------------------------------------------------------------------------------------------------------------------*/
static void SM_StoreD_ModifyReqestParms(SM_ContextData_t *pSM_ContextData,
D_ModifyPDP_ContextRequest_t *pMsg,
U8 *pUpdateFlags)
{
U8 UpdateFlags;
/* Store QOS parameter. */
SM_QOS_ToInner(&pSM_ContextData->NegotiatedQOS, &pMsg->QOS);
UpdateFlags = UPDATE_QOS;
/* Store Radio priority & SAPI parameters, if present. */
if (pSM_ContextData->RadioPrio != pMsg->RadioPrio
|| pSM_ContextData->SAPI != pMsg->SAPI)
{
pSM_ContextData->RadioPrio = pMsg->RadioPrio;
pSM_ContextData->SAPI = pMsg->SAPI;
UpdateFlags |= UPDATE_SAPI_RADIO_PRIO_PFI;
}
/* Store PFI parameter, if present. */
if (pMsg->PFI_Flag != FALSE && pMsg->PFI != pSM_ContextData->PFI)
{
pSM_ContextData->Flags |= CONTEXT_PFI_INCLUDED;
pSM_ContextData->PFI = pMsg->PFI;
UpdateFlags |= UPDATE_SAPI_RADIO_PRIO_PFI;
}
/* Store PDP address, if present. */
if (pMsg->PDP_AddressFlag != FALSE)
{
SM_WriteNegotiatedAddr(pSM_ContextData, &pMsg->PDP_Address, pMsg->PDP_AddressFlag);
UpdateFlags |= UPDATE_ADDRESS;
}
if (pMsg->PCO_Flag != FALSE && pMsg->PCO.LengthPCO_Buf > 0)
{
/* First free memory, if negotiatedPCO is not NULL */
SM_FreePCO(&pSM_ContextData->pNegotiatedPCO);
SM_AllocAndSetPCO(&pSM_ContextData->pNegotiatedPCO,
pMsg->PCO.PCO_Buf,
pMsg->PCO.LengthPCO_Buf);
UpdateFlags |= UPDATE_PCO;
}
*pUpdateFlags |= UpdateFlags;
}
/*---------------