308 lines
12 KiB
C
308 lines
12 KiB
C
/*
|
|
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership.
|
|
* The OpenAirInterface Software Alliance licenses this file to You under
|
|
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.openairinterface.org/?page_id=698
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*-------------------------------------------------------------------------------
|
|
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
|
* contact@openairinterface.org
|
|
*/
|
|
|
|
/*****************************************************************************
|
|
|
|
Source emm_fsm.c
|
|
|
|
Version 0.1
|
|
|
|
Date 2012/10/03
|
|
|
|
Product NAS stack
|
|
|
|
Subsystem EPS Mobility Management
|
|
|
|
Author Frederic Maurel
|
|
|
|
Description Defines the EPS Mobility Management procedures executed at
|
|
the EMMREG Service Access Point.
|
|
|
|
*****************************************************************************/
|
|
|
|
#include "emm_fsm.h"
|
|
#include "commonDef.h"
|
|
#include "nas_log.h"
|
|
|
|
#include "emmData.h"
|
|
#include "user_defs.h"
|
|
|
|
|
|
|
|
/****************************************************************************/
|
|
/**************** E X T E R N A L D E F I N I T I O N S ****************/
|
|
/****************************************************************************/
|
|
|
|
#define EMM_FSM_NB_UE_MAX 1
|
|
|
|
/****************************************************************************/
|
|
/******************* L O C A L D E F I N I T I O N S *******************/
|
|
/****************************************************************************/
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* Data used for trace logging
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
|
|
/* String representation of EMM events */
|
|
const char *emm_fsm_event2str(int evt) {
|
|
static const char *_emm_fsm_event_str[] = {
|
|
"S1_ENABLED",
|
|
"S1_DISABLED",
|
|
"NO_IMSI",
|
|
"NO_CELL",
|
|
"REGISTER_REQ",
|
|
"REGISTER_CNF",
|
|
"REGISTER_REJ",
|
|
"ATTACH_INIT",
|
|
"ATTACH_REQ",
|
|
"ATTACH_FAILED",
|
|
"ATTACH_EXCEEDED",
|
|
"AUTHENTICATION_REJ",
|
|
"ATTACH_CNF",
|
|
"ATTACH_REJ",
|
|
"DETACH_INIT",
|
|
"DETACH_REQ",
|
|
"DETACH_FAILED",
|
|
"DETACH_CNF",
|
|
"TAU_REQ",
|
|
"TAU_CNF",
|
|
"TAU_REJ",
|
|
"SERVICE_REQ",
|
|
"SERVICE_CNF",
|
|
"SERVICE_REJ",
|
|
"LOWERLAYER_SUCCESS",
|
|
"LOWERLAYER_FAILURE",
|
|
"LOWERLAYER_RELEASE",
|
|
};
|
|
return _emm_fsm_event_str[evt];
|
|
}
|
|
|
|
const char *emm_fsm_status2str(int status) {
|
|
/* String representation of EMM status */
|
|
static const char *_emm_fsm_status_str[EMM_STATE_MAX] = {
|
|
"INVALID",
|
|
"NULL",
|
|
"DEREGISTERED",
|
|
"REGISTERED",
|
|
"DEREGISTERED-INITIATED",
|
|
"DEREGISTERED.NORMAL-SERVICE",
|
|
"DEREGISTERED.LIMITED-SERVICE",
|
|
"DEREGISTERED.ATTEMPTING-TO-ATTACH",
|
|
"DEREGISTERED.PLMN-SEARCH",
|
|
"DEREGISTERED.NO-IMSI",
|
|
"DEREGISTERED.ATTACH-NEEDED",
|
|
"DEREGISTERED.NO-CELL-AVAILABLE",
|
|
"REGISTERED-INITIATED",
|
|
"REGISTERED.NORMAL-SERVICE",
|
|
"REGISTERED.ATTEMPTING-TO-PDATE",
|
|
"REGISTERED.LIMITED-SERVICE",
|
|
"REGISTERED.PLMN-SEARCH",
|
|
"REGISTERED.UPDATE-NEEDED",
|
|
"REGISTERED.NO-CELL-AVAILABLE",
|
|
"REGISTERED.ATTEMPTING-TO-UPDATE-MM",
|
|
"REGISTERED.IMSI-DETACH-INITIATED",
|
|
"TRACKING-AREA-UPDATING-INITIATED",
|
|
"SERVICE-REQUEST-INITIATED",
|
|
};
|
|
return _emm_fsm_status_str[status];
|
|
}
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* EPS Mobility Management state machine handlers
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
|
|
/* Type of the EPS Mobility Management state machine handler */
|
|
typedef int(*emm_fsm_handler_t)(nas_user_t *user, const emm_reg_t *);
|
|
|
|
int EmmNull(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregistered(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegistered(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredInitiated(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredNormalService(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredLimitedService(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredAttemptingToAttach(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredPlmnSearch(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredNoImsi(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredAttachNeeded(nas_user_t *user, const emm_reg_t *);
|
|
int EmmDeregisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredInitiated(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredNormalService(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredLimitedService(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredPlmnSearch(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredUpdateNeeded(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredNoCellAvailable(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredAttemptingToUpdate(nas_user_t *user, const emm_reg_t *);
|
|
int EmmRegisteredImsiDetachInitiated(nas_user_t *user, const emm_reg_t *);
|
|
int EmmTrackingAreaUpdatingInitiated(nas_user_t *user, const emm_reg_t *);
|
|
int EmmServiceRequestInitiated(nas_user_t *user, const emm_reg_t *);
|
|
|
|
|
|
/* EMM state machine handlers */
|
|
static const emm_fsm_handler_t _emm_fsm_handlers[EMM_STATE_MAX] = {
|
|
NULL,
|
|
EmmNull,
|
|
EmmDeregistered,
|
|
EmmRegistered,
|
|
EmmDeregisteredInitiated,
|
|
EmmDeregisteredNormalService,
|
|
EmmDeregisteredLimitedService,
|
|
EmmDeregisteredAttemptingToAttach,
|
|
EmmDeregisteredPlmnSearch,
|
|
EmmDeregisteredNoImsi,
|
|
EmmDeregisteredAttachNeeded,
|
|
EmmDeregisteredNoCellAvailable,
|
|
EmmRegisteredInitiated,
|
|
EmmRegisteredNormalService,
|
|
EmmRegisteredAttemptingToUpdate,
|
|
EmmRegisteredLimitedService,
|
|
EmmRegisteredPlmnSearch,
|
|
EmmRegisteredUpdateNeeded,
|
|
EmmRegisteredNoCellAvailable,
|
|
EmmRegisteredAttemptingToUpdate,
|
|
EmmRegisteredImsiDetachInitiated,
|
|
EmmTrackingAreaUpdatingInitiated,
|
|
EmmServiceRequestInitiated,
|
|
};
|
|
|
|
/****************************************************************************/
|
|
/****************** E X P O R T E D F U N C T I O N S ******************/
|
|
/****************************************************************************/
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: emm_fsm_initialize() **
|
|
** **
|
|
** Description: Initializes the EMM state machine **
|
|
** **
|
|
** Inputs: None **
|
|
** Others: None **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: None **
|
|
** Others: _emm_fsm_status **
|
|
** **
|
|
***************************************************************************/
|
|
emm_fsm_state_t emm_fsm_initialize()
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
LOG_FUNC_RETURN(EMM_NULL);
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: emm_fsm_set_status() **
|
|
** **
|
|
** Description: Set the EPS Mobility Management status to the given state **
|
|
** **
|
|
** Inputs: ueid: Lower layers UE identifier **
|
|
** status: The new EMM status **
|
|
** Others: None **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: RETURNok, RETURNerror **
|
|
** Others: _emm_fsm_status **
|
|
** **
|
|
***************************************************************************/
|
|
int emm_fsm_set_status(nas_user_t *user,
|
|
emm_fsm_state_t status)
|
|
{
|
|
LOG_FUNC_IN;
|
|
|
|
if ( status < EMM_STATE_MAX ) {
|
|
LOG_TRACE(INFO, "EMM-FSM - Status changed: %s ===> %s",
|
|
emm_fsm_status2str(user->emm_fsm_status),
|
|
emm_fsm_status2str(status));
|
|
|
|
if (status != user->emm_fsm_status) {
|
|
user->emm_fsm_status = status;
|
|
}
|
|
|
|
LOG_FUNC_RETURN (RETURNok);
|
|
}
|
|
|
|
LOG_FUNC_RETURN (RETURNerror);
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: emm_fsm_get_status() **
|
|
** **
|
|
** Description: Get the current value of the EPS Mobility Management **
|
|
** status **
|
|
** **
|
|
** Inputs: ueid: Lower layers UE identifier **
|
|
** Others: _emm_fsm_status **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: The current value of the EMM status **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
emm_fsm_state_t emm_fsm_get_status(nas_user_t *user)
|
|
{
|
|
return user->emm_fsm_status;
|
|
}
|
|
|
|
/****************************************************************************
|
|
** **
|
|
** Name: emm_fsm_process() **
|
|
** **
|
|
** Description: Executes the EMM state machine **
|
|
** **
|
|
** Inputs: evt: The EMMREG-SAP event to process **
|
|
** Others: _emm_fsm_status **
|
|
** **
|
|
** Outputs: None **
|
|
** Return: RETURNok, RETURNerror **
|
|
** Others: None **
|
|
** **
|
|
***************************************************************************/
|
|
int emm_fsm_process(nas_user_t *user, const emm_reg_t *evt)
|
|
{
|
|
int rc;
|
|
emm_fsm_state_t status;
|
|
|
|
LOG_FUNC_IN;
|
|
|
|
|
|
status = user->emm_fsm_status;
|
|
|
|
LOG_TRACE(INFO, "EMM-FSM - Received event %s (%d) in state %s",
|
|
emm_fsm_event2str(evt->primitive - _EMMREG_START - 1), evt->primitive,
|
|
emm_fsm_status2str(status));
|
|
|
|
|
|
/* Execute the EMM state machine */
|
|
rc = (_emm_fsm_handlers[status])(user, evt);
|
|
|
|
LOG_FUNC_RETURN (rc);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/********************* L O C A L F U N C T I O N S *********************/
|
|
/****************************************************************************/
|
|
|