939 lines
26 KiB
C
939 lines
26 KiB
C
/* ITu-T G.965 Section 16.2 V5.2-interface Link control FSM - LE side */
|
|
|
|
/* (C) 2021 by Harald Welte <laforge@gnumonks.org>
|
|
* (C) 2022 by Andreas Eversberg <jolly@eversberg.eu>
|
|
*
|
|
* All Rights Reserved
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
*/
|
|
|
|
/***********************************************************************/
|
|
/* internal data structures */
|
|
/***********************************************************************/
|
|
|
|
#include <unistd.h>
|
|
#include <stdint.h>
|
|
#include <errno.h>
|
|
|
|
#include <osmocom/core/utils.h>
|
|
|
|
#include "v5x_internal.h"
|
|
#include "v5x_protocol.h"
|
|
#include "layer1.h"
|
|
#include "v5x_l1_fsm.h"
|
|
#include "v5x_le_ctrl_fsm.h"
|
|
#include "v5x_le_management.h"
|
|
#include "v52_le_lcp_fsm.h"
|
|
#include "logging.h"
|
|
|
|
#define S(x) (1 << (x))
|
|
|
|
/***********************************************************************/
|
|
/* state names, event names, primitives, ... */
|
|
/***********************************************************************/
|
|
|
|
/* 16.2.4.2.2 */
|
|
enum v52_lcp_fsm_state {
|
|
V52_LCPFSM_S_LE01_NOP_LINK_FAILURE,
|
|
V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED,
|
|
V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED,
|
|
V52_LCPFSM_S_LE11_NOP_LOCAL_LINK_UNBLOCK,
|
|
V52_LCPFSM_S_LE12_NOP_REMOTE_LINK_UNBLOCK,
|
|
V52_LCPFSM_S_LE20_OP_OPERATIONAL,
|
|
V52_LCPFSM_S_LE21_OP_REMOTE_LINK_ID,
|
|
V52_LCPFSM_S_LE22_OP_LOCAL_LINK_ID,
|
|
};
|
|
|
|
enum v52_lcp_fsm_event {
|
|
V52_LCPFSM_E_MPH_AI, /* Activate Indication (L1 link operational) */
|
|
V52_LCPFSM_E_MPH_DI, /* Deactivate Indication (L1 link not operational) */
|
|
V52_LCPFSM_E_MDU_IDReq, /* Identification Request */
|
|
V52_LCPFSM_E_FE_IDAck,
|
|
V52_LCPFSM_E_MPH_IDI, /* Identification Indication */
|
|
V52_LCPFSM_E_MPH_EIg, /* Identification Failure */
|
|
V52_LCPFSM_E_FE_IDReq,
|
|
V52_LCPFSM_E_MDU_IDAck, /* Send Link ID ACK */
|
|
V52_LCPFSM_E_FE_IDRel,
|
|
V52_LCPFSM_E_MDU_IDRej, /* Link ID Reject */
|
|
V52_LCPFSM_E_FE_IDRej,
|
|
V52_LCPFSM_E_MDU_LUBR, /* Link Unblock Request */
|
|
V52_LCPFSM_E_MDU_LBI, /* Link Block Indication */
|
|
V52_LCPFSM_E_FE302, /* AN Initiated unblocking */
|
|
V52_LCPFSM_E_FE304, /* AN initiated link block */
|
|
V52_LCPFSM_E_FE305, /* deferred link block request */
|
|
V52_LCPFSM_E_FE306, /* non-deferred link block request */
|
|
};
|
|
|
|
static const struct value_string v52_lcp_fsm_event_names[] = {
|
|
{ V52_LCPFSM_E_MPH_AI, "MPH-AI" },
|
|
{ V52_LCPFSM_E_MPH_DI, "MPH-DI" },
|
|
{ V52_LCPFSM_E_MDU_IDReq, "MDU-IDReq" },
|
|
{ V52_LCPFSM_E_FE_IDAck, "FE-IDAck" },
|
|
{ V52_LCPFSM_E_MPH_IDI, "MPH-IDI" },
|
|
{ V52_LCPFSM_E_MPH_EIg, "MPH-EIg" },
|
|
{ V52_LCPFSM_E_FE_IDReq, "FE-IDReq" },
|
|
{ V52_LCPFSM_E_MDU_IDAck, "MDU-IDack" },
|
|
{ V52_LCPFSM_E_FE_IDRel, "FE-IDRel" },
|
|
{ V52_LCPFSM_E_MDU_IDRej, "MDU-IDRej" },
|
|
{ V52_LCPFSM_E_FE_IDRej, "FE-IDRej" },
|
|
{ V52_LCPFSM_E_MDU_LUBR, "MDU-LUBR" },
|
|
{ V52_LCPFSM_E_MDU_LBI, "MDU-LBI" },
|
|
{ V52_LCPFSM_E_FE302, "FE302" },
|
|
{ V52_LCPFSM_E_FE304, "FE304" },
|
|
{ V52_LCPFSM_E_FE305, "FE305" },
|
|
{ V52_LCPFSM_E_FE306, "FE306" },
|
|
{ 0, NULL }
|
|
};
|
|
|
|
/***********************************************************************/
|
|
/* Messages to other layers */
|
|
/***********************************************************************/
|
|
|
|
/* send message to upper (management) layer */
|
|
static void rcv_mdu(struct osmo_fsm_inst *fi, enum v5x_mgmt_prim prim)
|
|
{
|
|
struct v5x_link *v5l = fi->priv;
|
|
|
|
v52_le_lcp_mdu_rcv(v5l, prim);
|
|
}
|
|
|
|
/* send message to lower (L1 FSM) layer */
|
|
static void snd_mph(struct osmo_fsm_inst *fi, enum v5x_mph_prim prim)
|
|
{
|
|
struct v5x_link *v5l = fi->priv;
|
|
|
|
v5x_l1_mph_snd(v5l, prim);
|
|
}
|
|
|
|
/* send message to lower (CTRL) layer */
|
|
void snd_fe(struct osmo_fsm_inst *fi, enum v52_link_ctrl_func lcf)
|
|
{
|
|
struct v5x_link *v5l = fi->priv;
|
|
|
|
v52_le_ctrl_link_snd(v5l, lcf);
|
|
}
|
|
|
|
/***********************************************************************/
|
|
/* LCP state FSM */
|
|
/***********************************************************************/
|
|
|
|
static void lcp_fsm_le01_link_failure(struct osmo_fsm_inst *fi, uint32_t event, void __attribute__((unused)) *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send MDU-LAI */
|
|
rcv_mdu(fi, MDU_LAI);
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDReq:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDRel:
|
|
case V52_LCPFSM_E_FE_IDRej:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
case V52_LCPFSM_E_FE302:
|
|
case V52_LCPFSM_E_FE305:
|
|
case V52_LCPFSM_E_FE306:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED, 0, 0);
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
static void lcp_fsm_le02_link_failure_blocked(struct osmo_fsm_inst *fi, uint32_t event,
|
|
void __attribute__((unused)) *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
/* Send MDU-LAI */
|
|
rcv_mdu(fi, MDU_LAI);
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDReq:
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
case V52_LCPFSM_E_FE302:
|
|
case V52_LCPFSM_E_FE305:
|
|
case V52_LCPFSM_E_FE306:
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
/* ignore */
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
static void lcp_fsm_le10_link_blocked(struct osmo_fsm_inst *fi, uint32_t event, void __attribute__((unused)) *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
/* Send MDU-LAI */
|
|
rcv_mdu(fi, MDU_LAI);
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED, 0, 0);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDReq:
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDRel:
|
|
case V52_LCPFSM_E_FE_IDRej:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE11_NOP_LOCAL_LINK_UNBLOCK, 0, 0);
|
|
/* Send FE301 */
|
|
snd_fe(fi, V52_LCP_FE_301_302_LINK_UNBLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
case V52_LCPFSM_E_FE305:
|
|
case V52_LCPFSM_E_FE306:
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE302:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE12_NOP_REMOTE_LINK_UNBLOCK, 0, 0);
|
|
/* Send MDL-LUBR */
|
|
rcv_mdu(fi, MDU_LUBR);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
/* ignore */
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
|
|
}
|
|
|
|
static void lcp_fsm_le11_local_link_unblock(struct osmo_fsm_inst *fi, uint32_t event,
|
|
__attribute__((unused)) void *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED, 0, 0);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDReq:
|
|
/* Send FE-IDRej */
|
|
snd_fe(fi, V52_LCP_FE_IDRej);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDRel:
|
|
case V52_LCPFSM_E_FE_IDRej:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
/* Send FE301 */
|
|
snd_fe(fi, V52_LCP_FE_301_302_LINK_UNBLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE302:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send MDU-LUBI */
|
|
rcv_mdu(fi, MDU_LUBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE305:
|
|
case V52_LCPFSM_E_FE306:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
static void lcp_fsm_le12_remote_link_unblock(struct osmo_fsm_inst *fi, uint32_t event,
|
|
void __attribute__((unused)) *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED, 0, 0);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
/* Send MDU-IDRej */
|
|
rcv_mdu(fi, MDU_IDRej);
|
|
/* Send MDU-LUBR */
|
|
rcv_mdu(fi, MDU_LUBR);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDReq:
|
|
/* Send FE-IDRej */
|
|
snd_fe(fi, V52_LCP_FE_IDRej);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send FE301 */
|
|
snd_fe(fi, V52_LCP_FE_301_302_LINK_UNBLOCK);
|
|
/* Send MDU-LUBI */
|
|
rcv_mdu(fi, MDU_LUBI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE302:
|
|
/* Send MDU-LUBR */
|
|
rcv_mdu(fi, MDU_LUBR);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE305:
|
|
case V52_LCPFSM_E_FE306:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
static void lcp_fsm_le20_operational(struct osmo_fsm_inst *fi, uint32_t event, void __attribute__((unused)) *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE01_NOP_LINK_FAILURE, 0, 0);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE22_OP_LOCAL_LINK_ID, 0, 0);
|
|
/* Send FE-IDReq */
|
|
snd_fe(fi, V52_LCP_FE_IDReq);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDReq:
|
|
/* Send MDU-IDReq */
|
|
rcv_mdu(fi, MDU_IDReq);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDAck:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE21_OP_REMOTE_LINK_ID, 0, 0);
|
|
/* Send FE-IDAck */
|
|
snd_fe(fi, V52_LCP_FE_IDAck);
|
|
/* Send MPH-ID */
|
|
snd_mph(fi, MPH_ID);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDRej:
|
|
/* Send FE-IDRej */
|
|
snd_fe(fi, V52_LCP_FE_IDRej);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
/* Send FE301 */
|
|
snd_fe(fi, V52_LCP_FE_301_302_LINK_UNBLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE302:
|
|
/* Send MDU-LUBI */
|
|
rcv_mdu(fi, MDU_LUBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE305:
|
|
/* Send MDU-LBR */
|
|
rcv_mdu(fi, MDU_LBR);
|
|
break;
|
|
case V52_LCPFSM_E_FE306:
|
|
/* Send MDU-LBRN */
|
|
rcv_mdu(fi, MDU_LBRN);
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
|
|
}
|
|
|
|
static void lcp_fsm_le21_op_remote_link_id(struct osmo_fsm_inst *fi, uint32_t event, void __attribute__((unused)) *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE01_NOP_LINK_FAILURE, 0, 0);
|
|
/* Send MPH-NOR */
|
|
snd_mph(fi, MPH_NOR);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
/* Send MDU-IDRej */
|
|
rcv_mdu(fi, MDU_IDRej);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDAck:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDRel:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send MDU-IDRel */
|
|
rcv_mdu(fi, MDU_IDRel);
|
|
/* Send MPH-NOR */
|
|
snd_mph(fi, MPH_NOR);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDRej:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send FE-IDRej */
|
|
rcv_mdu(fi, MDU_IDRej);
|
|
/* Send MPH-NOR */
|
|
snd_mph(fi, MPH_NOR);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send FE301 */
|
|
snd_fe(fi, V52_LCP_FE_301_302_LINK_UNBLOCK);
|
|
/* Send MPH-NOR */
|
|
snd_mph(fi, MPH_NOR);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
/* Send MPH-NOR */
|
|
snd_mph(fi, MPH_NOR);
|
|
break;
|
|
case V52_LCPFSM_E_FE302:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send MPH-NOR */
|
|
snd_mph(fi, MPH_NOR);
|
|
/* Send MDU-IDRel */
|
|
rcv_mdu(fi, MDU_IDRel);
|
|
/* Send MDU-LUBI */
|
|
rcv_mdu(fi, MDU_LUBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send MPH-NOR */
|
|
snd_mph(fi, MPH_NOR);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE305:
|
|
/* Send MDU-LBR */
|
|
rcv_mdu(fi, MDU_LBR);
|
|
break;
|
|
case V52_LCPFSM_E_FE306:
|
|
/* Send MDU-LBRN */
|
|
rcv_mdu(fi, MDU_LBRN);
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
static void lcp_fsm_le22_op_local_link_id(struct osmo_fsm_inst *fi, uint32_t event, void __attribute__((unused)) *data)
|
|
{
|
|
switch (event) {
|
|
case V52_LCPFSM_E_MPH_AI:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_MPH_DI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE01_NOP_LINK_FAILURE, 0, 0);
|
|
/* Send FE-IDRel */
|
|
snd_fe(fi, V52_LCP_FE_IDRel);
|
|
/* Send MDU-DI */
|
|
rcv_mdu(fi, MDU_DI);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_IDReq:
|
|
/* ignore */
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDAck:
|
|
/* Send MPH-IDR */
|
|
snd_mph(fi, MPH_IDR);
|
|
break;
|
|
case V52_LCPFSM_E_MPH_IDI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send FE-IDRel */
|
|
snd_fe(fi, V52_LCP_FE_IDRel);
|
|
/* Send MDU-AI */
|
|
rcv_mdu(fi, MDU_AI);
|
|
break;
|
|
case V52_LCPFSM_E_MPH_EIg:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send FE-IDRel */
|
|
snd_fe(fi, V52_LCP_FE_IDRel);
|
|
/* Send MDU-EIg */
|
|
rcv_mdu(fi, MDU_EIg);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDReq:
|
|
/* Send FE-IDRej */
|
|
snd_fe(fi, V52_LCP_FE_IDRej);
|
|
break;
|
|
case V52_LCPFSM_E_FE_IDRej:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send MDU-IDRej */
|
|
rcv_mdu(fi, MDU_IDRej);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LUBR:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send FE301 */
|
|
snd_fe(fi, V52_LCP_FE_301_302_LINK_UNBLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_MDU_LBI:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send FE303 */
|
|
snd_fe(fi, V52_LCP_FE_303_304_LINK_BLOCK);
|
|
break;
|
|
case V52_LCPFSM_E_FE302:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE20_OP_OPERATIONAL, 0, 0);
|
|
/* Send MDU-IDRej */
|
|
rcv_mdu(fi, MDU_IDRej);
|
|
/* Send MDU-LUBI */
|
|
rcv_mdu(fi, MDU_LUBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE304:
|
|
osmo_fsm_inst_state_chg(fi, V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED, 0, 0);
|
|
/* Send MDU-LBI */
|
|
rcv_mdu(fi, MDU_LBI);
|
|
break;
|
|
case V52_LCPFSM_E_FE305:
|
|
/* Send MDU-LBR */
|
|
rcv_mdu(fi, MDU_LBR);
|
|
break;
|
|
case V52_LCPFSM_E_FE306:
|
|
/* Send MDU-LBRN */
|
|
rcv_mdu(fi, MDU_LBRN);
|
|
break;
|
|
default:
|
|
OSMO_ASSERT(0);
|
|
}
|
|
}
|
|
|
|
/* Table 17G.965 */
|
|
static const struct osmo_fsm_state v52_le_lcp_fsm_states[] = {
|
|
[V52_LCPFSM_S_LE01_NOP_LINK_FAILURE] = {
|
|
.name = "Link failure (LE0.1)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDRel) |
|
|
S(V52_LCPFSM_E_FE_IDRej) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE20_OP_OPERATIONAL) |
|
|
S(V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED),
|
|
.action = lcp_fsm_le01_link_failure,
|
|
},
|
|
[V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED] = {
|
|
.name = "Link failure and blocked(LE0.2)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED),
|
|
.action = lcp_fsm_le02_link_failure_blocked,
|
|
},
|
|
[V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED] = {
|
|
.name = "Link blocked (LE1.0)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDRel) |
|
|
S(V52_LCPFSM_E_FE_IDRej) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED) |
|
|
S(V52_LCPFSM_S_LE11_NOP_LOCAL_LINK_UNBLOCK) |
|
|
S(V52_LCPFSM_S_LE12_NOP_REMOTE_LINK_UNBLOCK),
|
|
.action = lcp_fsm_le10_link_blocked,
|
|
},
|
|
[V52_LCPFSM_S_LE11_NOP_LOCAL_LINK_UNBLOCK] = {
|
|
.name = "Local link unblock (LE1.1)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDRel) |
|
|
S(V52_LCPFSM_E_FE_IDRej) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED) |
|
|
S(V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED) |
|
|
S(V52_LCPFSM_S_LE20_OP_OPERATIONAL),
|
|
.action = lcp_fsm_le11_local_link_unblock,
|
|
},
|
|
[V52_LCPFSM_S_LE12_NOP_REMOTE_LINK_UNBLOCK] = {
|
|
.name = "Remote link unblocke (LE1.2)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE02_NOP_LINK_FAILURE_AND_BLOCKED) |
|
|
S(V52_LCPFSM_S_LE20_OP_OPERATIONAL) |
|
|
S(V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED),
|
|
.action = lcp_fsm_le12_remote_link_unblock,
|
|
},
|
|
[V52_LCPFSM_S_LE20_OP_OPERATIONAL] = {
|
|
.name = "Link Operational (LE2.0)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_MDU_IDAck) |
|
|
S(V52_LCPFSM_E_MDU_IDRej) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE01_NOP_LINK_FAILURE) |
|
|
S(V52_LCPFSM_S_LE22_OP_LOCAL_LINK_ID) |
|
|
S(V52_LCPFSM_S_LE21_OP_REMOTE_LINK_ID) |
|
|
S(V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED),
|
|
.action = lcp_fsm_le20_operational,
|
|
},
|
|
[V52_LCPFSM_S_LE21_OP_REMOTE_LINK_ID] = {
|
|
.name = "Remote link identification (LE2.1)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_MDU_IDAck) |
|
|
S(V52_LCPFSM_E_FE_IDRel) |
|
|
S(V52_LCPFSM_E_MDU_IDRej) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE01_NOP_LINK_FAILURE) |
|
|
S(V52_LCPFSM_S_LE20_OP_OPERATIONAL) |
|
|
S(V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED),
|
|
.action = lcp_fsm_le21_op_remote_link_id,
|
|
},
|
|
[V52_LCPFSM_S_LE22_OP_LOCAL_LINK_ID] = {
|
|
.name = "Local link identification (LE2.2)",
|
|
.in_event_mask = S(V52_LCPFSM_E_MPH_AI) |
|
|
S(V52_LCPFSM_E_MPH_DI) |
|
|
S(V52_LCPFSM_E_MDU_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDAck) |
|
|
S(V52_LCPFSM_E_MPH_IDI) |
|
|
S(V52_LCPFSM_E_MPH_EIg) |
|
|
S(V52_LCPFSM_E_FE_IDReq) |
|
|
S(V52_LCPFSM_E_FE_IDRej) |
|
|
S(V52_LCPFSM_E_MDU_LUBR) |
|
|
S(V52_LCPFSM_E_MDU_LBI) |
|
|
S(V52_LCPFSM_E_FE302) |
|
|
S(V52_LCPFSM_E_FE304) |
|
|
S(V52_LCPFSM_E_FE305) |
|
|
S(V52_LCPFSM_E_FE306),
|
|
.out_state_mask = S(V52_LCPFSM_S_LE01_NOP_LINK_FAILURE) |
|
|
S(V52_LCPFSM_S_LE20_OP_OPERATIONAL) |
|
|
S(V52_LCPFSM_S_LE10_NOP_LINK_BLOCKED),
|
|
.action =lcp_fsm_le22_op_local_link_id,
|
|
},
|
|
};
|
|
|
|
struct osmo_fsm v52_le_lcp_fsm = {
|
|
.name = "V52_LE_LCP",
|
|
.states = v52_le_lcp_fsm_states,
|
|
.num_states = ARRAY_SIZE(v52_le_lcp_fsm_states),
|
|
.timer_cb = NULL,
|
|
.log_subsys = DV5LCP,
|
|
.event_names = v52_lcp_fsm_event_names,
|
|
};
|
|
|
|
struct osmo_fsm_inst *v52_le_lcp_create(void *ctx, struct v5x_link *v5l, uint8_t id)
|
|
{
|
|
struct osmo_fsm_inst *fi;
|
|
|
|
OSMO_ASSERT(v5l);
|
|
|
|
fi = osmo_fsm_inst_alloc(&v52_le_lcp_fsm, ctx, v5l, LOGL_DEBUG, NULL);
|
|
if (!fi)
|
|
return NULL;
|
|
osmo_fsm_inst_update_id_f(fi, "%d", id);
|
|
/* initial state for links that are not in failure state */
|
|
fi->state = V52_LCPFSM_S_LE20_OP_OPERATIONAL;
|
|
|
|
return fi;
|
|
}
|
|
|
|
void v52_le_lcp_destroy(struct osmo_fsm_inst *fi)
|
|
{
|
|
if (fi)
|
|
osmo_fsm_inst_free(fi);
|
|
}
|
|
|
|
bool v52_le_lcp_is_operational(struct osmo_fsm_inst *fi)
|
|
{
|
|
return (fi->state >= V52_LCPFSM_S_LE20_OP_OPERATIONAL);
|
|
}
|
|
|
|
const char *v52_le_lcp_state_name(struct osmo_fsm_inst *fi)
|
|
{
|
|
return v52_le_lcp_fsm_states[fi->state].name;
|
|
}
|
|
|
|
void v52_le_lcp_init(void)
|
|
{
|
|
int rc;
|
|
|
|
rc = osmo_fsm_register(&v52_le_lcp_fsm);
|
|
OSMO_ASSERT(!rc);
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Using V52 link control protocol\n");
|
|
}
|
|
|
|
/***********************************************************************
|
|
* Messages from other layers
|
|
***********************************************************************/
|
|
|
|
/* receive message from lower (L1 FSM) layer */
|
|
int v52_le_lcp_mph_rcv(struct v5x_link *v5l, enum v5x_mph_prim prim)
|
|
{
|
|
enum v52_lcp_fsm_event event = 9999;
|
|
|
|
switch (prim) {
|
|
case MPH_AI:
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Received link activation indication from L1 (link ID %d).\n", v5l->id);
|
|
event = V52_LCPFSM_E_MPH_AI;
|
|
break;
|
|
case MPH_DI:
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Received link deactivation indication from L1 (link ID %d).\n", v5l->id);
|
|
event = V52_LCPFSM_E_MPH_DI;
|
|
break;
|
|
case MPH_EIa:
|
|
LOGP(DV5LCP, LOGL_DEBUG, "Received link error indication from L1 (link ID %d): LOS\n", v5l->id);
|
|
return 0;
|
|
case MPH_EIb:
|
|
LOGP(DV5LCP, LOGL_DEBUG, "Received link error indication from L1 (link ID %d): RAI\n", v5l->id);
|
|
return 0;
|
|
case MPH_EIc:
|
|
LOGP(DV5LCP, LOGL_DEBUG, "Received link error indication from L1 (link ID %d): AIS\n", v5l->id);
|
|
return 0;
|
|
case MPH_EId:
|
|
LOGP(DV5LCP, LOGL_DEBUG, "Received link error indication from L1 (link ID %d): Internal failure\n",
|
|
v5l->id);
|
|
return 0;
|
|
case MPH_EIe:
|
|
LOGP(DV5LCP, LOGL_DEBUG, "Received link error indication from L1 (link ID %d): CRC error\n", v5l->id);
|
|
return 0;
|
|
case MPH_EIf:
|
|
LOGP(DV5LCP, LOGL_DEBUG, "Received link error indication from L1 (link ID %d): "
|
|
"Remote CRC error indication\n", v5l->id);
|
|
return 0;
|
|
case MPH_IDI:
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Received link identification indication from L1 (link ID %d).\n", v5l->id);
|
|
event = V52_LCPFSM_E_MPH_IDI;
|
|
break;
|
|
case MPH_EIg:
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Received link identification failure from L1 (link ID %d).\n", v5l->id);
|
|
event = V52_LCPFSM_E_MPH_EIg;
|
|
break;
|
|
case MPH_EIdr:
|
|
return 0;
|
|
case MPH_EIbr:
|
|
return 0;
|
|
default:
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Invalid LCP primitive %d receied from L1/AN (link ID %d).\n", prim, v5l->id);
|
|
return -EINVAL;
|
|
}
|
|
|
|
OSMO_ASSERT(event < 9999);
|
|
osmo_fsm_inst_dispatch(v5l->fi, event, NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* receive message from lower (CTRL) layer */
|
|
int v52_le_lcp_fe_rcv(struct v5x_link *v5l, enum v52_link_ctrl_func lcf)
|
|
{
|
|
enum v52_lcp_fsm_event event;
|
|
|
|
switch (lcf) {
|
|
case V52_LCP_FE_IDReq:
|
|
event = V52_LCPFSM_E_FE_IDReq;
|
|
break;
|
|
case V52_LCP_FE_IDAck:
|
|
event = V52_LCPFSM_E_FE_IDAck;
|
|
break;
|
|
case V52_LCP_FE_IDRel:
|
|
event = V52_LCPFSM_E_FE_IDRel;
|
|
break;
|
|
case V52_LCP_FE_IDRej:
|
|
event = V52_LCPFSM_E_FE_IDRej;
|
|
break;
|
|
case V52_LCP_FE_301_302_LINK_UNBLOCK:
|
|
event = V52_LCPFSM_E_FE302;
|
|
break;
|
|
case V52_LCP_FE_303_304_LINK_BLOCK:
|
|
event = V52_LCPFSM_E_FE304;
|
|
break;
|
|
case V52_LCP_FE_305_DEF_LINK_BLOCK_REQ:
|
|
event = V52_LCPFSM_E_FE305;
|
|
break;
|
|
case V52_LCP_FE_306_NON_DEF_LINK_BLOCK_REQ:
|
|
event = V52_LCPFSM_E_FE306;
|
|
break;
|
|
default:
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Invalid link control function primitive %d receied from AN.\n", lcf);
|
|
return -EINVAL;
|
|
}
|
|
|
|
osmo_fsm_inst_dispatch(v5l->fi, event, NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int v52_le_lcp_mdu_snd(struct v5x_link *v5l, enum v5x_mgmt_prim prim)
|
|
{
|
|
enum v52_lcp_fsm_event event;
|
|
|
|
switch (prim) {
|
|
case MDU_IDReq:
|
|
event = V52_LCPFSM_E_MDU_IDReq;
|
|
break;
|
|
case MDU_IDAck:
|
|
event = V52_LCPFSM_E_MDU_IDAck;
|
|
break;
|
|
case MDU_IDRej:
|
|
event = V52_LCPFSM_E_MDU_IDRej;
|
|
break;
|
|
case MDU_LUBR:
|
|
event = V52_LCPFSM_E_MDU_LUBR;
|
|
break;
|
|
case MDU_LBI:
|
|
event = V52_LCPFSM_E_MDU_LBI;
|
|
break;
|
|
default:
|
|
LOGP(DV5LCP, LOGL_NOTICE, "Invalid MDU primitive %d receied from management.\n", prim);
|
|
return -EINVAL;
|
|
}
|
|
|
|
osmo_fsm_inst_dispatch(v5l->fi, event, NULL);
|
|
|
|
return 0;
|
|
}
|