Files

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 *********************/
/****************************************************************************/